summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <cgf@redhat.com>2003-03-01 02:05:41 +0000
committerChristopher Faylor <cgf@redhat.com>2003-03-01 02:05:41 +0000
commitae892ce74b257cfa5ec50a0a6b263f5f9be28510 (patch)
tree918c0cbfc507a46190842c60d63b422f89339ad1
parent8762951e1db488d9f84e67e1007f0d54a675f70e (diff)
downloadgdb-ae892ce74b257cfa5ec50a0a6b263f5f9be28510.tar.gz
merge from trunk
-rw-r--r--winsup/cygwin/ChangeLog35
-rw-r--r--winsup/cygwin/cygwin.din6
-rw-r--r--winsup/cygwin/dcrt0.cc23
-rw-r--r--winsup/cygwin/dll_init.cc17
-rw-r--r--winsup/cygwin/fhandler_socket.cc179
-rw-r--r--winsup/cygwin/include/cygwin/version.h4
-rw-r--r--winsup/cygwin/uinfo.cc3
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");