From dfb3d3163986fd82c6f51d5f07421ad5549b6660 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Fri, 21 Mar 2003 15:15:16 +0000 Subject: merge from trunk --- winsup/cygwin/ChangeLog | 39 ++++++++++ winsup/cygwin/dcrt0.cc | 2 +- winsup/cygwin/exceptions.cc | 4 +- winsup/cygwin/fhandler_disk_file.cc | 2 +- winsup/cygwin/fhandler_socket.cc | 9 ++- winsup/cygwin/glob.c | 17 +---- winsup/cygwin/include/cygwin/version.h | 4 + winsup/cygwin/security.cc | 25 ++++--- winsup/cygwin/sigproc.h | 131 +++++++++++++++++++++++++++++++++ winsup/cygwin/syscalls.cc | 22 ++++-- 10 files changed, 216 insertions(+), 39 deletions(-) create mode 100644 winsup/cygwin/sigproc.h diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 81265353885..f2b5123f846 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,42 @@ +2003-03-20 Corinna Vinschen + + * fhandler_socket.cc (fhandler_socket::sendto): Restrict EPIPE and + SIGPIPE handling to connection oriented sockets. Add comment. + +2003-03-19 Christopher Faylor + + * sigproc.h (signal_fixup_after_exec): Eliminate argument in declaration. + * exceptions.cc (signal_fixup_after_exec): Eliminate argument in + definition. Don't reset signal handlers after spawm. Just treat like + fork/exec. + * dcrt0.cc (dll_crt0_1): Don't pass PROC_SPAWN argument to + signal_fixup_after_exec. + * syscalls.cc (unlink): Don't change attributes of file if not readonly/system. + Ditto for resetting of arguments. + +2003-03-19 Corinna Vinschen + + * glob.c: Eliminate __INSIDE_CYGWIN__ preprocessor conditionals + throughout. + +2003-03-19 Corinna Vinschen + + * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): Fix + wrong usage of S_IFDIR. + * security.cc (get_attribute_from_acl): Ditto. + (get_file_attribute): Fix wrong usage of S_IFLNK. + (get_object_attribute): Ditto. + (alloc_sd): Fix wrong usage of S_IFDIR. + * syscalls.cc (chmod): Allow chmod'ing of socket files. + +2003-03-19 Corinna Vinschen + + * include/cygwin/version.h (CYGWIN_VERSION_CHECK_FOR_USING_BIG_TYPES): + Define. + * glob.c (g_lstat): Use CYGWIN_VERSION_CHECK_FOR_USING_BIG_TYPES + instead of numerical constants. + (g_stat): Ditto. + 2003-03-18 Thomas Pfaff * pthread.cc (pthread_attr_init): Remove diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 8407a3bd141..430b74e3d57 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -611,7 +611,7 @@ dll_crt0_1 () envp = spawn_info->moreinfo->envp; envc = spawn_info->moreinfo->envc; cygheap->fdtab.fixup_after_exec (spawn_info->parent); - signal_fixup_after_exec (child_proc_info->type == PROC_SPAWN); + signal_fixup_after_exec (); CloseHandle (spawn_info->parent); if (spawn_info->moreinfo->old_title) { diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index e2df0c91315..5acbe558de3 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -735,13 +735,13 @@ signal_fixup_after_fork () } void __stdcall -signal_fixup_after_exec (bool isspawn) +signal_fixup_after_exec () { /* Set up child's signal handlers */ for (int i = 0; i < NSIG; i++) { myself->getsig (i).sa_mask = 0; - if (myself->getsig (i).sa_handler != SIG_IGN || isspawn) + if (myself->getsig (i).sa_handler != SIG_IGN) myself->getsig (i).sa_handler = SIG_DFL; } } diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 667f160ff28..9390a3186cb 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -311,7 +311,7 @@ fhandler_base::fstat_helper (struct __stat64 *buf, buf->st_mode |= STD_WBITS; /* | S_IWGRP | S_IWOTH; we don't give write to group etc */ - if (buf->st_mode & S_IFDIR) + if (S_ISDIR (buf->st_mode)) buf->st_mode |= S_IFDIR | STD_XBITS; else if (buf->st_mode & S_IFMT) /* nothing */; diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index a79259d94c4..077d0be9a88 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -1033,8 +1033,13 @@ fhandler_socket::sendto (const void *ptr, size_t len, int flags, else res = ret; - /* Special handling for SIGPIPE */ - if (res == -1 && get_errno () == ESHUTDOWN) + /* Special handling for EPIPE and SIGPIPE. + + EPIPE is generated if the local end has been shut down on a connection + oriented socket. In this case the process will also receive a SIGPIPE + unless MSG_NOSIGNAL is set. */ + if (res == -1 && get_errno () == ESHUTDOWN + && get_socket_type () == SOCK_STREAM) { set_errno (EPIPE); if (! (flags & MSG_NOSIGNAL)) diff --git a/winsup/cygwin/glob.c b/winsup/cygwin/glob.c index c74a7812cee..1db8685aa07 100644 --- a/winsup/cygwin/glob.c +++ b/winsup/cygwin/glob.c @@ -81,6 +81,7 @@ #include #include "perprocess.h" +#include "cygwin/version.h" #ifdef __weak_alias #ifdef __LIBC12_SOURCE__ @@ -96,11 +97,7 @@ __weak_alias(__globfree13,___globfree13); #ifdef __LIBC12_SOURCE__ #define STAT stat12 #else -#if defined (__INSIDE_CYGWIN__) #define STAT __stat64 -#else -#define STAT stat -#endif #endif #define DOLLAR '$' @@ -840,17 +837,13 @@ g_lstat(fn, sb, pglob) struct __stat32 lsb; int ret; - if (user_data->api_major > 0 || user_data->api_minor > 78) + if (CYGWIN_VERSION_CHECK_FOR_USING_BIG_TYPES) ret = (*pglob->gl_lstat)(buf, &sb); else if (!(ret = (*pglob->gl_lstat)(buf, &lsb))) stat32_to_STAT (&lsb, sb); return ret; } -#ifdef __INSIDE_CYGWIN__ return(lstat64(buf, sb)); -#else - return(lstat(buf, sb)); -#endif } static int @@ -866,17 +859,13 @@ g_stat(fn, sb, pglob) struct __stat32 lsb; int ret; - if (user_data->api_major > 0 || user_data->api_minor > 78) + if (CYGWIN_VERSION_CHECK_FOR_USING_BIG_TYPES) ret = (*pglob->gl_stat)(buf, &sb); if (!(ret = (*pglob->gl_stat)(buf, &lsb))) stat32_to_STAT (&lsb, sb); return ret; } -#ifdef __INSIDE_CYGWIN__ return(stat64(buf, sb)); -#else - return(stat(buf, sb)); -#endif } static Char * diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 60cfd10b463..6ca91004a3b 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -84,6 +84,10 @@ details. */ #define CYGWIN_VERSION_CHECK_FOR_OLD_O_NONBLOCK \ (CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) <= \ 28) + +#define CYGWIN_VERSION_CHECK_FOR_USING_BIG_TYPES \ + (CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) >= \ + 79) /* We used to use the DLL major/minor to track non-backward-compatible interface changes to the API. Now we use an API major/minor number for this purpose. */ diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 5d0e51b711b..0295eebfb53 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -1267,7 +1267,7 @@ get_attribute_from_acl (mode_t *attribute, PACL acl, PSID owner_sid, *flags |= ((!(*anti & S_IXOTH)) ? S_IXOTH : 0) | ((!(*anti & S_IXGRP)) ? S_IXGRP : 0) | ((!(*anti & S_IXUSR)) ? S_IXUSR : 0); - if ((*attribute & S_IFDIR) && + if ((S_ISDIR (*attribute)) && (ace->Mask & (FILE_WRITE_DATA | FILE_EXECUTE | FILE_DELETE_CHILD)) == (FILE_WRITE_DATA | FILE_EXECUTE)) *flags |= S_ISVTX; @@ -1404,7 +1404,7 @@ get_file_attribute (int use_ntsec, const char *file, if (gidret) *gidret = ILLEGAL_GID; } - else if (attribute && (*attribute & S_IFLNK) == S_IFLNK) + else if (attribute && S_ISLNK (*attribute)) *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; return 0; } @@ -1427,7 +1427,7 @@ get_file_attribute (int use_ntsec, const char *file, res = 0; /* symlinks are everything for everyone! */ - if ((*attribute & S_IFLNK) == S_IFLNK) + if (S_ISLNK (*attribute)) *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; return res > 0 ? 0 : -1; @@ -1498,7 +1498,7 @@ get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, { int res = get_nt_object_attribute (handle, object_type, attribute, uidret, gidret); - if (attribute && (*attribute & S_IFLNK) == S_IFLNK) + if (attribute && S_ISLNK (*attribute)) *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; return res; } @@ -1512,7 +1512,7 @@ get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, return 0; /* symlinks are everything for everyone! */ - if ((*attribute & S_IFLNK) == S_IFLNK) + if (S_ISLNK (*attribute)) *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; return 0; @@ -1652,8 +1652,8 @@ alloc_sd (__uid32_t uid, __gid32_t gid, int attribute, owner_allow |= FILE_GENERIC_WRITE; if (attribute & S_IXUSR) owner_allow |= FILE_GENERIC_EXECUTE; - if ((attribute & (S_IFDIR | S_IWUSR | S_IXUSR)) - == (S_IFDIR | S_IWUSR | S_IXUSR)) + if (S_ISDIR (attribute) + && (attribute & (S_IWUSR | S_IXUSR)) == (S_IWUSR | S_IXUSR)) owner_allow |= FILE_DELETE_CHILD; /* Construct allow attribute for group. */ @@ -1665,8 +1665,9 @@ alloc_sd (__uid32_t uid, __gid32_t gid, int attribute, group_allow |= STANDARD_RIGHTS_WRITE | FILE_GENERIC_WRITE; if (attribute & S_IXGRP) group_allow |= FILE_GENERIC_EXECUTE; - if ((attribute & (S_IFDIR | S_IWGRP | S_IXGRP)) - == (S_IFDIR | S_IWGRP | S_IXGRP) && !(attribute & S_ISVTX)) + if (S_ISDIR (attribute) + && (attribute & (S_IWGRP | S_IXGRP)) == (S_IWGRP | S_IXGRP) + && !(attribute & S_ISVTX)) group_allow |= FILE_DELETE_CHILD; /* Construct allow attribute for everyone. */ @@ -1678,8 +1679,8 @@ alloc_sd (__uid32_t uid, __gid32_t gid, int attribute, other_allow |= STANDARD_RIGHTS_WRITE | FILE_GENERIC_WRITE; if (attribute & S_IXOTH) other_allow |= FILE_GENERIC_EXECUTE; - if ((attribute & (S_IFDIR | S_IWOTH | S_IXOTH)) - == (S_IFDIR | S_IWOTH | S_IXOTH) + if (S_ISDIR (attribute) + && (attribute & (S_IWOTH | S_IXOTH)) == (S_IWOTH | S_IXOTH) && !(attribute & S_ISVTX)) other_allow |= FILE_DELETE_CHILD; @@ -1788,7 +1789,7 @@ alloc_sd (__uid32_t uid, __gid32_t gid, int attribute, } /* Construct appropriate inherit attribute for new directories */ - if (attribute & S_IFDIR && !acl_exists ) + if (S_ISDIR (attribute) && !acl_exists ) { const DWORD inherit = SUB_CONTAINERS_AND_OBJECTS_INHERIT | INHERIT_ONLY; diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h new file mode 100644 index 00000000000..cda8cad67ca --- /dev/null +++ b/winsup/cygwin/sigproc.h @@ -0,0 +1,131 @@ +/* sigproc.h + + Copyright 1997, 1998, 2000, 2001, 2002 Red Hat, Inc. + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#ifndef _SIGPROC_H +#define _SIGPROC_H +#include + +#define EXIT_SIGNAL 0x010000 +#define EXIT_REPARENTING 0x020000 +#define EXIT_NOCLOSEALL 0x040000 + +enum procstuff +{ + PROC_ADDCHILD = 1, // add a new subprocess to list + PROC_CHILDTERMINATED = 2, // a child died + PROC_CLEARWAIT = 3, // clear all waits - signal arrived + PROC_WAIT = 4, // setup for wait() for subproc + PROC_NOTHING = 5 // nothing, really +}; + +typedef struct struct_waitq +{ + int pid; + int options; + int status; + HANDLE ev; + void *rusage; /* pointer to potential rusage */ + struct struct_waitq *next; + HANDLE thread_ev; +} waitq; + +struct sigthread +{ + DWORD id; + DWORD frame; + CRITICAL_SECTION lock; + LONG winapi_lock; + BOOL exception; + bool get_winapi_lock (int test = 0); + void release_winapi_lock (); + void init (const char *s); +}; + +class sigframe +{ +private: + sigthread *st; + inline bool unregister () + { + if (!st) + return 0; + EnterCriticalSection (&st->lock); + st->frame = 0; + st->exception = 0; + st->release_winapi_lock (); + LeaveCriticalSection (&st->lock); + st = NULL; + return 1; + } + +public: + inline void set (sigthread &t, DWORD ebp, bool is_exception = 0) + { + DWORD oframe = t.frame; + st = &t; + t.frame = ebp; + t.exception = is_exception; + if (!oframe) + t.get_winapi_lock (); + } + inline void init (sigthread &t, DWORD ebp = (DWORD) __builtin_frame_address (0)) + { + if (!t.frame && t.id == GetCurrentThreadId ()) + set (t, ebp); + else + st = NULL; + } + + sigframe (): st (NULL) {} + sigframe (sigthread &t, DWORD ebp = (DWORD) __builtin_frame_address (0)) {init (t, ebp);} + ~sigframe () + { + unregister (); + } + + int call_signal_handler (); +}; + +extern sigthread mainthread; +extern HANDLE signal_arrived; +extern HANDLE sigCONT; + +BOOL __stdcall my_parent_is_alive (); +extern "C" int __stdcall sig_dispatch_pending (int force = FALSE); +extern "C" void __stdcall set_process_mask (sigset_t newmask); +extern "C" void __stdcall reset_signal_arrived (); +int __stdcall sig_handle (int, bool); +void __stdcall sig_clear (int); +void __stdcall sig_set_pending (int); +int __stdcall handle_sigsuspend (sigset_t); + +int __stdcall proc_subproc (DWORD, DWORD); + +class _pinfo; +void __stdcall proc_terminate (); +void __stdcall sigproc_init (); +void __stdcall subproc_init (); +void __stdcall sigproc_terminate (); +BOOL __stdcall proc_exists (_pinfo *) __attribute__ ((regparm(1))); +BOOL __stdcall pid_exists (pid_t) __attribute__ ((regparm(1))); +int __stdcall sig_send (_pinfo *, int, DWORD ebp = (DWORD) __builtin_frame_address (0), + bool exception = 0) __attribute__ ((regparm(3))); +void __stdcall signal_fixup_after_fork (); +void __stdcall signal_fixup_after_exec (); +void __stdcall wait_for_sigthread (); + +extern char myself_nowait_dummy[]; +extern char myself_nowait_nonmain_dummy[]; + +#define WAIT_SIG_PRIORITY THREAD_PRIORITY_TIME_CRITICAL + +#define myself_nowait ((_pinfo *)myself_nowait_dummy) +#define myself_nowait_nonmain ((_pinfo *)myself_nowait_nonmain_dummy) +#endif /*_SIGPROC_H*/ diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index c7335664aba..d40c237d6ab 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -152,8 +152,15 @@ unlink (const char *ourname) goto done; } - /* Allow us to delete even if read-only */ - SetFileAttributes (win32_name, (DWORD) win32_name & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)); + bool setattrs; + if (!((DWORD) win32_name & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))) + setattrs = false; + else + { + /* Allow us to delete even if read-only */ + SetFileAttributes (win32_name, (DWORD) win32_name & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)); + setattrs = true; + } /* Attempt to use "delete on close" semantics to handle removing a file which may be open. */ HANDLE h; @@ -161,12 +168,12 @@ unlink (const char *ourname) OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); if (h != INVALID_HANDLE_VALUE) { - (void) SetFileAttributes (win32_name, (DWORD) win32_name); + if (wincap.has_hard_links () && setattrs) + (void) SetFileAttributes (win32_name, (DWORD) win32_name); BOOL res = CloseHandle (h); syscall_printf ("%d = CloseHandle (%p)", res, h); - if (!win32_name.isremote () - || (GetFileAttributes (win32_name) == INVALID_FILE_ATTRIBUTES - || wincap.has_delete_on_close ())) + if (GetFileAttributes (win32_name) == INVALID_FILE_ATTRIBUTES + || !win32_name.isremote ()) { syscall_printf ("CreateFile (FILE_FLAG_DELETE_ON_CLOSE) succeeded"); goto ok; @@ -174,7 +181,8 @@ unlink (const char *ourname) else { syscall_printf ("CreateFile (FILE_FLAG_DELETE_ON_CLOSE) failed"); - SetFileAttributes (win32_name, (DWORD) win32_name & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)); + if (setattrs) + SetFileAttributes (win32_name, (DWORD) win32_name & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)); } } -- cgit v1.2.1