diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a2171c5de..cb2779432 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,28 @@ +Wed May 30 23:51:32 2001 Earnie Boyd + + * 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 + + * 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 * sec_helper.cc (cygsid::getfrompw): Change parameter to `const'. diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index d94429665..4b042b285 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -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); diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index aed8bfe6e..6f193c385 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -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); } diff --git a/winsup/cygwin/ntea.cc b/winsup/cygwin/ntea.cc index 2c9df4ce6..85cc4187f 100644 --- a/winsup/cygwin/ntea.cc +++ b/winsup/cygwin/ntea.cc @@ -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; diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 4f7a03acc..31388416c 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -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) diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 49b475993..ee23d9fd9 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -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; + DWORD vol_flags; + DWORD drive_type; + DWORD vol_serial; - 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;} + 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; diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 2a5749971..c618c0794 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -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; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index a4252532f..98df195f9 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -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)