summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2010-07-02 14:36:43 +0000
committerCorinna Vinschen <corinna@vinschen.de>2010-07-02 14:36:43 +0000
commit7ba0a42f557f68deea9c1b612afc4c74dd55a521 (patch)
treee7a746aa06aeb5ab35d5b9b03b54c273fba8adf4
parentae96209cbbad66d908ac79bcfb3565f04bb14d34 (diff)
downloadcygnal-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/ChangeLog6
-rw-r--r--winsup/cygwin/net.cc30
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;