diff options
author | Christopher Faylor <cgf@redhat.com> | 2003-03-01 02:05:41 +0000 |
---|---|---|
committer | Christopher Faylor <cgf@redhat.com> | 2003-03-01 02:05:41 +0000 |
commit | ae892ce74b257cfa5ec50a0a6b263f5f9be28510 (patch) | |
tree | 918c0cbfc507a46190842c60d63b422f89339ad1 | |
parent | 8762951e1db488d9f84e67e1007f0d54a675f70e (diff) | |
download | gdb-ae892ce74b257cfa5ec50a0a6b263f5f9be28510.tar.gz |
merge from trunk
-rw-r--r-- | winsup/cygwin/ChangeLog | 35 | ||||
-rw-r--r-- | winsup/cygwin/cygwin.din | 6 | ||||
-rw-r--r-- | winsup/cygwin/dcrt0.cc | 23 | ||||
-rw-r--r-- | winsup/cygwin/dll_init.cc | 17 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_socket.cc | 179 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/version.h | 4 | ||||
-rw-r--r-- | winsup/cygwin/uinfo.cc | 3 |
7 files changed, 195 insertions, 72 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 4065d80c879..b2639ac5f7b 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,32 @@ +2003-02-28 Christopher Faylor <cgf@redhat.com> + + * cygwin.din: Wrap atexit and exit with cygwin, thread-safe functions. + * dcrt0.cc (cygwin_atexit): New function. + (cygwin_exit): Ditto. + +2003-02-28 Pierre Humblet <pierre.humblet@ieee.org> + + * syscalls.cc (fstat64): Pass get_name () to pc. + (access): Pass fn to stat_worker. + +2003-03-27 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (class sock_event): New class managing Winsock + events for interruptible socket calls. + (fhandler_socket::connect): Move support for interruptible call to + class sock_event. Use class object instead. + (fhandler_socket::accept): Ditto. Remove useless casts. + +2003-03-27 Thomas Pfaff <tpfaff@gmx.net> + + * fhandler_socket.cc (fhandler_socket::connect): Add support for + an interruptable connect. + +2003-02-27 Pierre Humblet <pierre.humblet@ieee.org> + + * uinfo.cc (internal_getlogin): Only update user.groups.pgsid + if the call to set the primary group succeeds. + 2003-02-27 Christopher Faylor <cgf@redhat.com> * cygthread::detach: Improve error message. @@ -116,8 +145,8 @@ (wincap_2000): Ditto. (wincap_xp): Ditto. * path.h (path_conv::fs_flags): New method. - * fhandler_disk_file.cc: Include winioctl.h for DeviceIoControl. - (fhandler_disk_file::open): Set newly created and truncated files as + * fhandler_disk_file.cc: Include winioctl.h for DeviceIoControl. + (fhandler_disk_file::open): Set newly created and truncated files as sparse on platforms that support it. 2003-02-17 Pierre Humblet <pierre.humblet@ieee.org> @@ -145,7 +174,7 @@ from non-waitloop call. 2003-02-13 Vaclav Haisman <V.Haisman@sh.cvut.cz> - Christopher Faylor <cgf@redhat.com> + Christopher Faylor <cgf@redhat.com> * fhandler_console.cc (fhandler_console::write_normal): Use MessageBeep for bell sound. diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index a2dd2667463..d723c7260c6 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -156,8 +156,8 @@ atanh _atanh = atanh atanhf _atanhf = atanhf -atexit -_atexit = atexit +atexit = cygwin_atexit +_atexit = cygwin_atexit atof _atof = atof atoff @@ -372,7 +372,7 @@ execve _execve = execve execvp _execvp = execvp -exit +exit = cygwin_exit exp _exp = exp exp2 diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 37212730008..8407a3bd141 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -34,6 +34,7 @@ details. */ #include "cygwin_version.h" #include "dll_init.h" #include "cygthread.h" +#include "sync.h" #define MAX_AT_FILE_LEVEL 10 @@ -1063,6 +1064,28 @@ do_exit (int status) myself->exit (n); } +static muto *atexit_lock; + +extern "C" int +cygwin_atexit (void (*function)(void)) +{ + int res; + if (!atexit_lock) + new_muto (atexit_lock); + atexit_lock->acquire (); + res = atexit (function); + atexit_lock->release (); + return res; +} + +extern "C" void +cygwin_exit (int n) +{ + if (atexit_lock) + atexit_lock->acquire (); + exit (n); +} + extern "C" void _exit (int n) { diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 3b26607c9f6..bd2b2af65d4 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -304,8 +304,16 @@ dll_list::load_after_fork (HANDLE parent, dll *first) the parent had some of those. */ if (d.type == DLL_LOAD) { + bool unload = true; HMODULE h = LoadLibraryEx (d.name, NULL, DONT_RESOLVE_DLL_REFERENCES); + if (!h) + { + unload = false; + LoadLibrary (d.name); + } + if (!h) + system_printf ("can't reload %s", d.name); /* See if DLL will load in proper place. If so, free it and reload it the right way. It sort of stinks that we can't invert the order of the FreeLibrary @@ -313,10 +321,13 @@ dll_list::load_after_fork (HANDLE parent, dll *first) should do what we want. However, since the library was loaded above, the second LoadLibrary does not execute it's startup code unless it is first unloaded. */ - if (h == d.handle) + else if (h == d.handle) { - FreeLibrary (h); - LoadLibrary (d.name); + if (unload) + { + FreeLibrary (h); + LoadLibrary (d.name); + } } else if (try2) api_fatal ("unable to remap %s to same address as parent(%p) != %p", diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index a01dbe5bf52..124d9330d03 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -90,6 +90,73 @@ get_inet_addr (const struct sockaddr *in, int inlen, } } +class sock_event +{ + WSAEVENT ev[2]; + SOCKET evt_sock; + int evt_type_bit; + +public: + sock_event () + { + ev[0] = WSA_INVALID_EVENT; + ev[1] = signal_arrived; + } + bool load (SOCKET sock, int type_bit) + { + if ((ev[0] = WSACreateEvent ()) == WSA_INVALID_EVENT) + return false; + evt_sock = sock; + evt_type_bit = type_bit; + if (WSAEventSelect (evt_sock, ev[0], 1 << evt_type_bit)) + { + WSACloseEvent (ev[0]); + ev[0] = WSA_INVALID_EVENT; + return false; + } + return true; + } + int wait () + { + WSANETWORKEVENTS sock_event; + int wait_result = WSAWaitForMultipleEvents (2, ev, FALSE, WSA_INFINITE, + FALSE); + if (wait_result == WSA_WAIT_EVENT_0) + WSAEnumNetworkEvents (evt_sock, ev[0], &sock_event); + + /* Cleanup, Revert to blocking. */ + WSAEventSelect (evt_sock, ev[0], 0); + WSACloseEvent (ev[0]); + unsigned long nonblocking = 0; + ioctlsocket (evt_sock, FIONBIO, &nonblocking); + + switch (wait_result) + { + case WSA_WAIT_EVENT_0: + if ((sock_event.lNetworkEvents & (1 << evt_type_bit)) + && sock_event.iErrorCode[evt_type_bit]) + { + WSASetLastError (sock_event.iErrorCode[evt_type_bit]); + set_winsock_errno (); + return -1; + } + break; + + case WSA_WAIT_EVENT_0 + 1: + debug_printf ("signal received"); + set_errno (EINTR); + return 1; + + case WSA_WAIT_FAILED: + default: + WSASetLastError (WSAEFAULT); + set_winsock_errno (); + return -1; + } + return 0; + } +}; + /**********************************************************************/ /* fhandler_socket */ @@ -409,6 +476,8 @@ out: int fhandler_socket::connect (const struct sockaddr *name, int namelen) { + sock_event evt; + BOOL interrupted = FALSE; int res = -1; BOOL secret_check_failed = FALSE; BOOL in_progress = FALSE; @@ -418,12 +487,36 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) if (!get_inet_addr (name, namelen, &sin, &namelen, secret)) return -1; + if (!is_nonblocking () && !is_connect_pending ()) + if (!evt.load (get_socket (), FD_CONNECT_BIT)) + { + set_winsock_errno (); + return -1; + } + res = ::connect (get_socket (), (sockaddr *) &sin, namelen); + + if (res && !is_nonblocking () && !is_connect_pending () && + WSAGetLastError () == WSAEWOULDBLOCK) + switch (evt.wait ()) + { + case 1: /* Signal */ + WSASetLastError (WSAEINPROGRESS); + interrupted = TRUE; + break; + case 0: + res = 0; + break; + default: + res = -1; + break; + } + if (res) { /* Special handling for connect to return the correct error code when called on a non-blocking socket. */ - if (is_nonblocking ()) + if (is_nonblocking () || is_connect_pending ()) { DWORD err = WSAGetLastError (); if (err == WSAEWOULDBLOCK || err == WSAEALREADY) @@ -471,6 +564,10 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) set_connect_state (CONNECT_PENDING); else set_connect_state (CONNECTED); + + if (interrupted) + set_errno (EINTR); + return res; } @@ -489,7 +586,6 @@ int fhandler_socket::accept (struct sockaddr *peer, int *len) { int res = -1; - WSAEVENT ev[2] = { WSA_INVALID_EVENT, signal_arrived }; BOOL secret_check_failed = FALSE; BOOL in_progress = FALSE; @@ -513,65 +609,31 @@ fhandler_socket::accept (struct sockaddr *peer, int *len) if (!is_nonblocking ()) { - ev[0] = WSACreateEvent (); - - if (ev[0] != WSA_INVALID_EVENT && - !WSAEventSelect (get_socket (), ev[0], FD_ACCEPT)) - { - WSANETWORKEVENTS sock_event; - int wait_result; - - wait_result = WSAWaitForMultipleEvents (2, ev, FALSE, WSA_INFINITE, - FALSE); - if (wait_result == WSA_WAIT_EVENT_0) - WSAEnumNetworkEvents (get_socket (), ev[0], &sock_event); - - /* Unset events for listening socket and - switch back to blocking mode */ - WSAEventSelect (get_socket (), ev[0], 0); - unsigned long nonblocking = 0; - ioctlsocket (get_socket (), FIONBIO, &nonblocking); - - switch (wait_result) - { - case WSA_WAIT_EVENT_0: - if (sock_event.lNetworkEvents & FD_ACCEPT) - { - if (sock_event.iErrorCode[FD_ACCEPT_BIT]) - { - WSASetLastError (sock_event.iErrorCode[FD_ACCEPT_BIT]); - set_winsock_errno (); - res = -1; - goto done; - } - } - /* else; : Should never happen since FD_ACCEPT is the only event - that has been selected */ - break; - case WSA_WAIT_EVENT_0 + 1: - debug_printf ("signal received during accept"); - set_errno (EINTR); - res = -1; - goto done; - case WSA_WAIT_FAILED: - default: /* Should never happen */ - WSASetLastError (WSAEFAULT); - set_winsock_errno (); - res = -1; - goto done; - } + sock_event evt; + if (!evt.load (get_socket (), FD_ACCEPT_BIT)) + { + set_winsock_errno (); + return -1; + } + switch (evt.wait ()) + { + case 1: /* Signal */ + return -1; + case 0: + break; + case -1: + return -1; } } res = ::accept (get_socket (), peer, len); - if ((SOCKET) res == (SOCKET) INVALID_SOCKET && - WSAGetLastError () == WSAEWOULDBLOCK) + if ((SOCKET) res == INVALID_SOCKET && WSAGetLastError () == WSAEWOULDBLOCK) in_progress = TRUE; if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM) { - if ((SOCKET) res != (SOCKET) INVALID_SOCKET || in_progress) + if ((SOCKET) res != INVALID_SOCKET || in_progress) { if (!create_secret_event ()) secret_check_failed = TRUE; @@ -580,7 +642,7 @@ fhandler_socket::accept (struct sockaddr *peer, int *len) } if (!secret_check_failed && - (SOCKET) res != (SOCKET) INVALID_SOCKET) + (SOCKET) res != INVALID_SOCKET) { if (!check_peer_secret_event ((struct sockaddr_in*) peer)) { @@ -592,15 +654,14 @@ fhandler_socket::accept (struct sockaddr *peer, int *len) if (secret_check_failed) { close_secret_event (); - if ((SOCKET) res != (SOCKET) INVALID_SOCKET) + if ((SOCKET) res != INVALID_SOCKET) closesocket (res); set_errno (ECONNABORTED); - res = -1; - goto done; + return -1; } } - if ((SOCKET) res == (SOCKET) INVALID_SOCKET) + if ((SOCKET) res == INVALID_SOCKET) set_winsock_errno (); else { @@ -624,10 +685,6 @@ fhandler_socket::accept (struct sockaddr *peer, int *len) } } -done: - if (ev[0] != WSA_INVALID_EVENT) - WSACloseEvent (ev[0]); - return res; } diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index c3ee2bcabbd..306f3197225 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -184,12 +184,14 @@ details. */ lrintf lround lroundf nearbyint nearbyintf remquo remquof round roundf scalbln scalblnf sincos sincosf tgamma tgammaf truncf + 76: mallinfo + 77: thread-safe exit/at_exit */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 75 +#define CYGWIN_VERSION_API_MINOR 77 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 1bde7086d58..b74cd165b2c 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -83,10 +83,11 @@ internal_getlogin (cygheap_user &user) if (gsid.getfromgr (internal_getgrgid (pw->pw_gid))) { /* Set primary group to the group in /etc/passwd. */ - user.groups.pgsid = gsid; if (!SetTokenInformation (ptok, TokenPrimaryGroup, &gsid, sizeof gsid)) debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E"); + else + user.groups.pgsid = gsid; } else debug_printf ("gsid not found in augmented /etc/group"); |