diff options
Diffstat (limited to 'winsup/cygwin')
-rw-r--r-- | winsup/cygwin/ChangeLog | 70 | ||||
-rw-r--r-- | winsup/cygwin/assert.cc | 55 | ||||
-rw-r--r-- | winsup/cygwin/cygthread.cc | 9 | ||||
-rw-r--r-- | winsup/cygwin/dcrt0.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/environ.cc | 3 | ||||
-rw-r--r-- | winsup/cygwin/exceptions.cc | 15 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_socket.cc | 89 | ||||
-rw-r--r-- | winsup/cygwin/fork.cc | 3 | ||||
-rw-r--r-- | winsup/cygwin/miscfuncs.cc | 8 | ||||
-rw-r--r-- | winsup/cygwin/net.cc | 327 | ||||
-rw-r--r-- | winsup/cygwin/resource.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/sec_helper.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.cc | 25 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.h | 1 | ||||
-rw-r--r-- | winsup/cygwin/winsup.h | 4 |
16 files changed, 335 insertions, 283 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 3a4487f2328..0b4ed5b5f01 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,73 @@ +2002-08-11 Conrad Scott <conrad.scott@dsl.pipex.com> + + * fhandler.h (fhandler_socket::recv): Remove method. + (fhandler_socket::send): Ditto. + * fhandler_socket.cc (fhandler_socket::recv): Ditto. + (fhandler_socket::send): Ditto. + (fhandler_socket::read): Delegate to fhandler_socket::recvfrom. + (fhandler_socket::write): Delegate to fhandler_socket::sendto. + (fhandler_socket::sendto): Check for null `to' address. + * net.cc (cygwin_sendto): Check for zero request length. + (cygwin_recvfrom): Ditto. Fix signature, use void *buf. + (cygwin_recv): Delegate to cygwin_recvfrom. + (cygwin_send): Delegate to cygwin_sendto. + +2002-08-11 Christopher Faylor <cgf@redhat.com> + + * cygthread.cc (cygthread::cygthread): Close another race. + +2002-08-11 Christopher Faylor <cgf@redhat.com> + + * assert.cc (__assert): Call debugger on assertion failure if + debugging. + * dcrt0.cc (dll_crt0_1): Just wait for signal thread to go live rather + than going through the overhead of invoking it. + * fork.cc (fork_child): Ditto. + * exceptions.cc (signal_fixup_after_fork): Call sigproc_init here. + * sigproc.cc (proc_can_be_signalled): Assume that the signal thread is + live. + (sig_dispatch): Ditto. + (sig_send): Ditto. + (wait_for_sigthread): Renamed from "wait_for_me". Assume that + wait_sig_inited has been set and that this function is only called from + the main thread. + * winsup.h (wait_for_sigthread): Declare new function. + +2002-08-08 Christopher Faylor <cgf@redhat.com> + + * environ.cc (parse_options): Remember the "no" part of any options for + later export. + +2002-08-07 Conrad Scott <conrad.scott@dsl.pipex.com> + + * winsup.h (__check_null_invalid_struct): Make ptr argument non-const. + (__check_null_invalid_struct_errno): Ditto. + * miscfuncs.cc (__check_null_invalid_struct): Ditto. + (__check_null_invalid_struct_errno): Ditto. + (__check_invalid_read_ptr_errno): Remove superfluous cast. + * net.cc (get): Set appropriate errno if fd is not a socket. + (cygwin_sendto): Fix parameter checking. + (cygwin_recvfrom): Ditto. + (cygwin_setsockopt): Ditto. + (cygwin_getsockopt): Ditto. + (cygwin_connect): Ditto. + (cygwin_gethostbyaddr): Ditto. + (cygwin_accept): Ditto. + (cygwin_bind): Ditto. + (cygwin_getsockname): Ditto. + (cygwin_listen): Ditto. + (cygwin_getpeername): Ditto. + (cygwin_send): Ditto. + (cygwin_shutdown): Ditto. Move sigframe to fhandler_socket. + (cygwin_recvmsg): Fix parameter checking. Add tracing. + (cygwin_sendmsg): Ditto. + * fhandler_socket.cc (fhandler_socket::shutdown): Add sigframe. + * resource.cc (setrlimit): Fix parameter checking. + +2002-08-08 Joe Buehler <jbuehler@hekimian.com + + * sec_helper.cc (sec_acl): remove extraneous arg to debug_printf. + 2002-08-07 Conrad Scott <conrad.scott@dsl.pipex.com> * fhandler_socket.cc (fhandler_socket::accept): Fix FIONBIO call. diff --git a/winsup/cygwin/assert.cc b/winsup/cygwin/assert.cc new file mode 100644 index 00000000000..fbce8753e8c --- /dev/null +++ b/winsup/cygwin/assert.cc @@ -0,0 +1,55 @@ +/* assert.cc: Handle the assert macro for WIN32. + + Copyright 1997, 1998, 2000, 2001 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. */ + +#include "winsup.h" +#include "security.h" +#include <wingdi.h> +#include <winuser.h> + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> + +/* This function is called when the assert macro fails. This will + override the function of the same name in newlib. */ + +extern "C" void +__assert (const char *file, int line, const char *failedexpr) +{ + HANDLE h; + + /* If we don't have a console in a Windows program, then bring up a + message box for the assertion failure. */ + + h = CreateFileA ("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, &sec_none_nih, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (h == INVALID_HANDLE_VALUE || h == 0) + { + char *buf; + + buf = (char *) alloca (100 + strlen (failedexpr)); + __small_sprintf (buf, "Failed assertion\n\t%s\nat line %d of file %s", + failedexpr, line, file); + MessageBox (NULL, buf, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL); + } + else + { + CloseHandle (h); + small_printf ("assertion \"%s\" failed: file \"%s\", line %d\n", + failedexpr, file, line); + } + +#ifdef DEBUGGING + try_to_debug (); +#endif + abort (); // FIXME: Someday this should work. + + /* NOTREACHED */ +} diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index 00eeb25d07a..d1d93375c74 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -123,8 +123,15 @@ cygthread::cygthread (LPTHREAD_START_ROUTINE start, LPVOID param, api_fatal ("name should never be NULL"); #endif thread_printf ("name %s, id %p", name, id); - while (ResumeThread (h) == 0) + while (!h || ResumeThread (h) != 1) +#ifndef DEBUGGING Sleep (0); +#else + { + thread_printf ("waiting for %s<%p> to become active", __name, h); + Sleep (0); + } +#endif __name = name; /* Need to set after thread has woken up to ensure that it won't be cleared by exiting thread. */ diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 14426f8a131..2d10a021318 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -770,7 +770,7 @@ dll_crt0_1 () /* Flush signals and ensure that signal thread is up and running. Can't do this for noncygwin case since the signal thread is blocked due to LoadLibrary serialization. */ - sig_send (NULL, __SIGFLUSH); + wait_for_sigthread (); set_errno (0); diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 04436edc112..a38fc46ad69 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -559,6 +559,7 @@ parse_options (char *buf) p != NULL; p = strtok_r (NULL, " \t", &lasts)) { + char *keyword_here = p; if (!(istrue = !strncasematch (p, "no", 2))) p += 2; else if (!(istrue = *p != '-')) @@ -602,7 +603,7 @@ parse_options (char *buf) *--eq = ch; int n = eq - p; - p = strdup (p); + p = strdup (keyword_here); if (n > 0) p[n] = ':'; k->remember = p; diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index f907b21a460..9e2e631ecc4 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -715,15 +715,16 @@ interrupt_now (CONTEXT *ctx, int sig, void *handler, struct sigaction& siga) void __stdcall signal_fixup_after_fork () { - if (!sigsave.sig) - return; - - sigsave.sig = 0; - if (sigsave.retaddr_on_stack) + if (sigsave.sig) { - *sigsave.retaddr_on_stack = sigsave.retaddr; - set_process_mask (sigsave.oldmask); + sigsave.sig = 0; + if (sigsave.retaddr_on_stack) + { + *sigsave.retaddr_on_stack = sigsave.retaddr; + set_process_mask (sigsave.oldmask); + } } + sigproc_init (); } void __stdcall diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index a338987d4f3..6237c6ca9c9 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -397,15 +397,12 @@ class fhandler_socket: public fhandler_base int getsockname (struct sockaddr *name, int *namelen); int getpeername (struct sockaddr *name, int *namelen); - int recv (void *ptr, size_t len, unsigned int flags); int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); int recvfrom (void *ptr, size_t len, unsigned int flags, struct sockaddr *from, int *fromlen); int recvmsg (struct msghdr *msg, int flags); - int send (const void *ptr, size_t len, unsigned int flags); int write (const void *ptr, size_t len); - int sendto (const void *ptr, size_t len, unsigned int flags, const struct sockaddr *to, int tolen); int sendmsg (const struct msghdr *msg, int flags); diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 01a9f738e8a..c938773185b 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -668,47 +668,10 @@ fhandler_socket::getpeername (struct sockaddr *name, int *namelen) return res; } -int -fhandler_socket::recv (void *ptr, size_t len, unsigned int flags) -{ - int res = -1; - wsock_event wsock_evt; - LPWSAOVERLAPPED ovr; - - sigframe thisframe (mainthread); - - if (is_nonblocking () || !(ovr = wsock_evt.prepare ())) - { - debug_printf ("Fallback to winsock 1 recv call"); - if ((res = ::recv (get_socket (), (char *) ptr, len, flags)) - == SOCKET_ERROR) - { - set_winsock_errno (); - res = -1; - } - } - else - { - WSABUF wsabuf = { len, (char *) ptr }; - DWORD ret = 0; - if (WSARecv (get_socket (), &wsabuf, 1, &ret, (DWORD *)&flags, - ovr, NULL) != SOCKET_ERROR) - res = ret; - else if ((res = WSAGetLastError ()) != WSA_IO_PENDING) - { - set_winsock_errno (); - res = -1; - } - else if ((res = wsock_evt.wait (get_socket (), (DWORD *)&flags)) == -1) - set_winsock_errno (); - } - return res; -} - int __stdcall fhandler_socket::read (void *ptr, size_t len) { - return recv (ptr, len, 0); + return recvfrom (ptr, len, 0, NULL, NULL); } int @@ -794,46 +757,9 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags) } int -fhandler_socket::send (const void *ptr, size_t len, unsigned int flags) -{ - int res = -1; - wsock_event wsock_evt; - LPWSAOVERLAPPED ovr; - - sigframe thisframe (mainthread); - - if (is_nonblocking () || !(ovr = wsock_evt.prepare ())) - { - debug_printf ("Fallback to winsock 1 send call"); - if ((res = ::send (get_socket (), (const char *) ptr, len, flags)) - == SOCKET_ERROR) - { - set_winsock_errno (); - res = -1; - } - } - else - { - WSABUF wsabuf = { len, (char *) ptr }; - DWORD ret = 0; - if (WSASend (get_socket (), &wsabuf, 1, &ret, (DWORD)flags, - ovr, NULL) != SOCKET_ERROR) - res = ret; - else if ((res = WSAGetLastError ()) != WSA_IO_PENDING) - { - set_winsock_errno (); - res = -1; - } - else if ((res = wsock_evt.wait (get_socket (), (DWORD *)&flags)) == -1) - set_winsock_errno (); - } - return res; -} - -int fhandler_socket::write (const void *ptr, size_t len) { - return send (ptr, len, 0); + return sendto (ptr, len, 0, NULL, 0); } int @@ -847,14 +773,15 @@ fhandler_socket::sendto (const void *ptr, size_t len, unsigned int flags, sigframe thisframe (mainthread); - if (!get_inet_addr (to, tolen, &sin, &tolen)) + if (to && !get_inet_addr (to, tolen, &sin, &tolen)) return -1; if (is_nonblocking () || !(ovr = wsock_evt.prepare ())) { debug_printf ("Fallback to winsock 1 sendto call"); if ((res = ::sendto (get_socket (), (const char *) ptr, len, flags, - (sockaddr *) &sin, tolen)) == SOCKET_ERROR) + (to ? (sockaddr *) &sin : NULL), + tolen)) == SOCKET_ERROR) { set_winsock_errno (); res = -1; @@ -865,7 +792,9 @@ fhandler_socket::sendto (const void *ptr, size_t len, unsigned int flags, WSABUF wsabuf = { len, (char *) ptr }; DWORD ret = 0; if (WSASendTo (get_socket (), &wsabuf, 1, &ret, (DWORD)flags, - (sockaddr *) &sin, tolen, ovr, NULL) != SOCKET_ERROR) + (to ? (sockaddr *) &sin : NULL), + tolen, + ovr, NULL) != SOCKET_ERROR) res = ret; else if ((res = WSAGetLastError ()) != WSA_IO_PENDING) { @@ -915,6 +844,8 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags) int fhandler_socket::shutdown (int how) { + sigframe thisframe (mainthread); + int res = ::shutdown (get_socket (), how); if (res) diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 7486da09890..d1b7fa9a71d 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -313,8 +313,7 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls) user_data->threadinterface->fixup_after_fork (); - /* Initialize signal/process handling */ - sigproc_init (); + wait_for_sigthread (); __pthread_atforkchild (); cygbench ("fork-child"); return 0; diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index 6fd9ffc9183..0849da51c97 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -154,16 +154,16 @@ check_null_str_errno (const char *name) } int __stdcall -__check_null_invalid_struct (const void *s, unsigned sz) +__check_null_invalid_struct (void *s, unsigned sz) { - if (s && !IsBadWritePtr ((void *) s, sz)) + if (s && !IsBadWritePtr (s, sz)) return 0; return EFAULT; } int __stdcall -__check_null_invalid_struct_errno (const void *s, unsigned sz) +__check_null_invalid_struct_errno (void *s, unsigned sz) { int err; if ((err = __check_null_invalid_struct (s, sz))) @@ -174,7 +174,7 @@ __check_null_invalid_struct_errno (const void *s, unsigned sz) int __stdcall __check_invalid_read_ptr_errno (const void *s, unsigned sz) { - if (s && !IsBadReadPtr ((void *) s, sz)) + if (s && !IsBadReadPtr (s, sz)) return 0; return set_errno (EFAULT); } diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index f6a403fc357..00fea193c9d 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -101,13 +101,17 @@ WSADATA wsadata; /* Cygwin internal */ static fhandler_socket * -get (int fd) +get (const int fd) { cygheap_fdget cfd (fd); if (cfd < 0) return 0; - return cfd->is_socket (); + fhandler_socket *const fh = cfd->is_socket (); + if (!fh) + set_errno (ENOTSOCK); + + return fh; } /* Cygwin internal */ @@ -567,10 +571,10 @@ cygwin_sendto (int fd, const void *buf, int len, unsigned int flags, fhandler_socket *fh = get (fd); if ((len && __check_invalid_read_ptr_errno (buf, (unsigned) len)) - || __check_null_invalid_struct_errno (to, tolen) + || (to &&__check_invalid_read_ptr_errno (to, tolen)) || !fh) res = -1; - else + else if ((res = len) != 0) res = fh->sendto (buf, len, flags, to, tolen); syscall_printf ("%d = sendto (%d, %x, %x, %x)", res, fd, buf, len, flags); @@ -580,18 +584,19 @@ cygwin_sendto (int fd, const void *buf, int len, unsigned int flags, /* exported as recvfrom: standards? */ extern "C" int -cygwin_recvfrom (int fd, char *buf, int len, int flags, struct sockaddr *from, +cygwin_recvfrom (int fd, void *buf, int len, int flags, struct sockaddr *from, int *fromlen) { int res; fhandler_socket *fh = get (fd); - if (__check_null_invalid_struct_errno (buf, (unsigned) len) - || check_null_invalid_struct_errno (fromlen) - || (from && __check_null_invalid_struct_errno (from, (unsigned) *fromlen)) + if ((len && __check_null_invalid_struct_errno (buf, (unsigned) len)) + || (from + && (check_null_invalid_struct_errno (fromlen) + ||__check_null_invalid_struct_errno (from, (unsigned) *fromlen))) || !fh) res = -1; - else + else if ((res = len) != 0) res = fh->recvfrom (buf, len, flags, from, fromlen); syscall_printf ("%d = recvfrom (%d, %x, %x, %x)", res, fd, buf, len, flags); @@ -604,47 +609,49 @@ extern "C" int cygwin_setsockopt (int fd, int level, int optname, const void *optval, int optlen) { + int res; fhandler_socket *fh = get (fd); - int res = -1; const char *name = "error"; - if ((!optval || !__check_invalid_read_ptr_errno (optval, optlen)) && fh) + /* For the following debug_printf */ + switch (optname) { - /* For the following debug_printf */ - switch (optname) - { - case SO_DEBUG: - name="SO_DEBUG"; - break; - case SO_ACCEPTCONN: - name="SO_ACCEPTCONN"; - break; - case SO_REUSEADDR: - name="SO_REUSEADDR"; - break; - case SO_KEEPALIVE: - name="SO_KEEPALIVE"; - break; - case SO_DONTROUTE: - name="SO_DONTROUTE"; - break; - case SO_BROADCAST: - name="SO_BROADCAST"; - break; - case SO_USELOOPBACK: - name="SO_USELOOPBACK"; - break; - case SO_LINGER: - name="SO_LINGER"; - break; - case SO_OOBINLINE: - name="SO_OOBINLINE"; - break; - case SO_ERROR: - name="SO_ERROR"; - break; - } + case SO_DEBUG: + name="SO_DEBUG"; + break; + case SO_ACCEPTCONN: + name="SO_ACCEPTCONN"; + break; + case SO_REUSEADDR: + name="SO_REUSEADDR"; + break; + case SO_KEEPALIVE: + name="SO_KEEPALIVE"; + break; + case SO_DONTROUTE: + name="SO_DONTROUTE"; + break; + case SO_BROADCAST: + name="SO_BROADCAST"; + break; + case SO_USELOOPBACK: + name="SO_USELOOPBACK"; + break; + case SO_LINGER: + name="SO_LINGER"; + break; + case SO_OOBINLINE: + name="SO_OOBINLINE"; + break; + case SO_ERROR: + name="SO_ERROR"; + break; + } + if ((optval && __check_invalid_read_ptr_errno (optval, optlen)) || !fh) + res = -1; + else + { res = setsockopt (fh->get_socket (), level, optname, (const char *) optval, optlen); @@ -664,49 +671,52 @@ cygwin_setsockopt (int fd, int level, int optname, const void *optval, extern "C" int cygwin_getsockopt (int fd, int level, int optname, void *optval, int *optlen) { + int res; fhandler_socket *fh = get (fd); - int res = -1; const char *name = "error"; - if (!check_null_invalid_struct_errno (optlen) - && (!optval - || !__check_null_invalid_struct_errno (optval, (unsigned) *optlen)) - && fh) + + /* For the following debug_printf */ + switch (optname) { - /* For the following debug_printf */ - switch (optname) - { - case SO_DEBUG: - name="SO_DEBUG"; - break; - case SO_ACCEPTCONN: - name="SO_ACCEPTCONN"; - break; - case SO_REUSEADDR: - name="SO_REUSEADDR"; - break; - case SO_KEEPALIVE: - name="SO_KEEPALIVE"; - break; - case SO_DONTROUTE: - name="SO_DONTROUTE"; - break; - case SO_BROADCAST: - name="SO_BROADCAST"; - break; - case SO_USELOOPBACK: - name="SO_USELOOPBACK"; - break; - case SO_LINGER: - name="SO_LINGER"; - break; - case SO_OOBINLINE: - name="SO_OOBINLINE"; - break; - case SO_ERROR: - name="SO_ERROR"; - break; - } + case SO_DEBUG: + name="SO_DEBUG"; + break; + case SO_ACCEPTCONN: + name="SO_ACCEPTCONN"; + break; + case SO_REUSEADDR: + name="SO_REUSEADDR"; + break; + case SO_KEEPALIVE: + name="SO_KEEPALIVE"; + break; + case SO_DONTROUTE: + name="SO_DONTROUTE"; + break; + case SO_BROADCAST: + name="SO_BROADCAST"; + break; + case SO_USELOOPBACK: + name="SO_USELOOPBACK"; + break; + case SO_LINGER: + name="SO_LINGER"; + break; + case SO_OOBINLINE: + name="SO_OOBINLINE"; + break; + case SO_ERROR: + name="SO_ERROR"; + break; + } + if ((optval + && (check_null_invalid_struct_errno (optlen) + || __check_null_invalid_struct_errno (optval, (unsigned) *optlen))) + || !fh) + res = -1; + else + { res = getsockopt (fh->get_socket (), level, optname, (char *) optval, (int *) optlen); @@ -732,10 +742,7 @@ cygwin_connect (int fd, const struct sockaddr *name, int namelen) int res; fhandler_socket *fh = get (fd); - if (__check_invalid_read_ptr_errno (name, namelen)) - return -1; - - if (!fh) + if (__check_invalid_read_ptr_errno (name, namelen) || !fh) res = -1; else res = fh->connect (name, namelen); @@ -970,7 +977,7 @@ cygwin_gethostbyname (const char *name) extern "C" struct hostent * cygwin_gethostbyaddr (const char *addr, int len, int type) { - if (__check_null_invalid_struct_errno (addr, len)) + if (__check_invalid_read_ptr_errno (addr, len)) return NULL; free_hostent_ptr (hostent_buf); @@ -992,15 +999,14 @@ cygwin_gethostbyaddr (const char *addr, int len, int type) extern "C" int cygwin_accept (int fd, struct sockaddr *peer, int *len) { - if (peer != NULL - && (check_null_invalid_struct_errno (len) - || __check_null_invalid_struct_errno (peer, (unsigned) *len))) - return -1; - - int res = -1; - + int res; fhandler_socket *fh = get (fd); - if (fh) + + if ((peer && (check_null_invalid_struct_errno (len) + || __check_null_invalid_struct_errno (peer, (unsigned) *len))) + || !fh) + res = -1; + else res = fh->accept (peer, len); syscall_printf ("%d = accept (%d, %x, %x)", res, fd, peer, len); @@ -1011,13 +1017,12 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len) extern "C" int cygwin_bind (int fd, const struct sockaddr *my_addr, int addrlen) { - if (__check_null_invalid_struct_errno (my_addr, addrlen)) - return -1; - - int res = -1; - + int res; fhandler_socket *fh = get (fd); - if (fh) + + if (__check_invalid_read_ptr_errno (my_addr, addrlen) || !fh) + res = -1; + else res = fh->bind (my_addr, addrlen); syscall_printf ("%d = bind (%d, %x, %d)", res, fd, my_addr, addrlen); @@ -1028,14 +1033,14 @@ cygwin_bind (int fd, const struct sockaddr *my_addr, int addrlen) extern "C" int cygwin_getsockname (int fd, struct sockaddr *addr, int *namelen) { - if (check_null_invalid_struct_errno (namelen) - || __check_null_invalid_struct_errno (addr, (unsigned) *namelen)) - return -1; - - int res = -1; - + int res; fhandler_socket *fh = get (fd); - if (fh) + + if (check_null_invalid_struct_errno (namelen) + || __check_null_invalid_struct_errno (addr, (unsigned) *namelen) + || !fh) + res = -1; + else res = fh->getsockname (addr, namelen); syscall_printf ("%d = getsockname (%d, %x, %d)", res, fd, addr, namelen); @@ -1046,10 +1051,12 @@ cygwin_getsockname (int fd, struct sockaddr *addr, int *namelen) extern "C" int cygwin_listen (int fd, int backlog) { - int res = -1; - + int res; fhandler_socket *fh = get (fd); - if (fh) + + if (!fh) + res = -1; + else res = fh->listen (backlog); syscall_printf ("%d = listen (%d, %d)", res, fd, backlog); @@ -1060,11 +1067,12 @@ cygwin_listen (int fd, int backlog) extern "C" int cygwin_shutdown (int fd, int how) { - int res = -1; - sigframe thisframe (mainthread); - + int res; fhandler_socket *fh = get (fd); - if (fh) + + if (!fh) + res = -1; + else res = fh->shutdown (how); syscall_printf ("%d = shutdown (%d, %d)", res, fd, how); @@ -1122,18 +1130,17 @@ cygwin_herror (const char *s) extern "C" int cygwin_getpeername (int fd, struct sockaddr *name, int *len) { - int res = -1; + int res; + fhandler_socket *fh = get (fd); if (check_null_invalid_struct_errno (len) - || __check_null_invalid_struct_errno (name, (unsigned) *len)) - return -1; - - fhandler_socket *fh = get (fd); - if (fh) + || __check_null_invalid_struct_errno (name, (unsigned) *len) + || !fh) + res = -1; + else res = fh->getpeername (name, len); syscall_printf ("%d = getpeername %d", res, (fh ? fh->get_socket () : -1)); - return res; } @@ -1141,34 +1148,14 @@ cygwin_getpeername (int fd, struct sockaddr *name, int *len) extern "C" int cygwin_recv (int fd, void *buf, int len, unsigned int flags) { - int res; - fhandler_socket *fh = get (fd); - - if (__check_null_invalid_struct_errno (buf, len) || !fh) - res = -1; - else - res = fh->recv (buf, len, flags); - - syscall_printf ("%d = recv (%d, %x, %x, %x)", res, fd, buf, len, flags); - - return res; + return cygwin_recvfrom (fd, buf, len, flags, NULL, NULL); } /* exported as send: standards? */ extern "C" int cygwin_send (int fd, const void *buf, int len, unsigned int flags) { - int res; - fhandler_socket *fh = get (fd); - - if (__check_invalid_read_ptr_errno (buf, len) || !fh) - res = -1; - else - res = fh->send (buf, len, flags); - - syscall_printf ("%d = send (%d, %x, %d, %x)", res, fd, buf, len, flags); - - return res; + return cygwin_sendto (fd, buf, len, flags, NULL, 0); } /* getdomainname: standards? */ @@ -2095,32 +2082,40 @@ endhostent (void) /* exported as recvmsg: standards? */ extern "C" int -cygwin_recvmsg (int s, struct msghdr *msg, int flags) +cygwin_recvmsg (int fd, struct msghdr *msg, int flags) { - if (check_null_invalid_struct_errno (msg)) - return -1; + int res; + fhandler_socket *fh = get (fd); - fhandler_socket *fh = get (s); - if (!fh) - { - set_errno (EINVAL); - return -1; - } - return fh->recvmsg (msg, flags); + if (check_null_invalid_struct_errno (msg) + || (msg->msg_name + && __check_null_invalid_struct_errno (msg->msg_name, + (unsigned) msg->msg_namelen)) + || !fh) + res = -1; + else + res = fh->recvmsg (msg, flags); + + syscall_printf ("%d = recvmsg (%d, %x, %x)", res, fd, msg, flags); + return res; } /* exported as sendmsg: standards? */ extern "C" int -cygwin_sendmsg (int s, const struct msghdr *msg, int flags) +cygwin_sendmsg (int fd, const struct msghdr *msg, int flags) { - if (__check_invalid_read_ptr_errno (msg, sizeof msg)) - return -1; + int res; + fhandler_socket *fh = get (fd); - fhandler_socket *fh = get (s); - if (!fh) - { - set_errno (EINVAL); - return -1; - } - return fh->sendmsg (msg, flags); + if (__check_invalid_read_ptr_errno (msg, sizeof msg) + || (msg->msg_name + && __check_invalid_read_ptr_errno (msg->msg_name, + (unsigned) msg->msg_namelen)) + || !fh) + res = -1; + else + res = fh->sendmsg (msg, flags); + + syscall_printf ("%d = recvmsg (%d, %x, %x)", res, fd, msg, flags); + return res; } diff --git a/winsup/cygwin/resource.cc b/winsup/cygwin/resource.cc index 8d988715842..cd2962d5696 100644 --- a/winsup/cygwin/resource.cc +++ b/winsup/cygwin/resource.cc @@ -157,7 +157,7 @@ getrlimit (int resource, struct rlimit *rlp) extern "C" int setrlimit (int resource, const struct rlimit *rlp) { - if (check_null_invalid_struct_errno (rlp)) + if (__check_invalid_read_ptr_errno (rlp, sizeof (*rlp))) return -1; struct rlimit oldlimits; diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc index e7377b617bd..6cc6f132cff 100644 --- a/winsup/cygwin/sec_helper.cc +++ b/winsup/cygwin/sec_helper.cc @@ -432,7 +432,7 @@ sec_acl (PACL acl, BOOL admins, PSID sid1, PSID sid2) if (sid1) if (!AddAccessAllowedAce (acl, ACL_REVISION, GENERIC_ALL, sid1)) - debug_printf ("AddAccessAllowedAce(sid1) %E", sid1); + debug_printf ("AddAccessAllowedAce(sid1) %E"); if (admins) if (!AddAccessAllowedAce (acl, ACL_REVISION, GENERIC_ALL, well_known_admins_sid)) diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 4914e6a24e3..49c8bda572e 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -17,6 +17,7 @@ details. */ #include <errno.h> #include <stdlib.h> #include <sys/cygwin.h> +#include <assert.h> #include "cygerrno.h" #include "sync.h" #include "sigproc.h" @@ -167,19 +168,13 @@ out: return res; } -__inline static void -wait_for_me () +void __stdcall +wait_for_sigthread () { - /* See if this is the first signal call after initialization. - * If so, wait for notification that all initialization has completed. - * Then set the handle to NULL to avoid checking this again. - */ - if (wait_sig_inited) - { - (void) WaitForSingleObject (wait_sig_inited, INFINITE); - (void) ForceCloseHandle (wait_sig_inited); - wait_sig_inited = NULL; - } + assert (wait_sig_inited); + (void) WaitForSingleObject (wait_sig_inited, INFINITE); + (void) ForceCloseHandle (wait_sig_inited); + wait_sig_inited = NULL; } /* Get the sync_proc_subproc muto to control access to @@ -210,7 +205,7 @@ proc_can_be_signalled (_pinfo *p) { if (p == myself_nowait || p == myself_nowait_nonmain || p == myself) { - wait_for_me (); + assert (!wait_sig_inited); return 1; } @@ -535,7 +530,7 @@ sig_dispatch_pending (int justwake) #endif else { - wait_for_me (); + assert (!wait_sig_inited); if (!justwake) (void) sig_send (myself, __SIGFLUSH); else if (ReleaseSemaphore (sigcatch_nosync, 1, NULL)) @@ -657,7 +652,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception) { if (no_signals_available ()) goto out; // Either exiting or not yet initializing - wait_for_me (); + assert (!wait_sig_inited); wait_for_completion = p != myself_nowait; p = myself; } diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index 0960efae28c..36babecff77 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -118,6 +118,7 @@ int __stdcall sig_send (_pinfo *, int, DWORD ebp = (DWORD) __builtin_frame_addre bool exception = 0) __attribute__ ((regparm(3))); void __stdcall signal_fixup_after_fork (); void __stdcall signal_fixup_after_exec (bool); +void __stdcall wait_for_sigthread (); extern char myself_nowait_dummy[]; extern char myself_nowait_nonmain_dummy[]; diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 513d448631c..433fc9944f4 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -212,8 +212,8 @@ int __stdcall check_null_str (const char *name) __attribute__ ((regparm(1))); int __stdcall check_null_empty_str (const char *name) __attribute__ ((regparm(1))); int __stdcall check_null_empty_str_errno (const char *name) __attribute__ ((regparm(1))); int __stdcall check_null_str_errno (const char *name) __attribute__ ((regparm(1))); -int __stdcall __check_null_invalid_struct (const void *s, unsigned sz) __attribute__ ((regparm(2))); -int __stdcall __check_null_invalid_struct_errno (const void *s, unsigned sz) __attribute__ ((regparm(2))); +int __stdcall __check_null_invalid_struct (void *s, unsigned sz) __attribute__ ((regparm(2))); +int __stdcall __check_null_invalid_struct_errno (void *s, unsigned sz) __attribute__ ((regparm(2))); int __stdcall __check_invalid_read_ptr_errno (const void *s, unsigned sz) __attribute__ ((regparm(2))); #define check_null_invalid_struct(s) \ |