build: Remove --enable-smbtorture, require bin/smbtorture (from waf) for make test
[Samba/bb.git] / lib / socket_wrapper / py_socket_wrapper.c
blobf5742d3dd1011aedc29667f7b40b5b75ad7cbd8f
1 /*
2 * Copyright (C) Amitay Isaacs 2011
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the author nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
36 Python interface to socket wrapper library.
38 Passes all socket communication over unix domain sockets if the environment
39 variable SOCKET_WRAPPER_DIR is set.
42 #include <Python.h>
43 #include <pytalloc.h>
44 #include "replace/replace.h"
45 #include "system/network.h"
46 #include "socket_wrapper.h"
48 /* There's no Py_ssize_t in 2.4, apparently */
49 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
50 typedef int Py_ssize_t;
51 typedef inquiry lenfunc;
52 typedef intargfunc ssizeargfunc;
53 #endif
55 #ifndef Py_RETURN_NONE
56 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
57 #endif
59 #ifndef Py_TYPE /* Py_TYPE is only available on Python > 2.6 */
60 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
61 #endif
63 #ifndef PY_CHECK_TYPE
64 #define PY_CHECK_TYPE(type, var, fail) \
65 if (!PyObject_TypeCheck(var, type)) {\
66 PyErr_Format(PyExc_TypeError, __location__ ": Expected type '%s' for '%s' of type '%s'", (type)->tp_name, #var, Py_TYPE(var)->tp_name); \
67 fail; \
69 #endif
71 staticforward PyTypeObject PySocket;
73 static PyObject *py_socket_error;
75 void initsocket_wrapper(void);
77 static PyObject *py_socket_addr_to_tuple(struct sockaddr *addr, socklen_t len)
79 char host[256];
80 char service[8];
81 int status;
82 PyObject *pyaddr;
84 status = getnameinfo(addr, len, host, 255, service, 7, NI_NUMERICHOST|NI_NUMERICSERV);
85 if (status < 0) {
86 PyErr_SetString(py_socket_error, gai_strerror(status));
87 return NULL;
90 pyaddr = PyTuple_New(2);
91 if (pyaddr == NULL) {
92 return PyErr_NoMemory();
95 PyTuple_SetItem(pyaddr, 0, PyString_FromString(host));
96 PyTuple_SetItem(pyaddr, 1, PyInt_FromLong(atoi(service)));
98 return pyaddr;
101 static bool py_socket_tuple_to_addr(PyObject *pyaddr, struct sockaddr *addr, socklen_t *len)
103 const char *host;
104 char *service;
105 in_port_t port;
106 struct addrinfo *ainfo;
107 int status;
109 if (!PyTuple_Check(pyaddr)) {
110 PyErr_SetString(PyExc_TypeError, "Expected a tuple");
111 return false;
114 if (!PyArg_ParseTuple(pyaddr, "sH", &host, &port)) {
115 return false;
118 service = talloc_asprintf(NULL, "%d", port);
119 if (service == NULL) {
120 PyErr_NoMemory();
121 return false;
124 status = getaddrinfo(host, service, NULL, &ainfo);
125 if (status < 0) {
126 talloc_free(service);
127 PyErr_SetString(py_socket_error, gai_strerror(status));
128 return false;
131 talloc_free(service);
133 memcpy(addr, ainfo->ai_addr, sizeof(struct sockaddr));
134 *len = ainfo->ai_addrlen;
136 freeaddrinfo(ainfo);
137 return true;
141 static PyObject *py_socket_accept(pytalloc_Object *self, PyObject *args)
143 int *sock, *new_sock;
144 struct sockaddr addr;
145 socklen_t addrlen;
146 PyObject *pysocket;
147 PyObject *pyaddr;
148 PyObject *pyret;
150 sock = pytalloc_get_ptr(self);
152 new_sock = talloc_zero(NULL, int);
153 if (new_sock == NULL) {
154 return PyErr_NoMemory();
157 *new_sock = swrap_accept(*sock, &addr, &addrlen);
158 if (*new_sock < 0) {
159 return PyErr_SetFromErrno(py_socket_error);
162 if ((pysocket = pytalloc_steal(&PySocket, new_sock)) == NULL) {
163 return PyErr_NoMemory();
166 pyret = PyTuple_New(2);
167 if (pyret == NULL) {
168 Py_DECREF(pysocket);
169 return PyErr_NoMemory();
172 pyaddr = py_socket_addr_to_tuple(&addr, addrlen);
173 if (pyaddr == NULL) {
174 Py_DECREF(pysocket);
175 Py_DECREF(pysocket);
176 return NULL;
179 PyTuple_SetItem(pyret, 0, pysocket);
180 PyTuple_SetItem(pyret, 1, pyaddr);
181 return pyret;
184 static PyObject *py_socket_bind(pytalloc_Object *self, PyObject *args)
186 PyObject *pyaddr;
187 int *sock;
188 int status;
189 struct sockaddr addr;
190 socklen_t addrlen;
192 if (!PyArg_ParseTuple(args, "O:bind", &pyaddr)) {
193 return NULL;
196 if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) {
197 return NULL;
200 sock = pytalloc_get_ptr(self);
202 status = swrap_bind(*sock, &addr, addrlen);
203 if (status < 0) {
204 PyErr_SetString(py_socket_error, "Unable to bind");
205 return NULL;
208 Py_RETURN_NONE;
211 static PyObject *py_socket_close(pytalloc_Object *self, PyObject *args)
213 int *sock;
214 int status;
216 sock = pytalloc_get_ptr(self);
218 status = swrap_close(*sock);
219 if (status < 0) {
220 return PyErr_SetFromErrno(py_socket_error);
223 Py_RETURN_NONE;
226 static PyObject *py_socket_connect(pytalloc_Object *self, PyObject *args)
228 int *sock;
229 PyObject *pyaddr;
230 struct sockaddr addr;
231 socklen_t addrlen;
232 int status;
234 if (!PyArg_ParseTuple(args, "O:connect", &pyaddr)) {
235 return NULL;
238 if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) {
239 return NULL;
242 sock = pytalloc_get_ptr(self);
244 status = swrap_connect(*sock, &addr, addrlen);
245 if (status < 0) {
246 PyErr_SetFromErrno(py_socket_error);
247 return NULL;
250 Py_RETURN_NONE;
253 static PyObject *py_socket_connect_ex(pytalloc_Object *self, PyObject *args)
255 int *sock;
256 PyObject *pyaddr;
257 struct sockaddr addr;
258 socklen_t addrlen;
259 int status;
261 if (!PyArg_ParseTuple(args, "O:connect", &pyaddr)) {
262 return NULL;
265 if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) {
266 return NULL;
269 sock = pytalloc_get_ptr(self);
271 status = swrap_connect(*sock, &addr, addrlen);
272 if (status < 0) {
273 return Py_BuildValue("%d", errno);
276 return Py_BuildValue("%d", 0);
279 static PyObject *py_socket_dup(pytalloc_Object *self, PyObject *args)
281 int *sock, *new_sock;
282 PyObject *pysocket;
284 sock = pytalloc_get_ptr(self);
286 new_sock = talloc_zero(NULL, int);
287 if (new_sock == NULL) {
288 return PyErr_NoMemory();
291 *new_sock = swrap_dup(*sock);
292 if (*new_sock < 0) {
293 return PyErr_SetFromErrno(py_socket_error);
296 pysocket = pytalloc_steal(&PySocket, new_sock);
297 if (pysocket == NULL) {
298 return PyErr_NoMemory();
301 return pysocket;
304 static PyObject *py_socket_dup2(pytalloc_Object *self, PyObject *args)
306 int *sock, *new_sock;
307 PyObject *pysocket;
308 int status;
310 if (!PyArg_ParseTuple(args, "O", &pysocket)) {
311 return NULL;
314 PY_CHECK_TYPE(&PySocket, pysocket, return NULL);
316 sock = pytalloc_get_ptr(self);
317 new_sock = pytalloc_get_ptr(pysocket);
319 status = swrap_dup2(*sock, *new_sock);
320 if (status < 0) {
321 return PyErr_SetFromErrno(py_socket_error);
324 Py_RETURN_NONE;
327 static PyObject *py_socket_fileno(pytalloc_Object *self, PyObject *args)
329 PyErr_SetString(py_socket_error, "Not Supported");
330 return NULL;
333 static PyObject *py_socket_getpeername(pytalloc_Object *self, PyObject *args)
335 int *sock;
336 struct sockaddr addr;
337 socklen_t addrlen;
338 int status;
339 PyObject *pyaddr;
341 sock = pytalloc_get_ptr(self);
343 status = swrap_getpeername(*sock, &addr, &addrlen);
344 if (status < 0) {
345 return PyErr_SetFromErrno(py_socket_error);
348 pyaddr = py_socket_addr_to_tuple(&addr, addrlen);
350 return pyaddr;
353 static PyObject *py_socket_getsockname(pytalloc_Object *self, PyObject *args)
355 int *sock;
356 struct sockaddr addr;
357 socklen_t addrlen;
358 int status;
359 PyObject *pyaddr;
361 sock = pytalloc_get_ptr(self);
363 status = swrap_getsockname(*sock, &addr, &addrlen);
364 if (status < 0) {
365 return PyErr_SetFromErrno(py_socket_error);
368 pyaddr = py_socket_addr_to_tuple(&addr, addrlen);
370 return pyaddr;
373 static PyObject *py_socket_getsockopt(pytalloc_Object *self, PyObject *args)
375 int level, optname;
376 int *sock;
377 socklen_t optlen = 0, newlen;
378 int optval;
379 bool is_integer = false;
380 char *buffer;
381 PyObject *pyret;
382 int status;
384 if (!PyArg_ParseTuple(args, "ii|i:getsockopt", &level, &optname, &optlen)) {
385 return NULL;
388 if (optlen == 0) {
389 optlen = sizeof(int);
390 is_integer = true;
393 buffer = talloc_zero_array(NULL, char, optlen);
394 if (buffer == NULL) {
395 return PyErr_NoMemory();
398 sock = pytalloc_get_ptr(self);
400 status = swrap_getsockopt(*sock, level, optname, (void *)buffer, &newlen);
401 if (status < 0) {
402 talloc_free(buffer);
403 return PyErr_SetFromErrno(py_socket_error);
406 if (is_integer) {
407 optval = *(int *)buffer;
408 pyret = PyInt_FromLong(optval);
409 } else {
410 pyret = PyString_FromStringAndSize(buffer, optlen);
413 talloc_free(buffer);
415 return pyret;
418 static PyObject *py_socket_gettimeout(pytalloc_Object *self, PyObject *args)
420 PyErr_SetString(py_socket_error, "Not Supported");
421 return NULL;
424 static PyObject *py_socket_listen(pytalloc_Object *self, PyObject *args)
426 int backlog;
427 int *sock;
428 int status;
430 if (!PyArg_ParseTuple(args, "i:listen", &backlog)) {
431 return NULL;
434 sock = pytalloc_get_ptr(self);
436 status = swrap_listen(*sock, backlog);
437 if (status < 0) {
438 return PyErr_SetFromErrno(py_socket_error);
441 Py_RETURN_NONE;
444 static PyObject *py_socket_makefile(pytalloc_Object *self, PyObject *args)
446 PyErr_SetString(py_socket_error, "Not Supported");
447 return NULL;
450 static PyObject *py_socket_read(pytalloc_Object *self, PyObject *args)
452 int bufsize, len;
453 int *sock;
454 char *buffer;
455 PyObject *pyret;
457 if (!PyArg_ParseTuple(args, "i:read", &bufsize)) {
458 return NULL;
461 buffer = talloc_zero_array(NULL, char, bufsize);
462 if (buffer == NULL) {
463 return PyErr_NoMemory();
466 sock = pytalloc_get_ptr(self);
468 len = swrap_read(*sock, buffer, bufsize);
469 if (len < 0) {
470 return PyErr_SetFromErrno(py_socket_error);
473 pyret = PyString_FromStringAndSize(buffer, len);
475 talloc_free(buffer);
477 return pyret;
480 static PyObject *py_socket_recv(pytalloc_Object *self, PyObject *args)
482 int bufsize, flags, len;
483 int *sock;
484 char *buffer;
485 PyObject *pyret;
487 if (!PyArg_ParseTuple(args, "ii:recv", &bufsize, &flags)) {
488 return NULL;
491 buffer = talloc_zero_array(NULL, char, bufsize);
492 if (buffer == NULL) {
493 return PyErr_NoMemory();
496 sock = pytalloc_get_ptr(self);
498 len = swrap_recv(*sock, buffer, bufsize, flags);
499 if (len < 0) {
500 return PyErr_SetFromErrno(py_socket_error);
503 pyret = PyString_FromStringAndSize(buffer, len);
505 talloc_free(buffer);
507 return pyret;
510 static PyObject *py_socket_recvfrom(pytalloc_Object *self, PyObject *args)
512 int bufsize, flags, len;
513 int *sock;
514 char *buffer;
515 struct sockaddr from;
516 socklen_t fromlen;
517 PyObject *pybuf, *pyaddr, *pyret;
519 if (!PyArg_ParseTuple(args, "ii:recvfrom", &bufsize, &flags)) {
520 return NULL;
523 buffer = talloc_zero_array(NULL, char, bufsize);
524 if (buffer == NULL) {
525 return PyErr_NoMemory();
528 sock = pytalloc_get_ptr(self);
530 fromlen = sizeof(struct sockaddr);
532 len = swrap_recvfrom(*sock, buffer, bufsize, flags, &from, &fromlen);
533 if (len < 0) {
534 talloc_free(buffer);
535 return PyErr_SetFromErrno(py_socket_error);
538 pybuf = PyString_FromStringAndSize(buffer, len);
539 if (pybuf == NULL) {
540 talloc_free(buffer);
541 return PyErr_NoMemory();
544 talloc_free(buffer);
546 pyaddr = py_socket_addr_to_tuple(&from, fromlen);
547 if (pyaddr == NULL) {
548 Py_DECREF(pybuf);
549 return NULL;
552 pyret = PyTuple_New(2);
553 if (pyret == NULL) {
554 Py_DECREF(pybuf);
555 Py_DECREF(pyaddr);
556 return PyErr_NoMemory();
559 PyTuple_SetItem(pyret, 0, pybuf);
560 PyTuple_SetItem(pyret, 1, pyaddr);
562 return pyret;
565 static PyObject *py_socket_send(pytalloc_Object *self, PyObject *args)
567 char *buffer;
568 int len, flags;
569 int *sock;
570 int status;
572 if (!PyArg_ParseTuple(args, "s#i:sendto", &buffer, &len, &flags)) {
573 return NULL;
576 sock = pytalloc_get_ptr(self);
578 status = swrap_send(*sock, buffer, len, flags);
579 if (status < 0) {
580 PyErr_SetFromErrno(py_socket_error);
581 return NULL;
584 Py_RETURN_NONE;
587 static PyObject *py_socket_sendall(pytalloc_Object *self, PyObject *args)
589 char *buffer;
590 int len, flags;
591 int *sock;
592 int status;
594 if (!PyArg_ParseTuple(args, "s#i:sendall", &buffer, &len, &flags)) {
595 return NULL;
598 sock = pytalloc_get_ptr(self);
600 status = swrap_send(*sock, buffer, len, flags);
601 if (status < 0) {
602 PyErr_SetFromErrno(py_socket_error);
603 return NULL;
606 Py_RETURN_NONE;
609 static PyObject *py_socket_sendto(pytalloc_Object *self, PyObject *args)
611 PyObject *pyaddr;
612 char *buffer;
613 int len, flags;
614 int *sock;
615 struct sockaddr addr;
616 socklen_t addrlen;
617 int status;
619 if (!PyArg_ParseTuple(args, "s#iO:sendto", &buffer, &len, &flags, &pyaddr)) {
620 return NULL;
623 if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) {
624 return NULL;
627 sock = pytalloc_get_ptr(self);
629 status = swrap_sendto(*sock, buffer, len, flags, &addr, addrlen);
630 if (status < 0) {
631 PyErr_SetFromErrno(py_socket_error);
632 return NULL;
635 Py_RETURN_NONE;
638 static PyObject *py_socket_setblocking(pytalloc_Object *self, PyObject *args)
640 PyErr_SetString(py_socket_error, "Not Supported");
641 return NULL;
644 static PyObject *py_socket_setsockopt(pytalloc_Object *self, PyObject *args)
646 int level, optname;
647 int *sock;
648 PyObject *pyval;
649 int optval;
650 Py_ssize_t optlen;
651 char *buffer;
652 int status;
654 if (!PyArg_ParseTuple(args, "iiO:getsockopt", &level, &optname, &pyval)) {
655 return NULL;
658 if (PyInt_Check(pyval)) {
659 optval = PyInt_AsLong(pyval);
660 buffer = (char *)&optval;
661 optlen = sizeof(int);
662 } else {
663 PyString_AsStringAndSize(pyval, &buffer, &optlen);
666 sock = pytalloc_get_ptr(self);
668 status = swrap_setsockopt(*sock, level, optname, (void *)buffer, optlen);
669 if (status < 0) {
670 return PyErr_SetFromErrno(py_socket_error);
673 Py_RETURN_NONE;
676 static PyObject *py_socket_settimeout(pytalloc_Object *self, PyObject *args)
678 PyErr_SetString(py_socket_error, "Not Supported");
679 return NULL;
682 static PyObject *py_socket_shutdown(pytalloc_Object *self, PyObject *args)
684 PyErr_SetString(py_socket_error, "Not Supported");
685 return NULL;
688 static PyObject *py_socket_write(pytalloc_Object *self, PyObject *args)
690 char *buffer;
691 int len;
692 int *sock;
693 int status;
695 if (!PyArg_ParseTuple(args, "s#:write", &buffer, &len)) {
696 return NULL;
699 sock = pytalloc_get_ptr(self);
701 status = swrap_send(*sock, buffer, len, 0);
702 if (status < 0) {
703 PyErr_SetFromErrno(py_socket_error);
704 return NULL;
707 Py_RETURN_NONE;
711 static PyMethodDef py_socket_methods[] = {
712 { "accept", (PyCFunction)py_socket_accept, METH_NOARGS,
713 "accept() -> (socket object, address info)\n\n \
714 Wait for an incoming connection." },
715 { "bind", (PyCFunction)py_socket_bind, METH_VARARGS,
716 "bind(address)\n\n \
717 Bind the socket to a local address." },
718 { "close", (PyCFunction)py_socket_close, METH_NOARGS,
719 "close()\n\n \
720 Close the socket." },
721 { "connect", (PyCFunction)py_socket_connect, METH_VARARGS,
722 "connect(address)\n\n \
723 Connect the socket to a remote address." },
724 { "connect_ex", (PyCFunction)py_socket_connect_ex, METH_VARARGS,
725 "connect_ex(address)\n\n \
726 Connect the socket to a remote address." },
727 { "dup", (PyCFunction)py_socket_dup, METH_VARARGS,
728 "dup() -> socket object\n\n \
729 Return a new socket object connected to the same system resource." },
730 { "dup2", (PyCFunction)py_socket_dup2, METH_VARARGS,
731 "dup2(socket object) -> socket object\n\n \
732 Return a new socket object connected to teh same system resource." },
733 { "fileno", (PyCFunction)py_socket_fileno, METH_NOARGS,
734 "fileno() -> file descriptor\n\n \
735 Return socket's file descriptor." },
736 { "getpeername", (PyCFunction)py_socket_getpeername, METH_NOARGS,
737 "getpeername() -> address info\n\n \
738 Return the address of the remote endpoint." },
739 { "getsockname", (PyCFunction)py_socket_getsockname, METH_NOARGS,
740 "getsockname() -> address info\n\n \
741 Return the address of the local endpoing." },
742 { "getsockopt", (PyCFunction)py_socket_getsockopt, METH_VARARGS,
743 "getsockopt(level, option[, buffersize]) -> value\n\n \
744 Get a socket option." },
745 { "gettimeout", (PyCFunction)py_socket_gettimeout, METH_NOARGS,
746 "gettimeout() -> value\n\n \
747 Return the timeout in seconds associated with socket operations." },
748 { "listen", (PyCFunction)py_socket_listen, METH_VARARGS,
749 "listen(backlog)\n\n \
750 Enable a server to accept connections." },
751 { "makefile", (PyCFunction)py_socket_makefile, METH_NOARGS,
752 "makefile() -> file object\n\n \
753 Return a file object associated with the socket." },
754 { "read", (PyCFunction)py_socket_read, METH_VARARGS,
755 "read(buflen) -> data\n\n \
756 Receive data." },
757 { "recv", (PyCFunction)py_socket_recv, METH_VARARGS,
758 "recv(buflen, flags) -> data\n\n \
759 Receive data." },
760 { "recvfrom", (PyCFunction)py_socket_recvfrom, METH_VARARGS,
761 "recvfrom(buflen, flags) -> (data, sender address)\n\n \
762 Receive data and sender's address." },
763 { "send", (PyCFunction)py_socket_send, METH_VARARGS,
764 "send(data, flags)\n\n \
765 Send data." },
766 { "sendall", (PyCFunction)py_socket_sendall, METH_VARARGS,
767 "sendall(data, flags)\n\n \
768 Send data." },
769 { "sendto", (PyCFunction)py_socket_sendto, METH_VARARGS,
770 "sendto(data, flags, addr)\n\n \
771 Send data to a given address." },
772 { "setblocking", (PyCFunction)py_socket_setblocking, METH_VARARGS,
773 "setblocking(flag)\n\n \
774 Set blocking or non-blocking mode of the socket." },
775 { "setsockopt", (PyCFunction)py_socket_setsockopt, METH_VARARGS,
776 "setsockopt(level, option, value)\n\n \
777 Set a socket option." },
778 { "settimeout", (PyCFunction)py_socket_settimeout, METH_VARARGS,
779 "settimeout(value)\n\n \
780 Set a timeout on socket blocking operations." },
781 { "shutdown", (PyCFunction)py_socket_shutdown, METH_VARARGS,
782 "shutdown(how)\n\n \
783 Shut down one or both halves of the connection." },
784 { "write", (PyCFunction)py_socket_write, METH_VARARGS,
785 "write(data)\n\n \
786 Send data." },
787 { NULL },
791 static PyObject *py_socket_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
793 int family, sock_type, protocol;
794 int *sock;
795 PyObject *pysocket;
797 if (!PyArg_ParseTuple(args, "iii:socket", &family, &sock_type, &protocol)) {
798 return NULL;
801 sock = talloc_zero(NULL, int);
802 if (sock == NULL) {
803 return PyErr_NoMemory();
806 *sock = swrap_socket(family, sock_type, protocol);
807 if (*sock < 0) {
808 return PyErr_SetFromErrno(py_socket_error);
811 if ((pysocket = pytalloc_steal(type, sock)) == NULL) {
812 return PyErr_NoMemory();
815 return pysocket;
819 static PyTypeObject PySocket = {
820 .tp_name = "socket_wrapper.socket",
821 .tp_basicsize = sizeof(pytalloc_Object),
822 .tp_flags = Py_TPFLAGS_DEFAULT,
823 .tp_methods = py_socket_methods,
824 .tp_new = py_socket_new,
825 .tp_doc = "socket(family, type, proto) -> socket object\n\n Open a socket of the give type.",
828 static PyObject *py_socket_wrapper_dir(PyObject *self)
830 const char *dir;
832 dir = socket_wrapper_dir();
834 return PyString_FromString(dir);
837 static PyObject *py_socket_wrapper_default_interface(PyObject *self)
839 unsigned int id;
841 id = socket_wrapper_default_iface();
843 return PyInt_FromLong(id);
847 static PyMethodDef py_socket_wrapper_methods[] = {
848 { "dir", (PyCFunction)py_socket_wrapper_dir, METH_NOARGS,
849 "dir() -> path\n\n \
850 Return socket_wrapper directory." },
851 { "default_iface", (PyCFunction)py_socket_wrapper_default_interface, METH_NOARGS,
852 "default_iface() -> id\n\n \
853 Return default interface id." },
854 { NULL },
857 void initsocket_wrapper(void)
859 PyObject *m;
860 char exception_name[] = "socket_wrapper.error";
862 PyTypeObject *talloc_type = pytalloc_GetObjectType();
863 if (talloc_type == NULL) {
864 return;
867 PySocket.tp_base = talloc_type;
868 if (PyType_Ready(&PySocket) < 0) {
869 return;
872 m = Py_InitModule3("socket_wrapper", py_socket_wrapper_methods, "Socket wrapper");
873 if (m == NULL) {
874 return;
877 py_socket_error = PyErr_NewException(exception_name, NULL, NULL);
878 Py_INCREF(py_socket_error);
879 PyModule_AddObject(m, "error", py_socket_error);
881 Py_INCREF(&PySocket);
882 PyModule_AddObject(m, "socket", (PyObject *)&PySocket);