Index: Lib/socket.py =================================================================== --- Lib/socket.py (Revision 58966) +++ Lib/socket.py (Arbeitskopie) @@ -111,10 +111,10 @@ # True if os.dup() can duplicate socket descriptors. -# (On Windows at least, os.dup only works on files) _can_dup_socket = hasattr(_socket.socket, "dup") -if _can_dup_socket: +# On Windows _socket.socket.dup() doesn't accept a file descriptor +if _can_dup_socket and os.name != 'nt': def fromfd(fd, family=AF_INET, type=SOCK_STREAM, proto=0): nfd = os.dup(fd) return socket(family, type, proto, fileno=nfd) Index: Lib/test/test_socket.py =================================================================== --- Lib/test/test_socket.py (Revision 58966) +++ Lib/test/test_socket.py (Arbeitskopie) @@ -566,7 +566,7 @@ def testFromFd(self): # Testing fromfd() if not hasattr(socket, "fromfd"): - return # On Windows, this doesn't exist + return # On BeOS, OS/2 and RiscOS this doesn't exist fd = self.cli_conn.fileno() sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM) msg = sock.recv(1024) @@ -575,6 +575,15 @@ def _testFromFd(self): self.serv_conn.send(MSG) + def testDup(self): + # Testing dup() + sock = self.cli_conn.dup() + msg = sock.recv(1024) + self.assertEqual(msg, MSG) + + def _testDup(self): + self.serv_conn.send(MSG) + def testShutdown(self): # Testing shutdown() msg = self.cli_conn.recv(1024) Index: Modules/socketmodule.c =================================================================== --- Modules/socketmodule.c (Revision 58966) +++ Modules/socketmodule.c (Arbeitskopie) @@ -324,10 +324,25 @@ #include "getnameinfo.c" #endif -#if defined(MS_WINDOWS) -/* seem to be a few differences in the API */ +#ifdef MS_WINDOWS +/* On Windows a socket is really a handle not an fd */ +static SOCKET +duplicate_socket(SOCKET handle) +{ + HANDLE newhandle; + + if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)handle, + GetCurrentProcess(), &newhandle, + 0, FALSE, DUPLICATE_SAME_ACCESS)) + { + WSASetLastError(WSAEBADF); + return INVALID_SOCKET; + } + return (SOCKET)newhandle; +} +#define dup(fd) duplicate_socket(fd) #define SOCKETCLOSE closesocket -#define NO_DUP /* Actually it exists on NT 3.5, but what the heck... */ +#define NO_MAKEFILE /* socket handles can't be treated like file handles */ #endif #ifdef MS_WIN32 @@ -344,6 +359,10 @@ #define SOCKETCLOSE close #endif +#ifdef NO_DUP +#define NO_MAKEFILE +#endif + #if defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H) #define USE_BLUETOOTH 1 #if defined(__FreeBSD__) @@ -1978,8 +1997,13 @@ PyObject *sock; newfd = dup(s->sock_fd); - if (newfd < 0) +#ifdef MS_WINDOWS + if (newfd == INVALID_SOCKET) { +#else + if (newfd < 0) { +#endif return s->errorhandler(); + } sock = (PyObject *) new_sockobject(newfd, s->sock_family, s->sock_type,