]> sourceware.org Git - newlib-cygwin.git/commitdiff
* path.cc (conv_path_list): Fix wild indexing into path due to conflicting
authorChristopher Faylor <me@cgf.cx>
Thu, 22 Nov 2001 05:59:07 +0000 (05:59 +0000)
committerChristopher Faylor <me@cgf.cx>
Thu, 22 Nov 2001 05:59:07 +0000 (05:59 +0000)
methods for setting src pointer.
* dir.cc (opendir): Only pass path_conv argument to opendir, since name is
already part of the fhandler.
* dtable.cc (dtable::build_fhandler): Accomodate new FH_CYGDRIVE type.
* fhandler.cc (fhandler_base::opendir): Nuke name argument.
* fhandler.h: Add FH_CYGDRIVE to "device" enum.
(fhandler_base::opendir): Nuke name argument.
(fhandler_disk_file::opendir): Ditto.
(fhandler_disk_file::fhandler_disk_file): Declare new method which passes
devtype through.
(fhandler_cygdrive): Add elements for tracking drives.
(fhandler_cygdrive::set_drives): Declare new method.
(fhandler_cygdrive::iscygdrive_root): Declare new method.
(fhandler_cygdrive::opendir): Declare new method.
(fhandler_cygdrive::readdir): Declare new method.
(fhandler_cygdrive::telldir): Declare new method.
(fhandler_cygdrive::seekdir): Declare new method.
(fhandler_cygdrive::rewinddir): Declare new method.
(fhandler_cygdrive::closedir): Declare new method.
(fhandler_cygdrive::fstat): Declare new method.
* fhandler_disk_file.cc (fhandler_disk_file::fhandler_disk_file): Define new
method which passes devtype through.
(fhandler_disk_file::open): Tweak debug output.
(fhandler_disk_file::opendir): Nuke first argument.  Use info from path_conv
and class rather than calling fstat.
(fhandler_cygdrive::set_drives): New method.
(fhandler_cygdrive::iscygdrive_root): New method.
(fhandler_cygdrive::opendir): New method.
(fhandler_cygdrive::readdir): New method.
(fhandler_cygdrive::telldir): New method.
(fhandler_cygdrive::seekdir): New method.
(fhandler_cygdrive::rewinddir): New method.
(fhandler_cygdrive::closedir): New method.
(fhandler_cygdrive::fstat): New method.
* path.cc (iscygdrive_device): Assume cygdriveness is already verified.
(path_conv::check): Treat FH_CYGDRIVE "method" as a special case, setting file
attributes as needed.
(mount_info::conv_to_win32_path): Allow stand-alone /cygdrive, meaning "the
directory which contains all of the drives on the system".
(fillout_mntent): Use cyg_tolower for conversions.
(mount_info::cygdrive_win32_path): Replace unused argument with unit number.
* shared_info.h (mount_info::cygdrive_win32_path): Reflect argument change.

winsup/cygwin/ChangeLog
winsup/cygwin/dir.cc
winsup/cygwin/dtable.cc
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_disk_file.cc
winsup/cygwin/path.cc
winsup/cygwin/shared_info.h

index db7f2a76ff84b8b79ffb04c6269e8482301dd0d1..935020e28ae96d2be6400d5af4b272e6281d128d 100644 (file)
@@ -1,3 +1,52 @@
+2001-11-22  Christopher Faylor  <cgf@redhat.com>
+
+       * path.cc (conv_path_list): Fix wild indexing into path due to
+       conflicting methods for setting src pointer.
+
+       * dir.cc (opendir): Only pass path_conv argument to opendir, since name
+       is already part of the fhandler.
+       * dtable.cc (dtable::build_fhandler): Accomodate new FH_CYGDRIVE type.
+       * fhandler.cc (fhandler_base::opendir): Nuke name argument.
+       * fhandler.h: Add FH_CYGDRIVE to "device" enum.
+       (fhandler_base::opendir): Nuke name argument.
+       (fhandler_disk_file::opendir): Ditto.
+       (fhandler_disk_file::fhandler_disk_file): Declare new method which
+       passes devtype through.
+       (fhandler_cygdrive): Add elements for tracking drives.
+       (fhandler_cygdrive::set_drives): Declare new method.
+       (fhandler_cygdrive::iscygdrive_root): Declare new method.
+       (fhandler_cygdrive::opendir): Declare new method.
+       (fhandler_cygdrive::readdir): Declare new method.
+       (fhandler_cygdrive::telldir): Declare new method.
+       (fhandler_cygdrive::seekdir): Declare new method.
+       (fhandler_cygdrive::rewinddir): Declare new method.
+       (fhandler_cygdrive::closedir): Declare new method.
+       (fhandler_cygdrive::fstat): Declare new method.
+       * fhandler_disk_file.cc (fhandler_disk_file::fhandler_disk_file):
+       Define new method which passes devtype through.
+       (fhandler_disk_file::open): Tweak debug output.
+       (fhandler_disk_file::opendir): Nuke first argument.  Use info from
+       path_conv and class rather than calling fstat.
+       (fhandler_cygdrive::set_drives): New method.
+       (fhandler_cygdrive::iscygdrive_root): New method.
+       (fhandler_cygdrive::opendir): New method.
+       (fhandler_cygdrive::readdir): New method.
+       (fhandler_cygdrive::telldir): New method.
+       (fhandler_cygdrive::seekdir): New method.
+       (fhandler_cygdrive::rewinddir): New method.
+       (fhandler_cygdrive::closedir): New method.
+       (fhandler_cygdrive::fstat): New method.
+       * path.cc (iscygdrive_device): Assume cygdriveness is already verified.
+       (path_conv::check): Treat FH_CYGDRIVE "method" as a special case,
+       setting file attributes as needed.
+       (mount_info::conv_to_win32_path): Allow stand-alone /cygdrive, meaning
+       "the directory which contains all of the drives on the system".
+       (fillout_mntent): Use cyg_tolower for conversions.
+       (mount_info::cygdrive_win32_path): Replace unused argument with unit
+       number.
+       * shared_info.h (mount_info::cygdrive_win32_path): Reflect argument
+       change.
+
 2001-11-21  Christopher Faylor  <cgf@redhat.com>
 
        * Makefile.in (DLL_OFILES): Add fhandler_disk_file.o.
index a5b0eabbff12c7c8b6c82fb5f2baf5d9b62552f5..07d2ce6d9878192897e2db93a57d87b5a6b68855 100644 (file)
@@ -86,7 +86,7 @@ opendir (const char *name)
 
   fh = cygheap->fdtab.build_fhandler_from_name (-1, name, NULL, pc,
                                                PC_SYM_FOLLOW | PC_FULL, NULL);
-  res = fh->opendir (name, pc);
+  res = fh->opendir (pc);
   if (!res)
     delete fh;
   return res;
index 4ae3871c1c4c685806fa903465f882fd029ebf3c..48bc1fca03900b379a2a7e3f40abf05891a762b8 100644 (file)
@@ -301,6 +301,9 @@ dtable::build_fhandler (int fd, DWORD dev, const char *name, int unit)
       case FH_DISK:
        fh = cnew (fhandler_disk_file) ();
        break;
+      case FH_CYGDRIVE:
+       fh = cnew (fhandler_cygdrive) (unit);
+       break;
       case FH_FLOPPY:
        fh = cnew (fhandler_dev_floppy) (unit);
        break;
index c8c08e72d2856c362087c40a6f8953b2e4ffe22f..e61b90ee9e312007914f84bebcff57de2ccfad96 100644 (file)
@@ -1166,7 +1166,7 @@ fhandler_base::set_nonblocking (int yes)
 }
 
 DIR *
-fhandler_base::opendir (const char *, path_conv&)
+fhandler_base::opendir (path_conv&)
 {
   set_errno (ENOTDIR);
   return NULL;
index ad6444d0628fee888205aa00a75dafaa1564330f..07864fca118bf614213c549db96f9406c32e1a07 100644 (file)
@@ -67,10 +67,11 @@ enum
   FH_ZERO    = 0x00000014,     /* is the zero device */
   FH_RANDOM  = 0x00000015,     /* is a random device */
   FH_MEM     = 0x00000016,     /* is a mem device */
-  FH_CLIPBOARD = 0x00000017, /* is a clipbaord device */
+  FH_CLIPBOARD = 0x00000017,   /* is a clipboard device */
   FH_OSS_DSP = 0x00000018,     /* is a dsp audio device */
+  FH_CYGDRIVE= 0x00000019,     /* /cygdrive/x */
 
-  FH_NDEV    = 0x00000019,     /* Maximum number of devices */
+  FH_NDEV    = 0x0000001a,     /* Maximum number of devices */
   FH_DEVMASK = 0x00000fff,     /* devices live here */
   FH_BAD     = 0xffffffff
 };
@@ -340,7 +341,7 @@ class fhandler_base
   void operator delete (void *);
   virtual HANDLE get_guard () const {return NULL;}
   virtual void set_eof () {}
-  virtual DIR *opendir (const char *dirname, path_conv& pc);
+  virtual DIR *opendir (path_conv& pc);
   virtual dirent *readdir (DIR *);
   virtual off_t telldir (DIR *);
   virtual void seekdir (DIR *, off_t);
@@ -527,6 +528,7 @@ class fhandler_disk_file: public fhandler_base
 {
  public:
   fhandler_disk_file ();
+  fhandler_disk_file (DWORD devtype);
 
   int open (path_conv * real_path, int flags, mode_t mode);
   int close ();
@@ -540,7 +542,7 @@ class fhandler_disk_file: public fhandler_base
   int msync (HANDLE h, caddr_t addr, size_t len, int flags);
   BOOL fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
                              DWORD size, void *address);
-  DIR *opendir (const char *dirname, path_conv& pc);
+  DIR *opendir (path_conv& pc);
   struct dirent *readdir (DIR *);
   off_t telldir (DIR *);
   void seekdir (DIR *, off_t);
@@ -548,6 +550,24 @@ class fhandler_disk_file: public fhandler_base
   int closedir (DIR *);
 };
 
+class fhandler_cygdrive: public fhandler_disk_file
+{
+  int unit;
+  int ndrives;
+  const char *pdrive;
+  void set_drives ();
+ public:
+  bool iscygdrive_root () const { return !unit; }
+  fhandler_cygdrive (int unit);
+  DIR *opendir (path_conv& pc);
+  struct dirent *readdir (DIR *);
+  off_t telldir (DIR *);
+  void seekdir (DIR *, off_t);
+  void rewinddir (DIR *);
+  int closedir (DIR *);
+  int __stdcall fstat (struct stat *buf, path_conv *pc) __attribute__ ((regparm (3)));
+};
+
 class fhandler_serial: public fhandler_base
 {
  private:
@@ -591,12 +611,6 @@ class fhandler_serial: public fhandler_base
   select_record *select_except (select_record *s);
 };
 
-class fhandler_cygdrive: public fhandler_disk_file
-{
- public:
-  fhandler_cygdrive ();
-};
-
 #define acquire_output_mutex(ms) \
   __acquire_output_mutex (__PRETTY_FUNCTION__, __LINE__, ms);
 
index 888df22339463f7436ee98193d51a4d376f44464..0585555c4a80d06e54e0bb65f0cdef64fc92b6f1 100644 (file)
@@ -338,8 +338,13 @@ fhandler_disk_file::fstat_helper (struct stat *buf)
   return 0;
 }
 
+fhandler_disk_file::fhandler_disk_file (DWORD devtype) :
+  fhandler_base (devtype)
+{
+}
+
 fhandler_disk_file::fhandler_disk_file () :
-       fhandler_base (FH_DISK)
+  fhandler_base (FH_DISK)
 {
 }
 
@@ -348,7 +353,7 @@ fhandler_disk_file::open (path_conv *real_path, int flags, mode_t mode)
 {
   if (real_path->case_clash && flags & O_CREAT)
     {
-      debug_printf ("Caseclash detected.");
+      debug_printf ("case clash detected");
       set_errno (ECASECLASH);
       return 0;
     }
@@ -564,14 +569,13 @@ fhandler_disk_file::lock (int cmd, struct flock *fl)
 }
 
 DIR *
-fhandler_disk_file::opendir (const char *name, path_conv& real_name)
+fhandler_disk_file::opendir (path_conv& real_name)
 {
-  struct stat statbuf;
   DIR *dir;
   DIR *res = NULL;
   size_t len;
 
-  if (fstat (&statbuf, &real_name) ||!(statbuf.st_mode & S_IFDIR))
+  if (!real_name.isdir ())
     set_errno (ENOTDIR);
   else if ((len = strlen (real_name))> MAX_PATH - 3)
     set_errno (ENAMETOOLONG);
@@ -606,12 +610,12 @@ fhandler_disk_file::opendir (const char *name, path_conv& real_name)
       dir->__d_cookie = __DIRENT_COOKIE;
       dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;
       dir->__d_position = 0;
-      dir->__d_dirhash = statbuf.st_ino;
+      dir->__d_dirhash = get_namehash ();
 
       res = dir;
     }
 
-  syscall_printf ("%p = opendir (%s)", res, name);
+  syscall_printf ("%p = opendir (%s)", res, get_name ());
   return res;
 }
 
@@ -702,7 +706,7 @@ fhandler_disk_file::readdir (DIR *dir)
       dir->__d_dirent->d_ino = hash_path_name (dino, buf.cFileName);
     }
 
-  ++dir->__d_position;
+  dir->__d_position++;
   res = dir->__d_dirent;
   syscall_printf ("%p = readdir (%p) (%s)",
                  &dir->__d_dirent, dir, buf.cFileName);
@@ -720,7 +724,7 @@ fhandler_disk_file::seekdir (DIR *dir, off_t loc)
 {
     rewinddir (dir);
     while (loc > dir->__d_position)
-      if (! readdir (dir))
+      if (!readdir (dir))
        break;
 }
 
@@ -748,3 +752,100 @@ fhandler_disk_file::closedir (DIR *dir)
   syscall_printf ("%d = closedir (%p)", res, dir);
   return 0;
 }
+
+fhandler_cygdrive::fhandler_cygdrive (int unit) :
+  fhandler_disk_file (FH_CYGDRIVE), unit (unit), ndrives (0), pdrive (NULL)
+{
+}
+
+#define DRVSZ sizeof ("x:\\")
+void
+fhandler_cygdrive::set_drives ()
+{
+  const int len = 1 + 26 * DRVSZ;
+  win32_path_name = (char *) crealloc (win32_path_name, len);
+
+  ndrives = GetLogicalDriveStrings (len, win32_path_name) / DRVSZ;
+  pdrive = win32_path_name;
+}
+
+int
+fhandler_cygdrive::fstat (struct stat *buf, path_conv *pc)
+{
+  if (!iscygdrive_root ())
+    return fhandler_disk_file::fstat (buf, pc);
+  buf->st_mode = S_IFDIR | 0555;
+  if (!ndrives)
+    set_drives ();
+  buf->st_nlink = ndrives;
+  return 0;
+}
+
+DIR *
+fhandler_cygdrive::opendir (path_conv& real_name)
+{
+  DIR *dir;
+
+  dir = fhandler_disk_file::opendir (real_name);
+  if (dir && iscygdrive_root () && !ndrives)
+    set_drives ();
+
+  return dir;
+}
+
+struct dirent *
+fhandler_cygdrive::readdir (DIR *dir)
+{
+  if (!iscygdrive_root ())
+    return fhandler_disk_file::readdir (dir);
+  if (!pdrive || !*pdrive)
+    {
+      set_errno (ENMFILE);
+      return NULL;
+    }
+  *dir->__d_dirent->d_name = cyg_tolower (*pdrive);
+  dir->__d_dirent->d_name[1] = '\0';
+  dir->__d_position++;
+  pdrive += DRVSZ;
+  syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir,
+                 dir->__d_dirent->d_name);
+  return dir->__d_dirent;
+}
+
+off_t
+fhandler_cygdrive::telldir (DIR *dir)
+{
+  return fhandler_disk_file::telldir (dir);
+}
+
+void
+fhandler_cygdrive::seekdir (DIR *dir, off_t loc)
+{
+  if (!iscygdrive_root ())
+    return fhandler_disk_file::seekdir (dir, loc);
+
+  for (pdrive = win32_path_name, dir->__d_position = -1; *pdrive; pdrive += DRVSZ)
+    if (++dir->__d_position >= loc)
+      break;
+
+  return;
+}
+
+void
+fhandler_cygdrive::rewinddir (DIR *dir)
+{
+  if (!iscygdrive_root ())
+    return fhandler_disk_file::rewinddir (dir);
+  pdrive = win32_path_name;
+  dir->__d_position = 0;
+  return;
+}
+
+int
+fhandler_cygdrive::closedir (DIR *dir)
+{
+  if (!iscygdrive_root ())
+    return fhandler_disk_file::closedir (dir);
+  pdrive = win32_path_name;
+  return -1;
+}
index 8405582695f7d4e9238acebc2f9c43a7be06b292..b74581de2a2926991ba569b6296cdbb469aa846a 100644 (file)
@@ -114,7 +114,7 @@ int pcheck_case = PCHECK_RELAXED; /* Determines the case check behaviour. */
   (path_prefix_p (mount_table->cygdrive, (path), mount_table->cygdrive_len))
 
 #define iscygdrive_device(path) \
-  (iscygdrive(path) && isalpha(path[mount_table->cygdrive_len]) && \
+  (isalpha(path[mount_table->cygdrive_len]) && \
    (isdirsep(path[mount_table->cygdrive_len + 1]) || \
     !path[mount_table->cygdrive_len + 1]))
 
@@ -482,12 +482,19 @@ path_conv::check (const char *src, unsigned opt,
          /* devn should not be a device.  If it is, then stop parsing now. */
          if (devn != FH_BAD)
            {
-             if (component)
+             if (devn == FH_CYGDRIVE)
+               fileattr = !unit ? FILE_ATTRIBUTE_DIRECTORY
+                                : GetFileAttributes (full_path);
+             else
                {
-                 error = ENOTDIR;
-                 return;
+                 if (component)
+                   {
+                     error = ENOTDIR;
+                     return;
+                   }
+                 fileattr = 0;
                }
-             fileattr = 0;
+
              goto out;         /* Found a device.  Stop parsing. */
            }
 
@@ -510,7 +517,7 @@ path_conv::check (const char *src, unsigned opt,
 
          if ((opt & PC_SYM_IGNORE) && pcheck_case == PCHECK_RELAXED)
            {
-             fileattr = GetFileAttributesA (full_path);
+             fileattr = GetFileAttributes (full_path);
              goto out;
            }
 
@@ -1237,21 +1244,18 @@ conv_path_list (const char *src, char *dst, int to_posix_p)
 
   char *srcbuf = (char *) alloca (strlen (src) + 1);
 
-  do
+  for (;;)
     {
       s = strccpy (srcbuf, &src, src_delim);
       int len = s - srcbuf;
       if (len >= MAX_PATH)
        srcbuf[MAX_PATH - 1] = '\0';
       (*conv_fn) (len ? srcbuf : ".", d);
-      src += len;
-      if (*src)
-       {
-         d = strchr (d, '\0');
-         *d++ = dst_delim;
-       }
+      if (!*src++)
+       break;
+      d = strchr (d, '\0');
+      *d++ = dst_delim;
     }
-  while (*src++);
 }
 
 /* init: Initialize the mount table.  */
@@ -1374,11 +1378,21 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
   /* Check if the cygdrive prefix was specified.  If so, just strip
      off the prefix and transform it into an MS-DOS path. */
   MALLOC_CHECK;
-  if (iscygdrive_device (pathbuf))
+  if (iscygdrive (pathbuf))
     {
-      if (!cygdrive_win32_path (pathbuf, dst, 0))
+      int n = mount_table->cygdrive_len - 1;
+      if (!pathbuf[n] ||
+         (pathbuf[n] == '/' && pathbuf[n + 1] == '.' && !pathbuf[n + 2]))
+       {
+         unit = 0;
+         dst[0] = '\0';
+       }
+      else if (!cygdrive_win32_path (pathbuf, dst, unit))
        return ENOENT;
-      *flags = cygdrive_flags;
+      else
+       *flags = cygdrive_flags;
+      if (mount_table->cygdrive_len > 1)
+       devn = FH_CYGDRIVE;
       goto out;
     }
 
@@ -1497,15 +1511,23 @@ mount_info::cygdrive_posix_path (const char *src, char *dst, int trailing_slash_
 }
 
 int
-mount_info::cygdrive_win32_path (const char *src, char *dst, int trailing_slash_p)
+mount_info::cygdrive_win32_path (const char *src, char *dst, int& unit)
 {
+  int res;
   const char *p = src + cygdrive_len;
   if (!isalpha (*p) || (!isdirsep (p[1]) && p[1]))
-    return 0;
-  dst[0] = *p;
-  dst[1] = ':';
-  strcpy (dst + 2, p + 1);
-  backslashify (dst, dst, trailing_slash_p || !dst[2]);
+    {
+      res = unit = -1;
+      dst[0] = '\0';
+    }
+  else
+    {
+      dst[0] = cyg_tolower (*p);
+      dst[1] = ':';
+      strcpy (dst + 2, p + 1);
+      backslashify (dst, dst, !dst[2]);
+      unit = dst[0];
+    }
   debug_printf ("src '%s', dst '%s'", src, dst);
   return 1;
 }
@@ -2305,7 +2327,7 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
   /* Remove drivenum from list if we see a x: style path */
   if (strlen (native_path) == 2 && native_path[1] == ':')
     {
-      int drivenum = tolower (native_path[0]) - 'a';
+      int drivenum = cyg_tolower (native_path[0]) - 'a';
       if (drivenum >= 0 && drivenum <= 31)
        available_drives &= ~(1 << drivenum);
     }
@@ -2657,7 +2679,7 @@ symlink (const char *topath, const char *frompath)
          if ((cp && cp[1] == '.') || *win32_path == '.')
            attr |= FILE_ATTRIBUTE_HIDDEN;
 #endif
-         SetFileAttributesA (win32_path.get_win32 (), attr);
+         SetFileAttributes (win32_path.get_win32 (), attr);
 
          if (win32_path.fs_fast_ea ())
            set_symlink_ea (win32_path, topath);
@@ -2886,13 +2908,13 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt)
   while (suffix.next ())
     {
       error = 0;
-      fileattr = GetFileAttributesA (suffix.path);
+      fileattr = GetFileAttributes (suffix.path);
       if (fileattr == (DWORD) -1)
        {
-         /* The GetFileAttributesA call can fail for reasons that don't
+         /* The GetFileAttributes call can fail for reasons that don't
             matter, so we just return 0.  For example, getting the
             attributes of \\HOST will typically fail.  */
-         debug_printf ("GetFileAttributesA (%s) failed", suffix.path);
+         debug_printf ("GetFileAttributes (%s) failed", suffix.path);
          error = geterrno_from_win_error (GetLastError (), EACCES);
          continue;
        }
index 46b53c8b3cc4dc0ab10f8bc09ff88c98209585db..3b8bbe7e34a29ddbbac6e70fc6fbd1b71e9d7601 100644 (file)
@@ -97,7 +97,7 @@ class mount_info
   void mount_slash ();
   void to_registry ();
 
-  int cygdrive_win32_path (const char *src, char *dst, int trailing_slash_p);
+  int cygdrive_win32_path (const char *src, char *dst, int& unit);
   void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
   void read_cygdrive_info_from_registry ();
 };
This page took 0.052078 seconds and 5 git commands to generate.