delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2001/09/21/17:50:35

Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT sources DOT redhat DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT sources DOT redhat DOT com>
List-Help: <mailto:cygwin-help AT sources DOT redhat DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT sources DOT redhat DOT com
Delivered-To: mailing list cygwin AT sources DOT redhat DOT com
From: "Ronald Landheer" <info AT rlsystems DOT net>
To: <cygwin AT cygwin DOT com>
Subject: RE: cygdrive stuff
Date: Fri, 21 Sep 2001 23:47:31 +0200
Message-ID: <NFBBLOMHALONCDMPGBLFGEPOCBAA.info@rlsystems.net>
MIME-Version: 1.0
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 <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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019