Mail Archives: cygwin/2001/09/21/17:50:35
------=_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 <stdio.h>=0A=
+#include <sys/cygwin.h>=0A=
+#include <sys/param.h>=0A=
+#include <sys/stat.h>=0A=
+#include <mntent.h>=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 <info AT rlsystems DOT net>=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--
- Raw text -