Sockets facelift. APIs that could return binary data (e.g. aton() and
recv()) now return bytes, not str or str8.  The socket.py code is
redone; it now subclasses _socket.socket and instead of having its own
_fileobject for makefile(), it uses io.SocketIO.  Some stuff in io.py
was moved around to make this work.  (I really need to rethink my
policy regarding readline() and read(-1) on raw files; and readline()
on buffered files ought to use peeking().  Later.)
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 71eafe6..eca29dd 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -19,15 +19,14 @@
 	a subclass of socket.error
 - socket.herror: exception raised for gethostby* errors,
 	a subclass of socket.error
-- socket.fromfd(fd, family, type[, proto]) --> new socket object (created
-        from an existing file descriptor)
 - socket.gethostbyname(hostname) --> host IP address (string: 'dd.dd.dd.dd')
 - socket.gethostbyaddr(IP address) --> (hostname, [alias, ...], [IP addr, ...])
 - socket.gethostname() --> host name (string: 'spam' or 'spam.domain.com')
 - socket.getprotobyname(protocolname) --> protocol number
 - socket.getservbyname(servicename[, protocolname]) --> port number
 - socket.getservbyport(portnumber[, protocolname]) --> service name
-- socket.socket([family[, type [, proto]]]) --> new socket object
+- socket.socket([family[, type [, proto, fileno]]]) --> new socket object
+        (fileno specifies a pre-existing socket file descriptor)
 - socket.socketpair([family[, type [, proto]]]) --> (socket, socket)
 - socket.ntohs(16 bit value) --> new int object
 - socket.ntohl(32 bit value) --> new int object
@@ -102,7 +101,6 @@
 getsockopt(level, optname[, buflen]) -- get socket options\n\
 gettimeout() -- return timeout or None\n\
 listen(n) -- start listening for incoming connections\n\
-makefile([mode, [bufsize]]) -- return a file object for the socket [*]\n\
 recv(buflen[, flags]) -- receive data\n\
 recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)\n\
 recvfrom(buflen[, flags]) -- receive data and sender\'s address\n\
@@ -402,6 +400,10 @@
 #define NI_MAXSERV 32
 #endif
 
+#ifndef INVALID_SOCKET /* MS defines this */
+#define INVALID_SOCKET (-1)
+#endif
+
 /* XXX There's a problem here: *static* functions are not supposed to have
    a Py prefix (or use CapitalizedWords).  Later... */
 
@@ -1551,7 +1553,7 @@
 sock_accept(PySocketSockObject *s)
 {
 	sock_addr_t addrbuf;
-	SOCKET_T newfd;
+	SOCKET_T newfd = INVALID_SOCKET;
 	socklen_t addrlen;
 	PyObject *sock = NULL;
 	PyObject *addr = NULL;
@@ -1562,12 +1564,6 @@
 		return NULL;
 	memset(&addrbuf, 0, addrlen);
 
-#ifdef MS_WINDOWS
-	newfd = INVALID_SOCKET;
-#else
-	newfd = -1;
-#endif
-
 	if (!IS_SELECTABLE(s))
 		return select_error();
 
@@ -1582,11 +1578,7 @@
 		return NULL;
 	}
 
-#ifdef MS_WINDOWS
 	if (newfd == INVALID_SOCKET)
-#else
-	if (newfd < 0)
-#endif
 		return s->errorhandler();
 
 	/* Create the new object with unspecified family,
@@ -1814,16 +1806,19 @@
 				"getsockopt buflen out of range");
 		return NULL;
 	}
-	buf = PyString_FromStringAndSize((char *)NULL, buflen);
+	buf = PyBytes_FromStringAndSize((char *)NULL, buflen);
 	if (buf == NULL)
 		return NULL;
 	res = getsockopt(s->sock_fd, level, optname,
-			 (void *)PyString_AS_STRING(buf), &buflen);
+			 (void *)PyBytes_AS_STRING(buf), &buflen);
 	if (res < 0) {
 		Py_DECREF(buf);
 		return s->errorhandler();
 	}
-	_PyString_Resize(&buf, buflen);
+	if (PyBytes_Resize(buf, buflen) < 0) {
+		Py_DECREF(buf);
+		return NULL;
+	}
 	return buf;
 #endif /* __BEOS__ */
 }
@@ -2173,69 +2168,6 @@
 will allow before refusing new connections.");
 
 
-#ifndef NO_DUP
-/* 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
-   that the open file and socket objects may be closed independent
-   of each other.)
-   The mode argument specifies 'r' or 'w' passed to fdopen(). */
-
-static PyObject *
-sock_makefile(PySocketSockObject *s, PyObject *args)
-{
-	extern int fclose(FILE *);
-	char *mode = "r";
-	int bufsize = -1;
-#ifdef MS_WIN32
-	Py_intptr_t fd;
-#else
-	int fd;
-#endif
-	FILE *fp;
-	PyObject *f;
-#ifdef __VMS
-	char *mode_r = "r";
-	char *mode_w = "w";
-#endif
-
-	if (!PyArg_ParseTuple(args, "|si:makefile", &mode, &bufsize))
-		return NULL;
-#ifdef __VMS
-	if (strcmp(mode,"rb") == 0) {
-	    mode = mode_r;
-	}
-	else {
-		if (strcmp(mode,"wb") == 0) {
-			mode = mode_w;
-		}
-	}
-#endif
-#ifdef MS_WIN32
-	if (((fd = _open_osfhandle(s->sock_fd, _O_BINARY)) < 0) ||
-	    ((fd = dup(fd)) < 0) || ((fp = fdopen(fd, mode)) == NULL))
-#else
-	if ((fd = dup(s->sock_fd)) < 0 || (fp = fdopen(fd, mode)) == NULL)
-#endif
-	{
-		if (fd >= 0)
-			SOCKETCLOSE(fd);
-		return s->errorhandler();
-	}
-	f = PyFile_FromFile(fp, "<socket>", mode, fclose);
-	if (f != NULL)
-		PyFile_SetBufSize(f, bufsize);
-	return f;
-}
-
-PyDoc_STRVAR(makefile_doc,
-"makefile([mode[, buffersize]]) -> file object\n\
-\n\
-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 */
-
 /*
  * This is the guts of the recv() and recv_into() methods, which reads into a
  * char buffer.  If you have any inc/dec ref to do to the objects that contain
@@ -2339,12 +2271,12 @@
 	}
 
 	/* Allocate a new string. */
-	buf = PyString_FromStringAndSize((char *) 0, recvlen);
+	buf = PyBytes_FromStringAndSize((char *) 0, recvlen);
 	if (buf == NULL)
 		return NULL;
 
 	/* Call the guts */
-	outlen = sock_recv_guts(s, PyString_AS_STRING(buf), recvlen, flags);
+	outlen = sock_recv_guts(s, PyBytes_AS_STRING(buf), recvlen, flags);
 	if (outlen < 0) {
 		/* An error occurred, release the string and return an
 		   error. */
@@ -2354,7 +2286,7 @@
 	if (outlen != recvlen) {
 		/* We did not read as many bytes as we anticipated, resize the
 		   string if possible and be succesful. */
-		if (_PyString_Resize(&buf, outlen) < 0)
+		if (PyBytes_Resize(buf, outlen) < 0)
 			/* Oopsy, not so succesful after all. */
 			return NULL;
 	}
@@ -2513,11 +2445,11 @@
 		return NULL;
 	}
 
-	buf = PyString_FromStringAndSize((char *) 0, recvlen);
+	buf = PyBytes_FromStringAndSize((char *) 0, recvlen);
 	if (buf == NULL)
 		return NULL;
 
-	outlen = sock_recvfrom_guts(s, PyString_AS_STRING(buf),
+	outlen = sock_recvfrom_guts(s, PyBytes_AS_STRING(buf),
 				    recvlen, flags, &addr);
 	if (outlen < 0) {
 		goto finally;
@@ -2526,7 +2458,7 @@
 	if (outlen != recvlen) {
 		/* We did not read as many bytes as we anticipated, resize the
 		   string if possible and be succesful. */
-		if (_PyString_Resize(&buf, outlen) < 0)
+		if (PyBytes_Resize(buf, outlen) < 0)
 			/* Oopsy, not so succesful after all. */
 			goto finally;
 	}
@@ -2788,10 +2720,6 @@
 			  getsockopt_doc},
 	{"listen",	  (PyCFunction)sock_listen, METH_O,
 			  listen_doc},
-#ifndef NO_DUP
-	{"makefile",	  (PyCFunction)sock_makefile, METH_VARARGS,
-			  makefile_doc},
-#endif
 	{"recv",	  (PyCFunction)sock_recv, METH_VARARGS,
 			  recv_doc},
 	{"recv_into",	  (PyCFunction)sock_recv_into, METH_VARARGS | METH_KEYWORDS,
@@ -2861,7 +2789,7 @@
 #endif
 	PyOS_snprintf(
 		buf, sizeof(buf),
-		"<socket object, fd=%ld, family=%d, type=%d, protocol=%d>",
+		"<socket object, fd=%ld, family=%d, type=%d, proto=%d>",
 		(long)s->sock_fd, s->sock_family,
 		s->sock_type,
 		s->sock_proto);
@@ -2893,27 +2821,35 @@
 sock_initobj(PyObject *self, PyObject *args, PyObject *kwds)
 {
 	PySocketSockObject *s = (PySocketSockObject *)self;
-	SOCKET_T fd;
+	PyObject *fdobj = NULL;
+	SOCKET_T fd = INVALID_SOCKET;
 	int family = AF_INET, type = SOCK_STREAM, proto = 0;
-	static char *keywords[] = {"family", "type", "proto", 0};
+	static char *keywords[] = {"family", "type", "proto", "fileno", 0};
 
 	if (!PyArg_ParseTupleAndKeywords(args, kwds,
-					 "|iii:socket", keywords,
-					 &family, &type, &proto))
+					 "|iiiO:socket", keywords,
+					 &family, &type, &proto, &fdobj))
 		return -1;
 
-	Py_BEGIN_ALLOW_THREADS
-	fd = socket(family, type, proto);
-	Py_END_ALLOW_THREADS
+	if (fdobj != NULL) {
+		fd = PyLong_AsLongLong(fdobj);
+		if (fd == (SOCKET_T)(-1) && PyErr_Occurred())
+			return -1;
+		if (fd == INVALID_SOCKET) {
+			PyErr_SetString(PyExc_ValueError,
+					"can't use invalid socket value");
+			return -1;
+		}
+	}
+	else {
+		Py_BEGIN_ALLOW_THREADS
+		fd = socket(family, type, proto);
+		Py_END_ALLOW_THREADS
 
-#ifdef MS_WINDOWS
-	if (fd == INVALID_SOCKET)
-#else
-	if (fd < 0)
-#endif
-	{
-		set_error();
-		return -1;
+		if (fd == INVALID_SOCKET) {
+			set_error();
+			return -1;
+		}
 	}
 	init_sockobject(s, fd, family, type, proto);
 
@@ -3462,39 +3398,6 @@
 #endif /* HAVE_SOCKETPAIR */
 
 
-#ifndef NO_DUP
-/* Create a socket object from a numeric file description.
-   Useful e.g. if stdin is a socket.
-   Additional arguments as for socket(). */
-
-/*ARGSUSED*/
-static PyObject *
-socket_fromfd(PyObject *self, PyObject *args)
-{
-	PySocketSockObject *s;
-	SOCKET_T fd;
-	int family, type, proto = 0;
-	if (!PyArg_ParseTuple(args, "iii|i:fromfd",
-			      &fd, &family, &type, &proto))
-		return NULL;
-	/* Dup the fd so it and the socket can be closed independently */
-	fd = dup(fd);
-	if (fd < 0)
-		return set_error();
-	s = new_sockobject(fd, family, type, proto);
-	return (PyObject *) s;
-}
-
-PyDoc_STRVAR(fromfd_doc,
-"fromfd(fd, family, type[, proto]) -> socket object\n\
-\n\
-Create a socket object from a duplicate of the given\n\
-file descriptor.\n\
-The remaining arguments are the same as for socket().");
-
-#endif /* NO_DUP */
-
-
 static PyObject *
 socket_ntohs(PyObject *self, PyObject *args)
 {
@@ -3613,7 +3516,7 @@
 /* socket.inet_aton() and socket.inet_ntoa() functions. */
 
 PyDoc_STRVAR(inet_aton_doc,
-"inet_aton(string) -> packed 32-bit IP representation\n\
+"inet_aton(string) -> bytes giving packed 32-bit IP representation\n\
 \n\
 Convert an IP address in string format (123.45.67.89) to the 32-bit packed\n\
 binary format used in low-level network functions.");
@@ -3644,7 +3547,7 @@
     if (inet_aton != NULL) {
 #endif
 	if (inet_aton(ip_addr, &buf))
-		return PyString_FromStringAndSize((char *)(&buf),
+		return PyBytes_FromStringAndSize((char *)(&buf),
 						  sizeof(buf));
 
 	PyErr_SetString(socket_error,
@@ -3673,8 +3576,8 @@
 			return NULL;
 		}
 	}
-	return PyString_FromStringAndSize((char *) &packed_addr,
-					  sizeof(packed_addr));
+	return PyBytes_FromStringAndSize((char *) &packed_addr,
+					 sizeof(packed_addr));
 
 #ifdef USE_INET_ATON_WEAKLINK
    }
@@ -4077,10 +3980,6 @@
 	 METH_VARARGS, getservbyport_doc},
 	{"getprotobyname",	socket_getprotobyname,
 	 METH_VARARGS, getprotobyname_doc},
-#ifndef NO_DUP
-	{"fromfd",		socket_fromfd,
-	 METH_VARARGS, fromfd_doc},
-#endif
 #ifdef HAVE_SOCKETPAIR
 	{"socketpair",		socket_socketpair,
 	 METH_VARARGS, socketpair_doc},
@@ -4229,14 +4128,11 @@
 /* Initialize the _socket module.
 
    This module is actually called "_socket", and there's a wrapper
-   "socket.py" which implements some additional functionality.  On some
-   platforms (e.g. Windows and OS/2), socket.py also implements a
-   wrapper for the socket type that provides missing functionality such
-   as makefile(), dup() and fromfd().  The import of "_socket" may fail
-   with an ImportError exception if os-specific initialization fails.
-   On Windows, this does WINSOCK initialization.  When WINSOCK is
-   initialized succesfully, a call to WSACleanup() is scheduled to be
-   made at exit time.
+   "socket.py" which implements some additional functionality.
+   The import of "_socket" may fail with an ImportError exception if
+   os-specific initialization fails.  On Windows, this does WINSOCK
+   initialization.  When WINSOCK is initialized succesfully, a call to
+   WSACleanup() is scheduled to be made at exit time.
 */
 
 PyDoc_STRVAR(socket_doc,