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!}
|
\warning{This does not do any certificate verification!}
|
||||||
\end{funcdesc}
|
\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}}
|
\begin{funcdesc}{fromfd}{fd, family, type\optional{, proto}}
|
||||||
Build a socket object from an existing file descriptor (an integer as
|
Build a socket object from an existing file descriptor (an integer as
|
||||||
returned by a file object's \method{fileno()} method). Address family,
|
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:
|
Functions:
|
||||||
|
|
||||||
socket() -- create a new socket object
|
socket() -- create a new socket object
|
||||||
|
socketpair() -- create a pair of new socket objects [*]
|
||||||
fromfd() -- create a socket object from an open file descriptor [*]
|
fromfd() -- create a socket object from an open file descriptor [*]
|
||||||
gethostname() -- return the current hostname
|
gethostname() -- return the current hostname
|
||||||
gethostbyname() -- map a hostname to its IP number
|
gethostbyname() -- map a hostname to its IP number
|
||||||
|
|
|
@ -187,6 +187,28 @@ class SocketConnectedTest(ThreadedTCPSocketTest):
|
||||||
self.serv_conn = None
|
self.serv_conn = None
|
||||||
ThreadedTCPSocketTest.clientTearDown(self)
|
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
|
## Begin Tests
|
||||||
|
|
||||||
|
@ -541,6 +563,25 @@ class BasicUDPTest(ThreadedUDPSocketTest):
|
||||||
def _testRecvFrom(self):
|
def _testRecvFrom(self):
|
||||||
self.cli.sendto(MSG, 0, (HOST, PORT))
|
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):
|
class NonBlockingTCPTests(ThreadedTCPSocketTest):
|
||||||
|
|
||||||
def __init__(self, methodName='runTest'):
|
def __init__(self, methodName='runTest'):
|
||||||
|
@ -786,6 +827,8 @@ def test_main():
|
||||||
LineBufferedFileObjectClassTestCase,
|
LineBufferedFileObjectClassTestCase,
|
||||||
SmallBufferedFileObjectClassTestCase
|
SmallBufferedFileObjectClassTestCase
|
||||||
])
|
])
|
||||||
|
if hasattr(socket, "socketpair"):
|
||||||
|
tests.append(BasicSocketPairTest)
|
||||||
test_support.run_unittest(*tests)
|
test_support.run_unittest(*tests)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -24,6 +24,8 @@ Core and builtins
|
||||||
Extension modules
|
Extension modules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Added socket.socketpair().
|
||||||
|
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ Module interface:
|
||||||
- socket.getservbyname(servicename[, protocolname]) --> port number
|
- socket.getservbyname(servicename[, protocolname]) --> port number
|
||||||
- socket.getservbyport(portnumber[, protocolname]) --> service name
|
- socket.getservbyport(portnumber[, protocolname]) --> service name
|
||||||
- socket.socket([family[, type [, proto]]]) --> new socket object
|
- socket.socket([family[, type [, proto]]]) --> new socket object
|
||||||
|
- socket.socketpair([family[, type [, proto]]]) --> (socket, socket)
|
||||||
- socket.ntohs(16 bit value) --> new int object
|
- socket.ntohs(16 bit value) --> new int object
|
||||||
- socket.ntohl(32 bit value) --> new int object
|
- socket.ntohl(32 bit value) --> new int object
|
||||||
- socket.htons(16 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.)");
|
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
|
#ifndef NO_DUP
|
||||||
/* Create a socket object from a numeric file description.
|
/* Create a socket object from a numeric file description.
|
||||||
Useful e.g. if stdin is a socket.
|
Useful e.g. if stdin is a socket.
|
||||||
|
@ -3607,6 +3665,10 @@ static PyMethodDef socket_methods[] = {
|
||||||
#ifndef NO_DUP
|
#ifndef NO_DUP
|
||||||
{"fromfd", socket_fromfd,
|
{"fromfd", socket_fromfd,
|
||||||
METH_VARARGS, fromfd_doc},
|
METH_VARARGS, fromfd_doc},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SOCKETPAIR
|
||||||
|
{"socketpair", socket_socketpair,
|
||||||
|
METH_VARARGS, socketpair_doc},
|
||||||
#endif
|
#endif
|
||||||
{"ntohs", socket_ntohs,
|
{"ntohs", socket_ntohs,
|
||||||
METH_VARARGS, ntohs_doc},
|
METH_VARARGS, ntohs_doc},
|
||||||
|
|
11
configure.in
11
configure.in
|
@ -2468,6 +2468,17 @@ int foo(int x, ...) {
|
||||||
])
|
])
|
||||||
AC_MSG_RESULT($works)
|
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
|
# check if sockaddr has sa_len member
|
||||||
AC_MSG_CHECKING(if sockaddr has sa_len member)
|
AC_MSG_CHECKING(if sockaddr has sa_len member)
|
||||||
AC_TRY_COMPILE([#include <sys/types.h>
|
AC_TRY_COMPILE([#include <sys/types.h>
|
||||||
|
|
|
@ -428,6 +428,9 @@
|
||||||
/* Define to 1 if you have the `snprintf' function. */
|
/* Define to 1 if you have the `snprintf' function. */
|
||||||
#undef HAVE_SNPRINTF
|
#undef HAVE_SNPRINTF
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `socketpair' function. */
|
||||||
|
#undef HAVE_SOCKETPAIR
|
||||||
|
|
||||||
/* Define if sockaddr has sa_len member */
|
/* Define if sockaddr has sa_len member */
|
||||||
#undef HAVE_SOCKADDR_SA_LEN
|
#undef HAVE_SOCKADDR_SA_LEN
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue