Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2010-07-02 18:36:43 +0400
committerCorinna Vinschen <corinna@vinschen.de>2010-07-02 18:36:43 +0400
commit7ba0a42f557f68deea9c1b612afc4c74dd55a521 (patch)
treee7a746aa06aeb5ab35d5b9b03b54c273fba8adf4 /winsup/cygwin/net.cc
parentae96209cbbad66d908ac79bcfb3565f04bb14d34 (diff)
* 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.
Diffstat (limited to 'winsup/cygwin/net.cc')
-rw-r--r--winsup/cygwin/net.cc30
1 files changed, 29 insertions, 1 deletions
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;