diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 195362fe7..09c20baa9 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,29 @@ +2004-01-23 Christopher Faylor + + * cygheap.cc (init_cygheap::close_ctty): Protect YA vforkism. + * fhandler.h (fhandler_base::has_acls): Make pass through for path_conv + method. + (fhandler_base::isremote): Ditto. + (fhandler_base::is_fs_special): Ditto. + (fhandler_base::has_attribute): Ditto. Define new function. + (fhandler_base::fhaccess): Declare new function based on access_worker. + (fhandler_base::set_has_acls): Eliminate obsolete function. + (fhandler_base::set_isremote): Ditto. + * fhandler.cc (fhandler_base::fhaccess): Move from syscalls.cc and into + fhandler_base class. Use fhandler methods to access data rather than + path_conv stuff. + (fhandler_base::device_access_denied): Use fhaccess method. + * fhandler_disk_file.cc (fhandler_disk_file::opendir): Ditto. + (fhandler_base::open_fs): Remove calls to obsolete functions. + * fhandler_virtual.cc (fhandler_virtual::open): Ditto. + * winsup.h (access_worker): Remove obsolete access_worker declaration. + *syscalls.cc (access_worker): Move function to fhandler.cc. + (access): Use fhaccess method. + + * pinfo.cc (_pinfo::set_ctty): Clarify debugging output. + * sigproc.cc (sig_dispatch_pending): Ditto. + * syscalls.cc (setsid): Perform minor rearrangement. + 2004-01-23 Pierre Humblet * fhandler_socket.cc (fhandler_socket::create_secret_event): Avoid diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index e057f2fee..83189c306 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -176,7 +176,9 @@ void init_cygheap::close_ctty () { debug_printf ("closing cygheap->ctty %p", cygheap->ctty); +#ifdef NEWVFORK int usecount = cygheap->ctty->usecount; +#endif cygheap->ctty->close (); #ifndef NEWVFORK cygheap->ctty = NULL; diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index d5619bd63..98b685b87 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -328,7 +328,92 @@ fhandler_base::device_access_denied (int flags) if (!mode) mode |= R_OK; - return access_worker (pc, mode, this); + return fhaccess (mode); +} + +bool +fhandler_base::fhaccess (int flags) +{ + if (error ()) + { + set_errno (error ()); + return -1; + } + + if (!exists ()) + { + set_errno (ENOENT); + return -1; + } + + if (!(flags & (R_OK | W_OK | X_OK))) + return 0; + + if (is_fs_special ()) + /* short circuit */; + else if (has_attribute (FILE_ATTRIBUTE_READONLY) && (flags & W_OK)) + { + set_errno (EACCES); + return -1; + } + else if (has_acls () && allow_ntsec) + return check_file_access (get_win32_name (), flags); + + struct __stat64 st; + int r = fstat (&st); + if (r) + return -1; + r = -1; + if (flags & R_OK) + { + if (st.st_uid == myself->uid) + { + if (!(st.st_mode & S_IRUSR)) + goto done; + } + else if (st.st_gid == myself->gid) + { + if (!(st.st_mode & S_IRGRP)) + goto done; + } + else if (!(st.st_mode & S_IROTH)) + goto done; + } + if (flags & W_OK) + { + if (st.st_uid == myself->uid) + { + if (!(st.st_mode & S_IWUSR)) + goto done; + } + else if (st.st_gid == myself->gid) + { + if (!(st.st_mode & S_IWGRP)) + goto done; + } + else if (!(st.st_mode & S_IWOTH)) + goto done; + } + if (flags & X_OK) + { + if (st.st_uid == myself->uid) + { + if (!(st.st_mode & S_IXUSR)) + goto done; + } + else if (st.st_gid == myself->gid) + { + if (!(st.st_mode & S_IXGRP)) + goto done; + } + else if (!(st.st_mode & S_IXOTH)) + goto done; + } + r = 0; +done: + if (r) + set_errno (EACCES); + return r; } /* Open system call handler function. */ diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 9ce75fbc4..514609b45 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -108,7 +108,6 @@ class fhandler_base __ino64_t namehash; /* hashed filename, used as inode num */ protected: - /* Full unix path name of this file */ /* File open flags from open () and fcntl () calls */ int openflags; @@ -256,12 +255,11 @@ class fhandler_base int get_readahead_into_buffer (char *buf, size_t buflen); - bool has_acls () { return FHISSETF (HASACLS); } - void set_has_acls (int val) { FHCONDSETF (val, HASACLS); } + bool has_acls () const { return pc.has_acls (); } - bool isremote () { return FHISSETF (ISREMOTE); } - void set_isremote (int val) { FHCONDSETF (val, ISREMOTE); } + bool isremote () { return pc.isremote (); } + bool has_attribute (DWORD x) const {return pc.has_attribute (x);} const char *get_name () const { return pc.normalized_path; } const char *get_win32_name () { return pc.get_win32 (); } __ino64_t get_namehash () { return namehash; } @@ -364,8 +362,9 @@ class fhandler_base virtual int closedir (DIR *); virtual bool is_slow () {return 0;} bool is_auto_device () {return isdevice () && !dev ().isfs ();} - bool is_fs_special () {return dev ().isfs ();} - bool device_access_denied (int) __attribute__ ((regparm (1))); + bool is_fs_special () {return pc.is_fs_special ();} + bool device_access_denied (int) __attribute__ ((regparm (2))); + bool fhaccess (int flags) __attribute__ ((regparm (2))); }; class fhandler_socket: public fhandler_base diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index f86432a31..d60d632b2 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -395,9 +395,6 @@ fhandler_base::open_fs (int flags, mode_t mode) return 0; } - set_has_acls (pc.has_acls ()); - set_isremote (pc.isremote ()); - int res = fhandler_base::open (flags | O_DIROPEN, mode); if (!res) goto out; @@ -632,7 +629,7 @@ fhandler_disk_file::opendir () set_errno (ENOMEM); goto free_dirname; } - else if (access_worker (pc, R_OK, this) != 0) + else if (fhaccess (R_OK) != 0) goto free_dirent; else { diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc index 957aaffc2..74d25bd6f 100644 --- a/winsup/cygwin/fhandler_virtual.cc +++ b/winsup/cygwin/fhandler_virtual.cc @@ -210,9 +210,6 @@ fhandler_virtual::open (int flags, mode_t mode) set_r_binary (1); set_w_binary (1); - set_has_acls (false); - set_isremote (false); - /* what to do about symlinks? */ set_symlink_p (false); set_execable_p (not_executable); diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 4a01193ae..c53ff9125 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -258,7 +258,7 @@ pinfo::set_acl() void _pinfo::set_ctty (tty_min *tc, int flags, fhandler_tty_slave *arch) { - debug_printf ("checking if /dev/tty%d differs from input", ctty); + debug_printf ("checking if /dev/tty%d changed", ctty); if ((ctty < 0 || ctty == tc->ntty) && !(flags & O_NOCTTY)) { ctty = tc->ntty; diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 20a44a279..3c0cfddaa 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -574,7 +574,7 @@ sig_dispatch_pending () if (exit_state || GetCurrentThreadId () == sigtid || !sigqueue.start.next) { #ifdef DEBUGGING - sigproc_printf ("exit_state %d, GetCurrentThreadId () %p, sigtid %p, sigqueue.start.next %p", + sigproc_printf ("exit_state %d, cur thread id %p, sigtid %p, sigqueue.start.next %p", exit_state, GetCurrentThreadId (), sigtid, sigqueue.start.next); #endif return 0; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 95eeff4f8..16486d9a9 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -327,10 +327,10 @@ setsid (void) myself->ctty = -1; myself->sid = getpid (); myself->pgid = getpid (); - syscall_printf ("sid %d, pgid %d, ctty %d, open_fhs %d", myself->sid, - myself->pgid, myself->ctty, cygheap->open_fhs); if (cygheap->ctty) cygheap->close_ctty (); + syscall_printf ("sid %d, pgid %d, ctty %d, open_fhs %d", myself->sid, + myself->pgid, myself->ctty, cygheap->open_fhs); return myself->sid; } @@ -1239,103 +1239,21 @@ lstat (const char *name, struct __stat32 *buf) return ret; } -int -access_worker (path_conv& real_path, int flags, fhandler_base *fh) -{ - if (real_path.error) - { - set_errno (real_path.error); - return -1; - } - - if (!real_path.exists ()) - { - set_errno (ENOENT); - return -1; - } - - if (!(flags & (R_OK | W_OK | X_OK))) - return 0; - - if (real_path.is_fs_special ()) - /* short circuit */; - else if (real_path.has_attribute (FILE_ATTRIBUTE_READONLY) && (flags & W_OK)) - { - set_errno (EACCES); - return -1; - } - else if (real_path.has_acls () && allow_ntsec) - return check_file_access (real_path, flags); - - struct __stat64 st; - int r = fh ? fh->fstat (&st) : stat_worker (real_path, &st, 0); - if (r) - return -1; - r = -1; - if (flags & R_OK) - { - if (st.st_uid == myself->uid) - { - if (!(st.st_mode & S_IRUSR)) - goto done; - } - else if (st.st_gid == myself->gid) - { - if (!(st.st_mode & S_IRGRP)) - goto done; - } - else if (!(st.st_mode & S_IROTH)) - goto done; - } - if (flags & W_OK) - { - if (st.st_uid == myself->uid) - { - if (!(st.st_mode & S_IWUSR)) - goto done; - } - else if (st.st_gid == myself->gid) - { - if (!(st.st_mode & S_IWGRP)) - goto done; - } - else if (!(st.st_mode & S_IWOTH)) - goto done; - } - if (flags & X_OK) - { - if (st.st_uid == myself->uid) - { - if (!(st.st_mode & S_IXUSR)) - goto done; - } - else if (st.st_gid == myself->gid) - { - if (!(st.st_mode & S_IXGRP)) - goto done; - } - else if (!(st.st_mode & S_IXOTH)) - goto done; - } - r = 0; -done: - if (r) - set_errno (EACCES); - return r; -} - extern "C" int access (const char *fn, int flags) { // flags were incorrectly specified + int res = -1; if (flags & ~(F_OK|R_OK|W_OK|X_OK)) + set_errno (EINVAL); + else { - set_errno (EINVAL); - return -1; + fhandler_base *fh = build_fh_name (fn, NULL, PC_SYM_FOLLOW | PC_FULL, stat_suffixes); + res = fh->fhaccess (flags); + delete fh; } - - path_conv pc (fn, PC_SYM_FOLLOW | PC_FULL, stat_suffixes); - return access_worker (pc, flags); + debug_printf ("returning %d", res); + return res; } extern "C" int diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 980f661e7..7f45dbebe 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -302,7 +302,6 @@ int symlink_worker (const char *, const char *, bool, bool) __attribute__ ((regparm (3))); class path_conv; -int access_worker (path_conv&, int, class fhandler_base * = NULL) __attribute__ ((regparm (3))); int fcntl_worker (int fd, int cmd, void *arg);