diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2010-07-02 14:36:43 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2010-07-02 14:36:43 +0000 |
commit | 7ba0a42f557f68deea9c1b612afc4c74dd55a521 (patch) | |
tree | e7a746aa06aeb5ab35d5b9b03b54c273fba8adf4 | |
parent | ae96209cbbad66d908ac79bcfb3565f04bb14d34 (diff) | |
download | cygnal-7ba0a42f557f68deea9c1b612afc4c74dd55a521.tar.gz cygnal-7ba0a42f557f68deea9c1b612afc4c74dd55a521.tar.bz2 cygnal-7ba0a42f557f68deea9c1b612afc4c74dd55a521.zip |
* net.cc (cygwin_getsockopt): Make sure SO_PEERCRED is only handled
in level SOL_SOCKET. Workaround a return value regression in Vista
and later. Add comment to explain.
-rw-r--r-- | winsup/cygwin/ChangeLog | 6 | ||||
-rw-r--r-- | winsup/cygwin/net.cc | 30 |
2 files changed, 35 insertions, 1 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index f7d5202fa..cc7e9b3ee 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2010-07-02 Corinna Vinschen <corinna@vinschen.de> + + * net.cc (cygwin_getsockopt): Make sure SO_PEERCRED is only handled + in level SOL_SOCKET. Workaround a return value regression in Vista + and later. Add comment to explain. + 2010-06-29 Corinna Vinschen <corinna@vinschen.de> * spawn.cc (spawn_guts): Reinstantiate a FIXME comment. diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 8a1d390dc..c0151e5b6 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -787,7 +787,7 @@ cygwin_getsockopt (int fd, int level, int optname, void *optval, myfault efault; if (efault.faulted (EFAULT) || !fh) res = -1; - else if (optname == SO_PEERCRED) + else if (optname == SO_PEERCRED && level == SOL_SOCKET) { struct ucred *cred = (struct ucred *) optval; res = fh->getpeereid (&cred->pid, &cred->uid, &cred->gid); @@ -800,6 +800,34 @@ cygwin_getsockopt (int fd, int level, int optname, void *optval, res = getsockopt (fh->get_socket (), level, optname, (char *) optval, (int *) optlen); + if (level == SOL_SOCKET) + { + switch (optname) + { + case SO_ERROR: + { + int *e = (int *) optval; + debug_printf ("WinSock SO_ERROR = %d", *e); + *e = find_winsock_errno (*e); + } + break; + case SO_KEEPALIVE: + case SO_DONTROUTE: + /* Regression in Vista and later: instead of a 4 byte BOOL + value, a 1 byte BOOLEAN value is returned, in contrast + to older systems and the documentation. Since an int + type is expected by the calling application, we convert + the result here. */ + if (*optlen == 1) + { + BOOLEAN *in = (BOOLEAN *) optval; + int *out = (int *) optval; + *out = *in; + *optlen = 4; + } + break; + } + } if (optname == SO_ERROR) { int *e = (int *) optval; |