Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 331708b

Browse files
author
Dave Cole
committed
Patch #1003700: Add socketpair function to socket module.
1 parent 80e5314 commit 331708b

7 files changed

Lines changed: 130 additions & 0 deletions

File tree

Doc/lib/libsocket.tex

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,14 @@ \section{\module{socket} ---
303303
\warning{This does not do any certificate verification!}
304304
\end{funcdesc}
305305

306+
\begin{funcdesc}{socketpair}{\optional{family\optional{, type\optional{, proto}}}}
307+
Build a pair of connected socket objects using the given address
308+
family, socket type and protocol number. Address family, socket type
309+
and protocol number are as for the \function{socket()} function above.
310+
Availability: \UNIX.
311+
\versionadded{2.3}
312+
\end{funcdesc}
313+
306314
\begin{funcdesc}{fromfd}{fd, family, type\optional{, proto}}
307315
Build a socket object from an existing file descriptor (an integer as
308316
returned by a file object's \method{fileno()} method). Address family,

Lib/socket.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
Functions:
1111
1212
socket() -- create a new socket object
13+
socketpair() -- create a pair of new socket objects [*]
1314
fromfd() -- create a socket object from an open file descriptor [*]
1415
gethostname() -- return the current hostname
1516
gethostbyname() -- map a hostname to its IP number

Lib/test/test_socket.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,28 @@ def clientTearDown(self):
187187
self.serv_conn = None
188188
ThreadedTCPSocketTest.clientTearDown(self)
189189

190+
class SocketPairTest(unittest.TestCase, ThreadableTest):
191+
192+
def __init__(self, methodName='runTest'):
193+
unittest.TestCase.__init__(self, methodName=methodName)
194+
ThreadableTest.__init__(self)
195+
196+
def setUp(self):
197+
self.serv, self.cli = socket.socketpair()
198+
199+
def tearDown(self):
200+
self.serv.close()
201+
self.serv = None
202+
203+
def clientSetUp(self):
204+
pass
205+
206+
def clientTearDown(self):
207+
self.cli.close()
208+
self.cli = None
209+
ThreadableTest.clientTearDown(self)
210+
211+
190212
#######################################################################
191213
## Begin Tests
192214

@@ -541,6 +563,25 @@ def testRecvFrom(self):
541563
def _testRecvFrom(self):
542564
self.cli.sendto(MSG, 0, (HOST, PORT))
543565

566+
class BasicSocketPairTest(SocketPairTest):
567+
568+
def __init__(self, methodName='runTest'):
569+
SocketPairTest.__init__(self, methodName=methodName)
570+
571+
def testRecv(self):
572+
msg = self.serv.recv(1024)
573+
self.assertEqual(msg, MSG)
574+
575+
def _testRecv(self):
576+
self.cli.send(MSG)
577+
578+
def testSend(self):
579+
self.serv.send(MSG)
580+
581+
def _testSend(self):
582+
msg = self.cli.recv(1024)
583+
self.assertEqual(msg, MSG)
584+
544585
class NonBlockingTCPTests(ThreadedTCPSocketTest):
545586

546587
def __init__(self, methodName='runTest'):
@@ -786,6 +827,8 @@ def test_main():
786827
LineBufferedFileObjectClassTestCase,
787828
SmallBufferedFileObjectClassTestCase
788829
])
830+
if hasattr(socket, "socketpair"):
831+
tests.append(BasicSocketPairTest)
789832
test_support.run_unittest(*tests)
790833

791834
if __name__ == "__main__":

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ Core and builtins
2424
Extension modules
2525
-----------------
2626

27+
- Added socket.socketpair().
28+
2729
Library
2830
-------
2931

Modules/socketmodule.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Module interface:
2828
- socket.getservbyname(servicename[, protocolname]) --> port number
2929
- socket.getservbyport(portnumber[, protocolname]) --> service name
3030
- socket.socket([family[, type [, proto]]]) --> new socket object
31+
- socket.socketpair([family[, type [, proto]]]) --> (socket, socket)
3132
- socket.ntohs(16 bit value) --> new int object
3233
- socket.ntohl(32 bit value) --> new int object
3334
- socket.htons(16 bit value) --> new int object
@@ -3009,6 +3010,63 @@ PyDoc_STRVAR(getprotobyname_doc,
30093010
Return the protocol number for the named protocol. (Rarely used.)");
30103011

30113012

3013+
#ifdef HAVE_SOCKETPAIR
3014+
/* Create a pair of sockets using the socketpair() function.
3015+
Arguments as for socket(). */
3016+
3017+
/*ARGSUSED*/
3018+
static PyObject *
3019+
socket_socketpair(PyObject *self, PyObject *args)
3020+
{
3021+
PySocketSockObject *s0 = NULL, *s1 = NULL;
3022+
SOCKET_T sv[2];
3023+
int family, type = SOCK_STREAM, proto = 0;
3024+
PyObject *res = NULL;
3025+
3026+
#if defined(AF_UNIX)
3027+
family = AF_UNIX;
3028+
#else
3029+
family = AF_INET;
3030+
#endif
3031+
if (!PyArg_ParseTuple(args, "|iii:socketpair",
3032+
&family, &type, &proto))
3033+
return NULL;
3034+
/* Create a pair of socket fds */
3035+
if (socketpair(family, type, proto, sv) < 0)
3036+
return set_error();
3037+
#ifdef SIGPIPE
3038+
(void) signal(SIGPIPE, SIG_IGN);
3039+
#endif
3040+
s0 = new_sockobject(sv[0], family, type, proto);
3041+
if (s0 == NULL)
3042+
goto finally;
3043+
s1 = new_sockobject(sv[1], family, type, proto);
3044+
if (s1 == NULL)
3045+
goto finally;
3046+
res = PyTuple_Pack(2, s0, s1);
3047+
3048+
finally:
3049+
if (res == NULL) {
3050+
if (s0 == NULL)
3051+
SOCKETCLOSE(sv[0]);
3052+
if (s1 == NULL)
3053+
SOCKETCLOSE(sv[1]);
3054+
}
3055+
Py_XDECREF(s0);
3056+
Py_XDECREF(s1);
3057+
return res;
3058+
}
3059+
3060+
PyDoc_STRVAR(socketpair_doc,
3061+
"socketpair([family[, type[, proto]]]) -> (socket object, socket object)\n\
3062+
\n\
3063+
Create a pair of socket objects from the sockets returned by the platform\n\
3064+
socketpair() function.\n\
3065+
The arguments are the same as for socket().");
3066+
3067+
#endif /* HAVE_SOCKETPAIR */
3068+
3069+
30123070
#ifndef NO_DUP
30133071
/* Create a socket object from a numeric file description.
30143072
Useful e.g. if stdin is a socket.
@@ -3607,6 +3665,10 @@ static PyMethodDef socket_methods[] = {
36073665
#ifndef NO_DUP
36083666
{"fromfd", socket_fromfd,
36093667
METH_VARARGS, fromfd_doc},
3668+
#endif
3669+
#ifdef HAVE_SOCKETPAIR
3670+
{"socketpair", socket_socketpair,
3671+
METH_VARARGS, socketpair_doc},
36103672
#endif
36113673
{"ntohs", socket_ntohs,
36123674
METH_VARARGS, ntohs_doc},

configure.in

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,6 +2468,17 @@ int foo(int x, ...) {
24682468
])
24692469
AC_MSG_RESULT($works)
24702470

2471+
# check for socketpair
2472+
AC_MSG_CHECKING(for socketpair)
2473+
AC_TRY_COMPILE([
2474+
#include <sys/types.h>
2475+
#include <sys/socket.h>
2476+
], void *x=socketpair,
2477+
AC_DEFINE(HAVE_SOCKETPAIR, 1, Define if you have the 'socketpair' function.)
2478+
AC_MSG_RESULT(yes),
2479+
AC_MSG_RESULT(no)
2480+
)
2481+
24712482
# check if sockaddr has sa_len member
24722483
AC_MSG_CHECKING(if sockaddr has sa_len member)
24732484
AC_TRY_COMPILE([#include <sys/types.h>

pyconfig.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,9 @@
428428
/* Define to 1 if you have the `snprintf' function. */
429429
#undef HAVE_SNPRINTF
430430

431+
/* Define to 1 if you have the `socketpair' function. */
432+
#undef HAVE_SOCKETPAIR
433+
431434
/* Define if sockaddr has sa_len member */
432435
#undef HAVE_SOCKADDR_SA_LEN
433436

0 commit comments

Comments
 (0)