mirror of https://github.com/python/cpython
Patch #1003700: Add socketpair function to socket module.
This commit is contained in:
parent
80e53141b9
commit
331708b226
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__":
|
||||
|
|
|
@ -24,6 +24,8 @@ Core and builtins
|
|||
Extension modules
|
||||
-----------------
|
||||
|
||||
- Added socket.socketpair().
|
||||
|
||||
Library
|
||||
-------
|
||||
|
||||
|
|
|
@ -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},
|
||||
|
|
11
configure.in
11
configure.in
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue