Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com From: "Ronald Landheer" To: Subject: RE: cygdrive stuff Date: Fri, 21 Sep 2001 23:47:31 +0200 Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0020_01C142F7.C79B8CE0" X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 In-Reply-To: <20010919151243.D17159@redhat.com> Importance: Normal ------=_NextPart_000_0020_01C142F7.C79B8CE0 Content-Type: text/plain; charset="Windows-1252" Content-Transfer-Encoding: quoted-printable Hello Chris, Salvador /et al/. > On Wed, Sep 19, 2001 at 04:11:52PM -0300, salvador wrote: >> 1) "ls -la /" doesn't show any cygdrive directory. Note it could=20 >> be solved in the same way UNIX solves the /proc stuff, just mounting >> over an existent directory a fake one. >> 2) "ls -la /cygdrive" doesn't work. > Correct. > If you'd like to correct this, patches will be, as always,=20 > gratefully accepted. I saw this, it itched me, so I'm attaching a patch :) The patch I'm attaching is against the source 'ls.c' as found in=20 fileutils-4.1-1. It introduces three methods, of which one is called:=20 ls-cygwin-loop(). It is called whenever needed. I've *only* tested this on a Win98 platform, but I don't think NT=20 changes anything in this case (I don't have any NT platforms here, so I=20 can't test them). Here's how it works: $ ls -la / (..) ?--------- 0 0 Sigma 0 Jan 1 1970 cygdrive (..) Note it only shows you that cygdrive exists. As there is no "magic dir"=20 filetype, and it's not a real directory, I'm not showing it as one. My=20 patch only does anything when there *is* no real directory - if it comes = through a stat() call, it is not handled. $ ls -la /cygdrive/ ?--------- 0 0 Sigma 0 Jan 1 1970 c ?--------- 0 0 Sigma 0 Jan 1 1970 d ?--------- 0 0 Sigma 0 Jan 1 1970 p ?--------- 0 0 Sigma 0 Jan 1 1970 u Note that 'ls -la /cygdrive' *only* shows: ?--------- 0 0 Sigma 0 Jan 1 1970 cygdrive The patch works regardless of the cygdrive setting, but does=20 (regrettably) not show the mounted drives if the cygdrive setting is=20 '/' and -an 'ls -la /' is done. I guess I should fix this, but the=20 problem is that the mounted drives come through a stat() call as a=20 directory, so I don't know whether or not they're really there -=20 ideas would help. Everything where displaying etc. is concerned is handled by the old code = - my code only adds stuff to the list and does so conservatively (so it=20 does not, for example, show the /usr/bin mount when an ls -la /usr is=20 done, unless the directory is really there, in which case ls would show=20 it anyway. (This is to avoid duplicates in the file list). I lifted some code from mount - code used to see what mounts exist, and=20 what the cygdrive prefix is.. I've surrounded those by copyright notices = attributing it to mount & Cygnus. The rest is my own (but I'm quite=20 willing to sign it over, if it's significant enough for any signatures:=20 I'm no lawyer, so I'm being conservative - this, ofcourse, only if it=20 proves useful enough to apply to ls..). All code is surrounded by the magic __CYGWIN__ ifdefs - so no other=20 platforms should be affected at all. (However, I don't know how MinGW32=20 handles this, or how this goes along with the -mno-cygwin flag) I hope it's helpful (and bug-free). Greetz! Ronald ------=_NextPart_000_0020_01C142F7.C79B8CE0 Content-Type: application/octet-stream; name="ls.c.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="ls.c.diff" --- ls.c.old Sun Apr 29 11:42:48 2001=0A= +++ ls.c Fri Sep 21 23:24:14 2001=0A= @@ -118,6 +118,18 @@=0A= #include "strverscmp.h"=0A= #include "xstrtol.h"=0A= =0A= +#ifdef __CYGWIN__=0A= +#include =0A= +#include =0A= +#include =0A= +#include =0A= +#include =0A= +=0A= +static uintmax_t gobble_mount (const char *name);=0A= +static char * ls_cygwin_scan(const char *base_list_path);=0A= +static int ls_cygwin_loop(const char *base_list_path);=0A= +#endif /* __CYGWIN__ */=0A= +=0A= /* Use access control lists only under all the following conditions.=0A= Some systems (OSF4, Irix5, Irix6) have the acl function, but not=0A= sys/acl.h or don't define the GETACLCNT macro. */=0A= @@ -1747,6 +1759,7 @@=0A= register uintmax_t total_blocks =3D 0;=0A= =0A= errno =3D 0;=0A= +=0A= reading =3D opendir (name);=0A= if (!reading)=0A= {=0A= @@ -1760,6 +1773,11 @@=0A= =0A= clear_files ();=0A= =0A= +#ifdef __CYGWIN__=0A= +/* Loop to the Cygwin-specific subroutine (which will put visible mount = points in the files table */=0A= + ls_cygwin_loop(name);=0A= +#endif =0A= +=0A= while ((next =3D readdir (reading)) !=3D NULL)=0A= if (file_interesting (next))=0A= {=0A= @@ -1924,9 +1942,17 @@=0A= =0A= if (val < 0)=0A= {=0A= +#ifdef __CYGWIN__=0A= + if (ls_cygwin_loop(name) =3D=3D -1) {=0A= + error (0, errno, "%s", quotearg_colon (path));=0A= + exit_status =3D 1;=0A= + return 0;=0A= + } else return(0);=0A= +#else /* !__CYGWIN__ */=0A= error (0, errno, "%s", quotearg_colon (path));=0A= exit_status =3D 1;=0A= return 0;=0A= +#endif /* !__CYGWIN__ */=0A= }=0A= =0A= #if USE_ACL=0A= @@ -3336,3 +3362,267 @@=0A= }=0A= exit (status);=0A= }=0A= +=0A= +/* contribution to ls by Ronald Landheer =0A= +// This allows ls to see the cygdrive magic dir, whatever it's called, = and the mounted drives.=0A= +// Copyright (c) Ronald Landheer (unless otherwise stated below)=0A= +// Published under GNU Public License (see COPYING for details)=0A= +// no warranties offered - at all.=0A= +*/=0A= +/*only compile if in Cygwin*/=0A= +#ifdef __CYGWIN__=0A= +/* Unlike when gobble_file() is called, gobble_mount() expects the path = to still be there (so it's removed) */=0A= +/* Lifted off strings.c from the Real Life Systems Swing library */=0A= +static char *invert(char *s) {=0A= + short k, j;=0A= + char c;=0A= +=0A= + j =3D strlen(s) - 1;=0A= + k =3D 0;=0A= + while (k < j) {=0A= + c =3D s[k]; s[k++] =3D s[j]; s[j--] =3D c;=0A= + } // while=0A= +=0A= + return(s);=0A= +} // invert()=0A= +=0A= +static uintmax_t=0A= +gobble_mount (const char *name)=0A= +{=0A= + char *inverted_name =3D NULL;=0A= + char *c;=0A= + struct fileinfo *mount_info;=0A= +=0A= + if ((inverted_name =3D (char*)malloc(strlen(name) + 1)) =3D=3D NULL) {=0A= + fprintf(stderr, "Out of memory!");=0A= + exit(1);=0A= + }=0A= + strcpy(inverted_name, name);=0A= + inverted_name =3D invert(inverted_name);=0A= + if (c =3D strchr(inverted_name, '/')) {=0A= + *c =3D 0;=0A= + }=0A= + inverted_name =3D invert(inverted_name);=0A= +=0A= + if ((mount_info =3D (struct fileinfo*)malloc(sizeof(struct = fileinfo))) =3D=3D NULL) {=0A= + fprintf(stderr, "Out of memory!");=0A= + exit(1);=0A= + }=0A= + if ((mount_info->name =3D (char*)malloc(strlen(name) + 1)) =3D=3D = NULL) {=0A= + fprintf(stderr, "Out of memory!");=0A= + exit(1);=0A= + }=0A= +=0A= + strcpy(mount_info->name, inverted_name);=0A= + mount_info->linkname =3D 0;=0A= + mount_info->linkok =3D 0;=0A= + mount_info->filetype =3D unknown;=0A= +#if USE_ACL=0A= + mount_info->have_acl =3D 0; /* The thing doesn't really exist, so it = doesn't have an ACL*/=0A= +#endif =0A= +=0A= + if (files_index =3D=3D nfiles)=0A= + {=0A= + nfiles *=3D 2;=0A= + files =3D (struct fileinfo *) xrealloc ((char *) files,=0A= + sizeof (*files) * nfiles);=0A= + }=0A= + memcpy(&(files[files_index]), mount_info, sizeof(struct fileinfo));=0A= +=0A= + files_index++;=0A= +=0A= + return(0);=0A= +}=0A= +=0A= +/* ls_cygwin_scan() =0A= + Returns a pointer to an internal static string holding the visible = mount =0A= + points, space-separated, null-terminated. NULL is returned if there = are=0A= + no visible mount points in BASE_LIST_PATH=0A= +*/=0A= +static char *=0A= +ls_cygwin_scan(const char *base_list_path)=0A= +{=0A= + static char *rVal =3D NULL;=0A= + char *cygdrive, *magic_cygdrive;=0A= + char cygdrive_basedir[MAXPATHLEN];=0A= + int i;=0A= + struct stat stat_info;=0A= +/*=0A= + Copyright 1996, 1997, 1998, 1999 Cygnus Solutions.=0A= + Lifted off: cygwin-1.3.3-2/winsup/utils/mount.cc=0A= +*/=0A= + FILE *m =3D setmntent ("/-not-used-", "r");=0A= + struct mntent *p;=0A= + char user[MAXPATHLEN];=0A= + char system[MAXPATHLEN];=0A= + char user_flags[MAXPATHLEN];=0A= + char system_flags[MAXPATHLEN];=0A= +=0A= + /*get cygdrive info*/=0A= + cygwin_internal (CW_GET_CYGDRIVE_INFO, user, system, user_flags, = system_flags);=0A= +/* end copyright Cygnus Solutions */=0A= + /* We now have the cygdrive path in either user or system - and will = put =0A= + it in the cygdrive var.*/=0A= + if (strlen(user) > 0) {=0A= + magic_cygdrive =3D cygdrive =3D user;=0A= + } else if (strlen(system) > 0) {=0A= + magic_cygdrive =3D cygdrive =3D system;=0A= + } else return(NULL);=0A= + strncpy(cygdrive_basedir, cygdrive, MAXPATHLEN);=0A= + for (i =3D strlen(cygdrive_basedir) - 1; (i > 0) && = (cygdrive_basedir[i] !=3D '/'); i--) cygdrive_basedir[i] =3D 0;=0A= + if (strcmp(cygdrive_basedir, base_list_path) =3D=3D 0) {=0A= + if (stat(cygdrive, &stat_info) !=3D 0) {=0A= + /* Here, rVal can only be NULL */=0A= + if ((rVal =3D (char*)malloc(strlen(cygdrive) + 2)) =3D=3D NULL) {=0A= + fprintf(stderr, "Error: out of memory.\n");=0A= + exit(1);=0A= + } else sprintf(rVal, " %s", cygdrive);=0A= + }=0A= + } else {=0A= + /* Remove trailing slash from cygdrive_basedir and try again */=0A= + cygdrive_basedir[strlen(cygdrive_basedir) - 1] =3D 0;=0A= + if (strcmp(cygdrive_basedir, base_list_path) =3D=3D 0) {=0A= + if (stat(cygdrive, &stat_info) !=3D 0) {=0A= + /* Here, rVal can only be NULL */=0A= + if ((rVal =3D (char*)malloc(strlen(cygdrive) + 2)) =3D=3D NULL) = {=0A= + fprintf(stderr, "Error: out of memory.\n");=0A= + exit(1);=0A= + } else sprintf(rVal, " %s", cygdrive);=0A= + }=0A= + }=0A= + }=0A= + if (strcmp(cygdrive, base_list_path) =3D=3D 0) {=0A= + if (stat(cygdrive, &stat_info) !=3D 0) {=0A= + /* Here, rVal can only be NULL */=0A= + if ((rVal =3D (char*)malloc(strlen(cygdrive) + 2)) =3D=3D NULL) {=0A= + fprintf(stderr, "Error: out of memory.\n");=0A= + exit(1);=0A= + } else sprintf(rVal, " %s", cygdrive);=0A= + }=0A= + }=0A= + =0A= +/*=0A= + Copyright 1996, 1997, 1998, 1999 Cygnus Solutions.=0A= + Lifted off: cygwin-1.3.3-2/winsup/utils/mount.cc=0A= +*/=0A= + while ((p =3D getmntent (m)) !=3D NULL) {=0A= +/* end copyright Cygnus Solutions */=0A= + /* We now have a mountpoint in p->mnt_dir */=0A= + cygdrive=3Dp->mnt_dir;=0A= + /* .. with which we'll do the same thing as above .. */=0A= + strncpy(cygdrive_basedir, cygdrive, MAXPATHLEN);=0A= + for (i =3D strlen(cygdrive_basedir) - 1; (i > 0) && = (cygdrive_basedir[i] !=3D '/'); i--) cygdrive_basedir[i] =3D 0;=0A= + if (strcmp(cygdrive_basedir, base_list_path) =3D=3D 0) {=0A= + if (stat(cygdrive, &stat_info) !=3D 0) {=0A= + /* Here, rVal might be ! NULL */=0A= + if (rVal) {=0A= + if ((rVal =3D (char*)realloc(rVal, strlen(rVal) + = strlen(cygdrive) + 2)) =3D=3D NULL) {=0A= + fprintf(stderr, "Error: out of memory.\n");=0A= + } else sprintf(rVal, "%s %s", ((rVal) ? (rVal) : ("")), = cygdrive);=0A= + } else {=0A= + if ((rVal =3D (char*)malloc(strlen(cygdrive) + 2)) =3D=3D = NULL) {=0A= + fprintf(stderr, "Error: out of memory.\n");=0A= + } else sprintf(rVal, " %s", cygdrive);=0A= + }=0A= + } else { =0A= + /* cygdrive drives come through stat() as a directory, =0A= + but they are not shown when scanning the cygdrive =0A= + magicdir for them.=0A= + This is fixed by checking to see if what just passed=0A= + through the stat() call is rooted in the cygdrive =0A= + magic dir.=0A= + FIXME: things may pass through because they actually =0A= + exist (i.e. the magic dir is mounted over a =0A= + real tree, or something similar). This should =0A= + be checked, but I don't know how.. (yet).=0A= + */=0A= + if (strcmp(cygdrive_basedir, magic_cygdrive) =3D=3D 0) {=0A= + if (rVal) {=0A= + if ((rVal =3D (char*)realloc(rVal, strlen(rVal) + = strlen(cygdrive) + 2)) =3D=3D NULL) {=0A= + fprintf(stderr, "Error: out of memory.\n");=0A= + } else sprintf(rVal, "%s %s", ((rVal) ? (rVal) : ("")), = cygdrive);=0A= + } else {=0A= + if ((rVal =3D (char*)malloc(strlen(cygdrive) + 2)) =3D=3D = NULL) {=0A= + fprintf(stderr, "Error: out of memory.\n");=0A= + } else sprintf(rVal, " %s", cygdrive);=0A= + }=0A= + } else { /* remove trailing slash and try again */=0A= + cygdrive_basedir[strlen(cygdrive_basedir) - 1] =3D 0;=0A= + if (strcmp(cygdrive_basedir, magic_cygdrive) =3D=3D 0) {=0A= + if (rVal) {=0A= + if ((rVal =3D (char*)realloc(rVal, strlen(rVal) + = strlen(cygdrive) + 2)) =3D=3D NULL) {=0A= + fprintf(stderr, "Error: out of memory.\n");=0A= + } else sprintf(rVal, "%s %s", ((rVal) ? (rVal) : ("")), = cygdrive);=0A= + } else {=0A= + if ((rVal =3D (char*)malloc(strlen(cygdrive) + 2)) =3D=3D = NULL) {=0A= + fprintf(stderr, "Error: out of memory.\n");=0A= + } else sprintf(rVal, " %s", cygdrive);=0A= + }=0A= + }=0A= + }=0A= + }=0A= + } else {=0A= + /* Remove trailing slash from basedir and try again */=0A= + cygdrive_basedir[strlen(cygdrive_basedir) - 1] =3D 0;=0A= + if (strcmp(cygdrive_basedir, base_list_path) =3D=3D 0) {=0A= + if (stat(cygdrive, &stat_info) !=3D 0) {=0A= + /* Here, rVal might be ! NULL */=0A= + if (rVal) {=0A= + if ((rVal =3D (char*)realloc(rVal, strlen(rVal) + = strlen(cygdrive) + 2)) =3D=3D NULL) {=0A= + fprintf(stderr, "Error: out of memory.\n");=0A= + } else sprintf(rVal, "%s %s", ((rVal) ? (rVal) : ("")), = cygdrive);=0A= + } else {=0A= + if ((rVal =3D (char*)malloc(strlen(cygdrive) + 2)) =3D=3D = NULL) {=0A= + fprintf(stderr, "Error: out of memory.\n");=0A= + } else sprintf(rVal, " %s", cygdrive);=0A= + }=0A= + } /* Note that the cygdrive magic dir shows up as a file when = scanned w/o trailing '/' */=0A= + }=0A= + }=0A= + if (strcmp(cygdrive, base_list_path) =3D=3D 0) {=0A= + if (stat(cygdrive, &stat_info) !=3D 0) {=0A= + /* Here, rVal can only be NULL */=0A= + if ((rVal =3D (char*)malloc(strlen(cygdrive) + 2)) =3D=3D NULL) = {=0A= + fprintf(stderr, "Error: out of memory.\n");=0A= + exit(1);=0A= + } else sprintf(rVal, " %s", cygdrive);=0A= + }=0A= + }=0A= + }=0A= +/*=0A= + Copyright 1996, 1997, 1998, 1999 Cygnus Solutions.=0A= + Lifted off: cygwin-1.3.3-2/winsup/utils/mount.cc=0A= +*/=0A= + endmntent (m);=0A= +/* end copyright Cygnus Solutions */=0A= +=0A= +=0A= + if (rVal && strlen(rVal)) {=0A= + return(rVal);=0A= + } else return(NULL);=0A= +} /* ls_cygwin_scan() */=0A= +=0A= +static int =0A= +ls_cygwin_loop(const char *base_list_path) =0A= +{=0A= + char *mount_list =3D NULL;=0A= + char *spaceFound, *nextSpace;=0A= + char mount_name[MAXPATHLEN];=0A= + char *c =3D NULL;=0A= +=0A= + if (mount_list =3D ls_cygwin_scan(base_list_path)) {=0A= + /* Note that the mount_list *starts* with a space, but does not end = with one! */=0A= + spaceFound =3D mount_list;=0A= + while (spaceFound =3D strchr(spaceFound, ' ')) {=0A= + spaceFound++; /* Get rid of the leading space */=0A= + strcpy(mount_name, spaceFound);=0A= + if (c =3D strchr(mount_name, ' ')) {=0A= + *c =3D 0;=0A= + }=0A= + gobble_mount(mount_name);=0A= + }=0A= + } else return(-1);=0A= +=0A= + return(0);=0A= +} /* ls_cygwin_loop() */=0A= +#endif /* defined __CYGWIN__ */=0A= ------=_NextPart_000_0020_01C142F7.C79B8CE0 Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ------=_NextPart_000_0020_01C142F7.C79B8CE0--