OSDN Git Service

* path.cc (chdir): Always send unsigned chars to isspace since newlib's isspace
authorcgf <cgf>
Thu, 31 May 2001 05:25:45 +0000 (05:25 +0000)
committercgf <cgf>
Thu, 31 May 2001 05:25:45 +0000 (05:25 +0000)
doesn't deal well with "negative" chars.
* fhandler.cc (fhandler_disk_file::open): Propagate remote status of file
garnered from path_conv.  Move #! checking to fstat.
(fhandler_disk_file::fstat): Reorganize st_mode setting to eliminate
duplication.  Move check for #! here from fhandler::open.
* fhandler.h (fhandler_base::isremote): New method.
(fhandler_base::set_isremote): Ditto.
(fhandler_base::set_execable_p): Also record "don't care if executable state".
(fhandler_base::dont_care_if_execable): New method.
* path.cc (path_conv::check): Clear new flags.  Appropriately set vol_flags,
drive_type, and is_remote_drive.
* path.h: Add new flags and methods for manipulating them.
* syscalls.cc (_unlink): Use isremote() to determine if a path is remote rather
than calling GetDriveType.
(stat_worker): Ditto.
* security.cc (get_file_attribute): Or attribute with result of NTReadEA to be
consistent with get_nt_attribute.

winsup/cygwin/ChangeLog
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler.h
winsup/cygwin/ntea.cc
winsup/cygwin/path.cc
winsup/cygwin/path.h
winsup/cygwin/security.cc
winsup/cygwin/syscalls.cc

index a2171c5..cb27794 100644 (file)
@@ -1,3 +1,28 @@
+Wed May 30 23:51:32 2001  Earnie Boyd  <earnie_boyd@yahoo.com>
+
+       * path.cc (chdir): Always send unsigned chars to isspace since newlib's
+       isspace doesn't deal well with "negative" chars.
+
+Wed May 30 23:51:32 2001  Christopher Faylor <cgf@cygnus.com>
+
+       * fhandler.cc (fhandler_disk_file::open): Propagate remote status of
+       file garnered from path_conv.  Move #! checking to fstat.
+       (fhandler_disk_file::fstat): Reorganize st_mode setting to eliminate
+       duplication.  Move check for #! here from fhandler::open.
+
+       * fhandler.h (fhandler_base::isremote): New method.
+       (fhandler_base::set_isremote): Ditto.
+       (fhandler_base::set_execable_p): Also record "don't care if executable state".
+       (fhandler_base::dont_care_if_execable): New method.
+       * path.cc (path_conv::check): Clear new flags.  Appropriately set
+       vol_flags, drive_type, and is_remote_drive.
+       * path.h: Add new flags and methods for manipulating them.
+       * syscalls.cc (_unlink): Use isremote() to determine if a path is
+       remote rather than calling GetDriveType.
+       (stat_worker): Ditto.
+       * security.cc (get_file_attribute): Or attribute with result of
+       NTReadEA to be consistent with get_nt_attribute.
+
 Tue May 29 19:02:00 2001  Corinna Vinschen <corinna@vinschen.de>
 
        * sec_helper.cc (cygsid::getfrompw): Change parameter to `const'.
index d944296..4b042b2 100644 (file)
@@ -920,6 +920,7 @@ fhandler_disk_file::fstat (struct stat *buf)
   buf->st_blksize = S_BLKSIZE;
   buf->st_blocks  = ((unsigned long) buf->st_size + S_BLKSIZE-1) / S_BLKSIZE;
 
+  buf->st_mode = 0;
   /* Using a side effect: get_file_attibutes checks for
      directory. This is used, to set S_ISVTX, if needed.  */
   if (local.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
@@ -938,9 +939,7 @@ fhandler_disk_file::fstat (struct stat *buf)
        buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
 
       buf->st_mode &= ~S_IFMT;
-      if (get_symlink_p ())
-       buf->st_mode |= S_IFLNK;
-      else if (get_socket_p ())
+      if (get_socket_p ())
        buf->st_mode |= S_IFSOCK;
       else if (local.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        buf->st_mode |= S_IFDIR;
@@ -949,16 +948,13 @@ fhandler_disk_file::fstat (struct stat *buf)
     }
   else
     {
-      buf->st_mode = 0;
       buf->st_mode |= STD_RBITS;
 
       if (!(local.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
        buf->st_mode |= STD_WBITS;
       /* | S_IWGRP | S_IWOTH; we don't give write to group etc */
 
-      if (get_symlink_p ())
-       buf->st_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
-      else if (get_socket_p ())
+      if (get_socket_p ())
        buf->st_mode |= S_IFSOCK;
       else
        switch (GetFileType (get_handle ()))
@@ -968,11 +964,25 @@ fhandler_disk_file::fstat (struct stat *buf)
            buf->st_mode |= S_IFCHR;
            break;
          case FILE_TYPE_DISK:
-          if (local.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-            buf->st_mode |= S_IFDIR | STD_XBITS;
+           if (local.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+             buf->st_mode |= S_IFDIR | STD_XBITS;
           else
             {
-              buf->st_mode |= S_IFREG;
+               buf->st_mode |= S_IFREG;
+               if (!dont_care_if_execable () && !get_execable_p ())
+                 {
+                   DWORD done;
+                   char magic[3];
+                   /* FIXME should we use /etc/magic ? */
+                   magic[0] = magic[1] = magic[2] = '\0';
+                   if (ReadFile (get_handle (), magic, 3, &done, 0)
+                       && done == 3)
+                     {
+                       if (has_exec_chars (magic, done))
+                         set_execable_p ();
+                       SetFilePointer (get_handle(), -(LONG) done, NULL, FILE_CURRENT);
+                     }
+                 }
                if (get_execable_p ())
                  buf->st_mode |= STD_XBITS;
             }
@@ -1241,6 +1251,7 @@ fhandler_disk_file::open (path_conv& real_path, int flags, mode_t mode)
     }
 
   set_has_acls (real_path.has_acls ());
+  set_isremote (real_path.isremote ());
 
   if (real_path.file_attributes () != (DWORD)-1
       && (real_path.file_attributes () & FILE_ATTRIBUTE_DIRECTORY))
@@ -1266,24 +1277,6 @@ fhandler_disk_file::open (path_conv& real_path, int flags, mode_t mode)
       return 0;
     }
 
-  extern BOOL allow_ntea;
-
-  if (real_path.isdisk ()
-      && !(real_path.file_attributes () & FILE_ATTRIBUTE_DIRECTORY)
-      && (real_path.exec_state () == dont_know_if_executable)
-      && !allow_ntea && (!allow_ntsec || !real_path.has_acls ()))
-    {
-      DWORD done;
-      char magic[3];
-      /* FIXME should we use /etc/magic ? */
-      magic[0] = magic[1] = magic[2] = '\0';
-      ReadFile (get_handle (), magic, 3, &done, 0);
-      if (has_exec_chars (magic, done))
-       real_path.set_exec ();
-      if (!(flags & O_APPEND))
-       SetFilePointer (get_handle(), 0, 0, FILE_BEGIN);
-    }
-
   if (flags & O_APPEND)
     SetFilePointer (get_handle(), 0, 0, FILE_END);
 
index aed8bfe..6f193c3 100644 (file)
@@ -71,6 +71,8 @@ enum
   FH_FFIXUP  = 0x02000000,     /* Set if need to fixup after fork. */
   FH_LOCAL   = 0x04000000,     /* File is unix domain socket */
   FH_FIFO    = 0x08000000,     /* File is FIFO */
+  FH_ISREMOTE= 0x10000000,     /* File is on a remote drive */
+  FH_DCEXEC  = 0x20000000,     /* Don't care if this is executable */
   FH_HASACLS = 0x40000000,     /* True if fs of file has ACLS */
 
   /* Device flags */
@@ -241,8 +243,10 @@ public:
   void set_execable_p (executable_states val)
   {
     FHCONDSETF (val == is_executable, EXECABL);
+    FHCONDSETF (val == dont_care_if_executable, DCEXEC);
   }
   void set_execable_p () { FHSETF (EXECABL); }
+  int dont_care_if_execable () { return FHISSETF (DCEXEC); }
 
   int get_append_p () { return FHISSETF (APPEND); }
   void set_append_p (int val) { FHCONDSETF (val, APPEND); }
@@ -264,6 +268,9 @@ public:
   int has_acls () { return FHISSETF (HASACLS); }
   void set_has_acls (int val) { FHCONDSETF (val, HASACLS); }
 
+  int isremote () { return FHISSETF (ISREMOTE); }
+  void set_isremote (int val) { FHCONDSETF (val, ISREMOTE); }
+
   int no_free_names () { return FHISSETF (NOFRNAME); }
   void set_no_free_names (int val) { FHCONDSETF (val, NOFRNAME); }
   void set_no_free_names () { FHSETF (NOFRNAME); }
index 2c9df4c..85cc418 100644 (file)
@@ -86,7 +86,7 @@ int __stdcall
 NTReadEA (const char *file, const char *attrname, char *attrbuf, int len)
 {
     /* return immediately if NTEA usage is turned off */
-    if (! allow_ntea)
+    if (!allow_ntea)
       return FALSE;
 
     HANDLE hFileSource;
@@ -257,7 +257,7 @@ BOOL __stdcall
 NTWriteEA (const char *file, const char *attrname, char *buf, int len)
 {
   /* return immediately if NTEA usage is turned off */
-  if (! allow_ntea)
+  if (!allow_ntea)
     return TRUE;
 
   HANDLE hFileSource;
index 4f7a03a..3138841 100644 (file)
@@ -374,6 +374,9 @@ path_conv::check (const char *src, unsigned opt,
   fileattr = (DWORD) -1;
   case_clash = FALSE;
   devn = unit = 0;
+  vol_flags = 0;
+  drive_type = 0;
+  is_remote_drive = 0;
 
   if (!(opt & PC_NULLEMPTY))
     error = 0;
@@ -634,14 +637,13 @@ out:
       return;
     }
 
-  DWORD serial, volflags;
   char fs_name[16];
 
   strcpy (tmp_buf, this->path);
 
   if (!rootdir (tmp_buf) ||
-      !GetVolumeInformation (tmp_buf, NULL, 0, &serial, NULL,
-                            &volflags, fs_name, 16))
+      !GetVolumeInformation (tmp_buf, NULL, 0, &vol_serial, NULL,
+                            &vol_flags, fs_name, 16))
     {
       debug_printf ("GetVolumeInformation(%s) = ERR, this->path(%s), set_has_acls(FALSE)",
                    tmp_buf, this->path, GetLastError ());
@@ -652,13 +654,14 @@ out:
     {
       set_isdisk ();
       debug_printf ("GetVolumeInformation(%s) = OK, this->path(%s), set_has_acls(%d)",
-                   tmp_buf, this->path, volflags & FS_PERSISTENT_ACLS);
-      if (!allow_smbntsec
-          && ((tmp_buf[0] == '\\' && tmp_buf[1] == '\\')
-              || GetDriveType (tmp_buf) == DRIVE_REMOTE))
+                   tmp_buf, this->path, vol_flags & FS_PERSISTENT_ACLS);
+      drive_type = GetDriveType (tmp_buf);
+      if (drive_type == DRIVE_REMOTE || (drive_type == DRIVE_UNKNOWN && (tmp_buf[0] == '\\' && tmp_buf[1] == '\\')))
+       is_remote_drive = 1;
+      if (!allow_smbntsec && is_remote_drive)
         set_has_acls (FALSE);
       else
-        set_has_acls (volflags & FS_PERSISTENT_ACLS);
+        set_has_acls (vol_flags & FS_PERSISTENT_ACLS);
       /* Known file systems with buggy open calls. Further explanation
          in fhandler.cc (fhandler_disk_file::open). */
       set_has_buggy_open (strcmp (fs_name, "SUNWNFS") == 0);
@@ -2894,7 +2897,7 @@ chdir (const char *dir)
      whitespace to SetCurrentDirectory.  This doesn't work too well
      with other parts of the API, though, apparently.  So nuke trailing
      white space. */
-  for (s = strchr (dir, '\0'); --s >= dir && isspace (*s); )
+  for (s = strchr (dir, '\0'); --s >= dir && isspace ((unsigned int) *s); )
     *s = '\0';
 
   if (path.error)
index 49b4759..ee23d9f 100644 (file)
@@ -57,19 +57,24 @@ class path_conv
 {
   char path[MAX_PATH];
   void add_ext_from_sym (symlink_info&);
+  bool is_remote_drive;
  public:
 
   unsigned path_flags;
-
-  int isdisk () {return path_flags & PATH_ISDISK;}
-  int has_acls () {return path_flags & PATH_HASACLS;}
-  int has_symlinks () {return path_flags & PATH_HAS_SYMLINKS;}
-  int hasgood_inode () {return path_flags & PATH_HASACLS;}  // Not strictly correct
-  int has_buggy_open () {return path_flags & PATH_HASBUGGYOPEN;}
-  int isbinary () {return path_flags & PATH_BINARY;}
-  int issymlink () {return path_flags & PATH_SYMLINK;}
-  int issocket () {return path_flags & PATH_SOCKET;}
-  int iscygexec () {return path_flags & PATH_CYGWIN_EXEC;}
+  DWORD vol_flags;
+  DWORD drive_type;
+  DWORD vol_serial;
+
+  int isdisk () const { return path_flags & PATH_ISDISK;}
+  int isremote () const {return is_remote_drive;}
+  int has_acls () const {return path_flags & PATH_HASACLS;}
+  int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;}
+  int hasgood_inode () const {return path_flags & PATH_HASACLS;}  // Not strictly correct
+  int has_buggy_open () const {return path_flags & PATH_HASBUGGYOPEN;}
+  int isbinary () const {return path_flags & PATH_BINARY;}
+  int issymlink () const {return path_flags & PATH_SYMLINK;}
+  int issocket () const {return path_flags & PATH_SOCKET;}
+  int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;}
   executable_states exec_state ()
   {
     extern int _check_for_executable;
index 2a57499..c618c07 100644 (file)
@@ -1199,7 +1199,9 @@ get_file_attribute (int use_ntsec, const char *file,
   if (!attribute)
     return 0;
 
+  int oatt = *attribute;
   res = NTReadEA (file, ".UNIXATTR", (char *) attribute, sizeof (*attribute));
+  *attribute |= oatt;
 
   /* symlinks are everything for everyone!*/
   if ((*attribute & S_IFLNK) == S_IFLNK)
@@ -1523,8 +1525,7 @@ set_file_attribute (int use_ntsec, const char *file,
 
   if (!use_ntsec || !allow_ntsec)
     {
-      if (!NTWriteEA (file, ".UNIXATTR",
-                      (char *) &attribute, sizeof (attribute)))
+      if (!NTWriteEA (file, ".UNIXATTR", (char *) &attribute, sizeof (attribute)))
        {
          __seterrno ();
          return -1;
index a425253..98df195 100644 (file)
@@ -133,14 +133,10 @@ _unlink (const char *ourname)
 
       if (i > 0)
        {
-         DWORD dtype;
          if (os_being_run == winNT || lasterr != ERROR_ACCESS_DENIED)
            goto err;
 
-         char root[MAX_PATH];
-         strcpy (root, win32_name);
-         dtype = GetDriveType (rootdir (root));
-         if (dtype & DRIVE_REMOTE)
+         if (win32_name.isremote ())
            {
              syscall_printf ("access denied on remote drive");
              goto err;  /* Can't detect this, unfortunately */
@@ -708,7 +704,7 @@ chown_worker (const char *name, unsigned fmode, uid_t uid, gid_t gid)
        attrib |= S_IFDIR;
       res = get_file_attribute (win32_path.has_acls (),
                                win32_path.get_win32 (),
-                                (int *) &attrib,
+                               (int *) &attrib,
                                &old_uid,
                                &old_gid);
       if (!res)
@@ -1016,7 +1012,6 @@ stat_worker (const char *caller, const char *name, struct stat *buf,
   uid_t uid;
   gid_t gid;
 
-  char root[MAX_PATH];
   UINT dtype;
   fhandler_disk_file fh (NULL);
 
@@ -1043,8 +1038,7 @@ stat_worker (const char *caller, const char *name, struct stat *buf,
 
   debug_printf ("%d = file_attributes for '%s'", atts, real_path.get_win32 ());
 
-  strcpy (root, real_path.get_win32 ());
-  dtype = GetDriveType (rootdir (root));
+  dtype = real_path.drive_type;
 
   if ((atts == -1 || ! (atts & FILE_ATTRIBUTE_DIRECTORY) ||
        (os_being_run == winNT
@@ -1108,8 +1102,9 @@ stat_worker (const char *caller, const char *name, struct stat *buf,
       else
        buf->st_mode = S_IFREG;
       if (!real_path.has_acls ()
-         || get_file_attribute (real_path.has_acls (), real_path.get_win32 (),
-                                &buf->st_mode, &buf->st_uid, &buf->st_gid))
+         || get_file_attribute (TRUE, real_path.get_win32 (),
+                                &buf->st_mode,
+                                &buf->st_uid, &buf->st_gid))
        {
          buf->st_mode |= STD_RBITS | STD_XBITS;
          if ((atts & FILE_ATTRIBUTE_READONLY) == 0)