Christian Heimes added the comment:

I've created a clean patch and tested it. It works as promised, great
work! Somebody with more Windows Fu than me should verify it before it's
applied.

----------
nosy: +tiran
Added file: http://bugs.python.org/file8723/trunk_socket_fromfd.patch

__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1378>
__________________________________
Index: Lib/test/test_socket.py
===================================================================
--- Lib/test/test_socket.py	(Revision 58923)
+++ Lib/test/test_socket.py	(Arbeitskopie)
@@ -558,7 +558,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)
@@ -567,6 +567,27 @@
     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 testInnerDup(self):
+        # Testing dup() for the wrapped socket object
+        inner = self.cli_conn._sock
+        if not hasattr(inner, "dup"):
+            return # On BeOS, OS/2 and RiscOS this doesn't exist
+        sock = inner.dup()
+        msg = sock.recv(1024)
+        self.assertEqual(msg, MSG)
+
+    def _testInnerDup(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 58923)
+++ Modules/socketmodule.c	(Arbeitskopie)
@@ -336,11 +336,32 @@
 #include "getnameinfo.c"
 #endif
 
-#if defined(MS_WINDOWS) || defined(__BEOS__)
+#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_MAKEFILE /* socket handles can't be treated like file handles */
+#endif
+
+#ifdef __BEOS__
 /* BeOS suffers from the same socket dichotomy as Win32... - [cjh] */
 /* seem to be a few differences in the API */
 #define SOCKETCLOSE closesocket
-#define NO_DUP /* Actually it exists on NT 3.5, but what the heck... */
+#define NO_DUP
 #endif
 
 #ifdef MS_WIN32
@@ -357,6 +378,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__)
@@ -2068,7 +2093,11 @@
 	PyObject *sock;
 
 	newfd = dup(s->sock_fd);
+#ifdef MS_WINDOWS
+	if (newfd == INVALID_SOCKET)
+#else
 	if (newfd < 0)
+#endif
 		return s->errorhandler();
 	sock = (PyObject *) new_sockobject(newfd,
 					   s->sock_family,
@@ -2176,7 +2205,7 @@
 will allow before refusing new connections.");
 
 
-#ifndef NO_DUP
+#ifndef NO_MAKEFILE
 /* s.makefile(mode) method.
    Create a new open file object referring to a dupped version of
    the socket's file descriptor.  (The dup() call is necessary so
@@ -2237,7 +2266,7 @@
 Return a regular file object corresponding to the socket.\n\
 The mode and buffersize arguments are as for the built-in open() function.");
 
-#endif /* NO_DUP */
+#endif /* NO_MAKEFILE */
 
 /*
  * This is the guts of the recv() and recv_into() methods, which reads into a
@@ -2791,7 +2820,7 @@
 			  getsockopt_doc},
 	{"listen",	  (PyCFunction)sock_listen, METH_O,
 			  listen_doc},
-#ifndef NO_DUP
+#ifndef NO_MAKEFILE
 	{"makefile",	  (PyCFunction)sock_makefile, METH_VARARGS,
 			  makefile_doc},
 #endif
@@ -3481,7 +3510,11 @@
 		return NULL;
 	/* Dup the fd so it and the socket can be closed independently */
 	fd = dup(fd);
+#ifdef MS_WINDOWS
+	if (fd == INVALID_SOCKET)
+#else
 	if (fd < 0)
+#endif
 		return set_error();
 	s = new_sockobject(fd, family, type, proto);
 	return (PyObject *) s;
_______________________________________________
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to