diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 80a503b50..93a3840a4 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,16 @@ +2004-03-25 Christopher Faylor + + * path.cc (normalize_posix_path): Reorganize to short circuit to DOS + path handling whenever a '\' is detected. + + * signal.cc (sigaction): Make strace output more informative. + * sigproc.cc (pending_signals::add): Just index directly into signal + array rather than treating the array as a heap. + (pending_signals::del): Ditto. + (wait_sig): Don't send signal if we already have a similar signal + queued. + * sigproc.h (call_signal_handler_now): Remove obsolete declaration. + 2004-03-23 Gerd Spalink * fhandler_dsp.cc (fhandler_dev_dsp::write): Remove type diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index e602c5e8e..96fa0628c 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -188,7 +188,6 @@ pathmatch (const char *path1, const char *path2) #define isslash(c) ((c) == '/') /* Normalize a POSIX path. - \'s are converted to /'s in the process. All duplicate /'s, except for 2 leading /'s, are deleted. The result is 0 for success, or an errno error value. */ @@ -200,14 +199,11 @@ normalize_posix_path (const char *src, char *dst) syscall_printf ("src %s", src); + const char *in_src = src; + char *in_dst = dst; + if (isdrive (src) || slash_unc_prefix_p (src)) - { - int err = normalize_win32_path (src, dst); - if (!err) - for (char *p = dst; (p = strchr (p, '\\')); p++) - *p = '/'; - return err; - } + goto win32_path; if (!isslash (src[0])) { @@ -247,6 +243,8 @@ normalize_posix_path (const char *src, char *dst) while (*src) { + if (*src == '\\') + goto win32_path; /* Strip runs of /'s. */ if (!isslash (*src)) *dst++ = *src++; @@ -309,6 +307,13 @@ done: debug_printf ("%s = normalize_posix_path (%s)", dst_start, src_start); return 0; + +win32_path: + int err = normalize_win32_path (in_src, in_dst); + if (!err) + for (char *p = in_dst; (p = strchr (p, '\\')); p++) + *p = '/'; + return err; } inline void diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 52c402c49..bd75dff32 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -349,17 +349,22 @@ extern "C" int sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact) { sig_dispatch_pending (); - sigproc_printf ("signal %d, newact %p, oldact %p", sig, newact, oldact); /* check that sig is in right range */ if (sig < 0 || sig >= NSIG) { set_errno (EINVAL); + sigproc_printf ("signal %d, newact %p, oldact %p", sig, newact, oldact); syscall_printf ("SIG_ERR = sigaction signal %d out of range", sig); return -1; } struct sigaction oa = global_sigs[sig]; + if (newact) + sigproc_printf ("signal %d, newact %p (handler %p), oa %p", sig, newact, newact->sa_handler, oa, oa.sa_handler); + else + sigproc_printf ("signal %d, newact %p, oa %p", sig, newact, oa, oa.sa_handler); + if (newact) { if (sig == SIGKILL || sig == SIGSTOP) diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index a04ea2f60..077557511 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -48,31 +48,11 @@ details. */ #define NZOMBIES 256 -class pending_signals -{ - sigpacket sigs[NSIG + 1]; - sigpacket start; - sigpacket *end; - sigpacket *prev; - sigpacket *curr; - int empty; -public: - void reset () {curr = &start; prev = &start;} - void add (sigpacket&); - void del (); - sigpacket *next (); - sigpacket *save () const {return curr;} - void restore (sigpacket *saved) {curr = saved;} - friend void __stdcall sig_dispatch_pending (bool); -}; - -static pending_signals sigq; - -struct sigaction *global_sigs; - /* * Global variables */ +struct sigaction *global_sigs; + const char *__sp_fn ; int __sp_ln; @@ -114,15 +94,37 @@ muto NO_COPY *sync_proc_subproc = NULL; // Control access to subproc stuff DWORD NO_COPY sigtid = 0; // ID of the signal thread -/* Functions - */ +/* Function declarations */ static int __stdcall checkstate (waitq *) __attribute__ ((regparm (1))); static __inline__ bool get_proc_lock (DWORD, DWORD); static void __stdcall remove_zombie (int); -static DWORD WINAPI wait_sig (VOID *arg); static int __stdcall stopped_or_terminated (waitq *, _pinfo *); static DWORD WINAPI wait_subproc (VOID *); +static DWORD WINAPI wait_sig (VOID *arg); +/* wait_sig bookkeeping */ + +class pending_signals +{ + sigpacket sigs[NSIG + 1]; + sigpacket start; + sigpacket *end; + sigpacket *prev; + sigpacket *curr; +public: + void reset () {curr = &start; prev = &start;} + void add (sigpacket&); + void del (); + sigpacket *next (); + sigpacket *save () const {return curr;} + void restore (sigpacket *saved) {curr = saved;} + friend void __stdcall sig_dispatch_pending (bool); + friend DWORD WINAPI wait_sig (VOID *arg); +}; + +static pending_signals sigq; + +/* Functions */ void __stdcall sigalloc () { @@ -1012,25 +1014,13 @@ talktome () pids[i]->commune_recv (); } -/* Process signals by waiting for a semaphore to become signaled. - Then scan an in-memory array representing queued signals. - Executes in a separate thread. - - Signals sent from this process are sent a completion signal so - that returns from kill/raise do not occur until the signal has - has been handled, as per POSIX. */ - void pending_signals::add (sigpacket& pack) { sigpacket *se; - for (se = start.next; se; se = se->next) - if (se->si.si_signo == pack.si.si_signo) - return; - while (sigs[empty].si.si_signo) - if (++empty == NSIG) - empty = 0; - se = sigs + empty; + if (sigs[pack.si.si_signo].si.si_signo) + return; + se = sigs + pack.si.si_signo; *se = pack; se->mask = &myself->getsigmask (); se->next = NULL; @@ -1039,7 +1029,6 @@ pending_signals::add (sigpacket& pack) end = se; if (!start.next) start.next = se; - empty++; } void @@ -1053,7 +1042,6 @@ pending_signals::del () #endif if (end == curr) end = prev; - empty = curr - sigs; curr = next; } @@ -1174,7 +1162,7 @@ wait_sig (VOID *self) default: if (pack.si.si_signo < 0) sig_clear (-pack.si.si_signo); - else + else if (!sigq.sigs[pack.si.si_signo].si.si_signo) { int sig = pack.si.si_signo; int sigres = pack.process (); diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index 80e5e71f1..4e70dea6b 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -66,7 +66,6 @@ int __stdcall handle_sigprocmask (int sig, const sigset_t *set, __attribute__ ((regparm (3))); extern "C" void __stdcall reset_signal_arrived (); -extern "C" int __stdcall call_signal_handler_now (); void __stdcall sig_clear (int) __attribute__ ((regparm (1))); void __stdcall sig_set_pending (int) __attribute__ ((regparm (1))); int __stdcall handle_sigsuspend (sigset_t);