Patch #1003700: Add socketpair function to socket module.

This commit is contained in:
Dave Cole 2004-08-09 04:51:41 +00:00
parent 80e53141b9
commit 331708b226
7 changed files with 130 additions and 0 deletions

View File

@ -303,6 +303,14 @@ success, a new \class{SSLObject} is returned.
\warning{This does not do any certificate verification!}
\end{funcdesc}
\begin{funcdesc}{socketpair}{\optional{family\optional{, type\optional{, proto}}}}
Build a pair of connected socket objects using the given address
family, socket type and protocol number. Address family, socket type
and protocol number are as for the \function{socket()} function above.
Availability: \UNIX.
\versionadded{2.3}
\end{funcdesc}
\begin{funcdesc}{fromfd}{fd, family, type\optional{, proto}}
Build a socket object from an existing file descriptor (an integer as
returned by a file object's \method{fileno()} method). Address family,

View File

@ -10,6 +10,7 @@ socket are available as methods of the socket object.
Functions:
socket() -- create a new socket object
socketpair() -- create a pair of new socket objects [*]
fromfd() -- create a socket object from an open file descriptor [*]
gethostname() -- return the current hostname
gethostbyname() -- map a hostname to its IP number

View File

@ -187,6 +187,28 @@ class SocketConnectedTest(ThreadedTCPSocketTest):
self.serv_conn = None
ThreadedTCPSocketTest.clientTearDown(self)
class SocketPairTest(unittest.TestCase, ThreadableTest):
def __init__(self, methodName='runTest'):
unittest.TestCase.__init__(self, methodName=methodName)
ThreadableTest.__init__(self)
def setUp(self):
self.serv, self.cli = socket.socketpair()
def tearDown(self):
self.serv.close()
self.serv = None
def clientSetUp(self):
pass
def clientTearDown(self):
self.cli.close()
self.cli = None
ThreadableTest.clientTearDown(self)
#######################################################################
## Begin Tests
@ -541,6 +563,25 @@ class BasicUDPTest(ThreadedUDPSocketTest):
def _testRecvFrom(self):
self.cli.sendto(MSG, 0, (HOST, PORT))
class BasicSocketPairTest(SocketPairTest):
def __init__(self, methodName='runTest'):
SocketPairTest.__init__(self, methodName=methodName)
def testRecv(self):
msg = self.serv.recv(1024)
self.assertEqual(msg, MSG)
def _testRecv(self):
self.cli.send(MSG)
def testSend(self):
self.serv.send(MSG)
def _testSend(self):
msg = self.cli.recv(1024)
self.assertEqual(msg, MSG)
class NonBlockingTCPTests(ThreadedTCPSocketTest):
def __init__(self, methodName='runTest'):
@ -786,6 +827,8 @@ def test_main():
LineBufferedFileObjectClassTestCase,
SmallBufferedFileObjectClassTestCase
])
if hasattr(socket, "socketpair"):
tests.append(BasicSocketPairTest)
test_support.run_unittest(*tests)
if __name__ == "__main__":

View File

@ -24,6 +24,8 @@ Core and builtins
Extension modules
-----------------
- Added socket.socketpair().
Library
-------

View File

@ -28,6 +28,7 @@ Module interface:
- socket.getservbyname(servicename[, protocolname]) --> port number
- socket.getservbyport(portnumber[, protocolname]) --> service name
- socket.socket([family[, type [, proto]]]) --> new socket object
- socket.socketpair([family[, type [, proto]]]) --> (socket, socket)
- socket.ntohs(16 bit value) --> new int object
- socket.ntohl(32 bit value) --> new int object
- socket.htons(16 bit value) --> new int object
@ -3009,6 +3010,63 @@ PyDoc_STRVAR(getprotobyname_doc,
Return the protocol number for the named protocol. (Rarely used.)");
#ifdef HAVE_SOCKETPAIR
/* Create a pair of sockets using the socketpair() function.
Arguments as for socket(). */
/*ARGSUSED*/
static PyObject *
socket_socketpair(PyObject *self, PyObject *args)
{
PySocketSockObject *s0 = NULL, *s1 = NULL;
SOCKET_T sv[2];
int family, type = SOCK_STREAM, proto = 0;
PyObject *res = NULL;
#if defined(AF_UNIX)
family = AF_UNIX;
#else
family = AF_INET;
#endif
if (!PyArg_ParseTuple(args, "|iii:socketpair",
&family, &type, &proto))
return NULL;
/* Create a pair of socket fds */
if (socketpair(family, type, proto, sv) < 0)
return set_error();
#ifdef SIGPIPE
(void) signal(SIGPIPE, SIG_IGN);
#endif
s0 = new_sockobject(sv[0], family, type, proto);
if (s0 == NULL)
goto finally;
s1 = new_sockobject(sv[1], family, type, proto);
if (s1 == NULL)
goto finally;
res = PyTuple_Pack(2, s0, s1);
finally:
if (res == NULL) {
if (s0 == NULL)
SOCKETCLOSE(sv[0]);
if (s1 == NULL)
SOCKETCLOSE(sv[1]);
}
Py_XDECREF(s0);
Py_XDECREF(s1);
return res;
}
PyDoc_STRVAR(socketpair_doc,
"socketpair([family[, type[, proto]]]) -> (socket object, socket object)\n\
\n\
Create a pair of socket objects from the sockets returned by the platform\n\
socketpair() function.\n\
The arguments are the same as for socket().");
#endif /* HAVE_SOCKETPAIR */
#ifndef NO_DUP
/* Create a socket object from a numeric file description.
Useful e.g. if stdin is a socket.
@ -3607,6 +3665,10 @@ static PyMethodDef socket_methods[] = {
#ifndef NO_DUP
{"fromfd", socket_fromfd,
METH_VARARGS, fromfd_doc},
#endif
#ifdef HAVE_SOCKETPAIR
{"socketpair", socket_socketpair,
METH_VARARGS, socketpair_doc},
#endif
{"ntohs", socket_ntohs,
METH_VARARGS, ntohs_doc},

View File

@ -2468,6 +2468,17 @@ int foo(int x, ...) {
])
AC_MSG_RESULT($works)
# check for socketpair
AC_MSG_CHECKING(for socketpair)
AC_TRY_COMPILE([
#include <sys/types.h>
#include <sys/socket.h>
], void *x=socketpair,
AC_DEFINE(HAVE_SOCKETPAIR, 1, Define if you have the 'socketpair' function.)
AC_MSG_RESULT(yes),
AC_MSG_RESULT(no)
)
# check if sockaddr has sa_len member
AC_MSG_CHECKING(if sockaddr has sa_len member)
AC_TRY_COMPILE([#include <sys/types.h>

View File

@ -428,6 +428,9 @@
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Define to 1 if you have the `socketpair' function. */
#undef HAVE_SOCKETPAIR
/* Define if sockaddr has sa_len member */
#undef HAVE_SOCKADDR_SA_LEN