diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 9e3a13218..574fff58d 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,23 @@ +2005-04-14 Christopher Faylor + + * dcrt0.cc (do_global_dtors): Run DLL dtors. + (__main): Don't rely on atexit to run dtors. + (do_exit): Specifically call do_global_dtors here. + (cygwin_exit): Ditto. + * dll_init.cc (dll_global_dtors): Make global. Only run dtors once. + (dll_list::init): Just set flag that dtors should be run. Don't rely on atexit. + * dll_init.h (dll_global_dtors): Declare. + + * exceptions.cc (sigrelse): Define. + + * path.h (is_fs_device): New method. + (is_lnk_special): Ditto. + * fhandler_disk_file.cc (fhandler_disk_file::link): Use + "is_lnk_special" rather than "is_lnk_symlink". + * syscalls.cc (rename): Ditto. + + * hookapi.cc (ld_preload): Use colon as a separator rather than space. + 2005-04-13 Corinna Vinschen * fhandler.h (class fhandler_socket): Remove utimes. diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index 9a09c7a89..a269d93bd 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -1260,6 +1260,7 @@ significandf NOSIGFE sigpause SIGFE sigpending SIGFE sigprocmask SIGFE +sigrelse SIGFE sigsuspend SIGFE sigwait SIGFE sigwaitinfo SIGFE diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index c5db62c07..b24e5fe16 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -129,9 +129,11 @@ char title_buf[TITLESIZE + 1]; static void do_global_dtors (void) { - if (user_data->dtors) + dll_global_dtors (); + void (**pfunc) () = user_data->dtors; + if (pfunc) { - void (**pfunc)() = user_data->dtors; + user_data->dtors = NULL; while (*++pfunc) (*pfunc) (); } @@ -972,7 +974,6 @@ extern "C" void __main (void) { do_global_ctors (user_data->ctors, false); - atexit (do_global_dtors); } exit_states NO_COPY exit_state; @@ -994,6 +995,8 @@ do_exit (int status) EnterCriticalSection (&exit_lock); muto::set_exiting_thread (); + do_global_dtors (); + if (exit_state < ES_EVENTS_TERMINATE) { exit_state = ES_EVENTS_TERMINATE; @@ -1096,6 +1099,7 @@ cygwin_atexit (void (*function)(void)) extern "C" void cygwin_exit (int n) { + do_global_dtors (); if (atexit_lock) atexit_lock.acquire (); exit (n); diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 4c3d9a26c..b3949062c 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -24,14 +24,17 @@ extern void __stdcall check_sanity_and_sync (per_process *); dll_list NO_COPY dlls; static int NO_COPY in_forkee; -static int dll_global_dtors_recorded; +static bool dll_global_dtors_recorded; /* Run destructors for all DLLs on exit. */ -static void +void dll_global_dtors () { - for (dll *d = dlls.istart (DLL_ANY); d; d = dlls.inext ()) - d->p.run_dtors (); + int recorded = dll_global_dtors_recorded; + dll_global_dtors_recorded = false; + if (recorded) + for (dll *d = dlls.istart (DLL_ANY); d; d = dlls.inext ()) + d->p.run_dtors (); } /* Run all constructors associated with a dll */ @@ -215,12 +218,7 @@ dll_list::detach (void *retaddr) void dll_list::init () { - /* Make sure that destructors are called on exit. */ - if (!dll_global_dtors_recorded) - { - atexit (dll_global_dtors); - dll_global_dtors_recorded = 1; - } + dll_global_dtors_recorded = true; /* Walk the dll chain, initializing each dll */ dll *d = &start; diff --git a/winsup/cygwin/dll_init.h b/winsup/cygwin/dll_init.h index 17e8e3ab4..2c4fb49c3 100644 --- a/winsup/cygwin/dll_init.h +++ b/winsup/cygwin/dll_init.h @@ -89,3 +89,4 @@ public: }; extern dll_list dlls; +void dll_global_dtors (); diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 96702b1de..fb4e0e91f 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -909,6 +909,24 @@ sighold (int sig) return 0; } +extern "C" int +sigrelse (int sig) +{ + /* check that sig is in right range */ + if (sig < 0 || sig >= NSIG) + { + set_errno (EINVAL); + syscall_printf ("signal %d out of range", sig); + return -1; + } + mask_sync.acquire (INFINITE); + sigset_t mask = myself->getsigmask (); + sigdelset (&mask, sig); + set_signal_mask (mask); + mask_sync.release (); + return 0; +} + /* Update the signal mask for this process and return the old mask. Called from sigdelayed */ diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 80d762ddc..8a08f3b91 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -701,7 +701,7 @@ fhandler_disk_file::link (const char *newpath) /* Shortcut hack. */ char new_lnk_buf[CYG_MAX_PATH + 5]; - if (allow_winsymlinks && pc.is_lnk_symlink () && !newpc.case_clash) + if (allow_winsymlinks && pc.is_lnk_special () && !newpc.case_clash) { strcpy (new_lnk_buf, newpath); strcat (new_lnk_buf, ".lnk"); @@ -800,7 +800,7 @@ fhandler_disk_file::link (const char *newpath) success: close (); - if (!allow_winsymlinks && pc.is_lnk_symlink ()) + if (!allow_winsymlinks && pc.is_lnk_special ()) SetFileAttributes (newpc, (DWORD) pc | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY); diff --git a/winsup/cygwin/hookapi.cc b/winsup/cygwin/hookapi.cc index 09c70c24b..9fe62383c 100644 --- a/winsup/cygwin/hookapi.cc +++ b/winsup/cygwin/hookapi.cc @@ -197,7 +197,7 @@ ld_preload () char *s = (char *) alloca (strlen (p) + 1); strcpy (s, p); char *here = NULL; - for (p = strtok_r (s, " \t\n", &here); p; p = strtok_r (NULL, " \t\n", &here)) + for (p = strtok_r (s, ":\t\n", &here); p; p = strtok_r (NULL, ":\t\n", &here)) { path_conv lib (p); if (!LoadLibrary (lib)) diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index bc3e2cc17..f21c4b999 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -144,7 +144,9 @@ class path_conv int isfifo () const {return dev == FH_FIFO;} int isspecial () const {return dev.devn && dev.devn != FH_FS;} int is_auto_device () const {return isdevice () && !is_fs_special ();} + int is_fs_device () const {return isdevice () && is_fs_special ();} int is_fs_special () const {return isspecial () && dev.isfs ();} + int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();} int issocket () const {return dev.devn == FH_UNIX;} int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;} bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;} diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index b3e7eb04f..da50b4fad 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1135,7 +1135,7 @@ rename (const char *oldpath, const char *newpath) /* Shortcut hack. */ char new_lnk_buf[CYG_MAX_PATH + 5]; - if (real_old.is_lnk_symlink () && !real_new.error && !real_new.case_clash) + if (real_old.is_lnk_special () && !real_new.error && !real_new.case_clash) { strcpy (new_lnk_buf, newpath); strcat (new_lnk_buf, ".lnk"); @@ -1170,7 +1170,7 @@ rename (const char *oldpath, const char *newpath) SetFileAttributes (real_new, (DWORD) real_new & ~FILE_ATTRIBUTE_READONLY); /* Shortcut hack No. 2, part 1 */ - if (!real_old.issymlink () && !real_new.error && real_new.is_lnk_symlink () + if (!real_old.issymlink () && !real_new.error && real_new.is_lnk_special () && (lnk_suffix = strrchr (real_new.get_win32 (), '.'))) *lnk_suffix = '\0';