* 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.
This commit is contained in:
Corinna Vinschen 2010-07-02 14:36:43 +00:00
parent ae96209cbb
commit 7ba0a42f55
2 changed files with 35 additions and 1 deletions

View File

@ -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.

View File

@ -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;