ctdb-tests: Handle interactions with monitor events
[Samba.git] / lib / socket_wrapper / py_socket_wrapper.c
blob411be59d5b14840a6c4a1dfbd659ec87b2f83d2f
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_TYPE /* Py_TYPE is only available on Python > 2.6 */
56 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
57 #endif
59 #ifndef PY_CHECK_TYPE
60 #define PY_CHECK_TYPE(type, var, fail) \
61 if (!PyObject_TypeCheck(var, type)) {\
62 PyErr_Format(PyExc_TypeError, __location__ ": Expected type '%s' for '%s' of type '%s'", (type)->tp_name, #var, Py_TYPE(var)->tp_name); \
63 fail; \
65 #endif
67 staticforward PyTypeObject PySocket;
69 static PyObject *py_socket_error;
71 void initsocket_wrapper(void);
73 static PyObject *py_socket_addr_to_tuple(struct sockaddr *addr, socklen_t len)
75 char host[256];
76 char service[8];
77 int status;
78 PyObject *pyaddr;
80 status = getnameinfo(addr, len, host, 255, service, 7, NI_NUMERICHOST|NI_NUMERICSERV);
81 if (status < 0) {
82 PyErr_SetString(py_socket_error, gai_strerror(status));
83 return NULL;
86 pyaddr = PyTuple_New(2);
87 if (pyaddr == NULL) {
88 return PyErr_NoMemory();
91 PyTuple_SetItem(pyaddr, 0, PyString_FromString(host));
92 PyTuple_SetItem(pyaddr, 1, PyInt_FromLong(atoi(service)));
94 return pyaddr;
97 static bool py_socket_tuple_to_addr(PyObject *pyaddr, struct sockaddr *addr, socklen_t *len)
99 const char *host;
100 char *service;
101 in_port_t port;
102 struct addrinfo *ainfo;
103 int status;
105 if (!PyTuple_Check(pyaddr)) {
106 PyErr_SetString(PyExc_TypeError, "Expected a tuple");
107 return false;
110 if (!PyArg_ParseTuple(pyaddr, "sH", &host, &port)) {
111 return false;
114 service = talloc_asprintf(NULL, "%d", port);
115 if (service == NULL) {
116 PyErr_NoMemory();
117 return false;
120 status = getaddrinfo(host, service, NULL, &ainfo);
121 if (status < 0) {
122 talloc_free(service);
123 PyErr_SetString(py_socket_error, gai_strerror(status));
124 return false;
127 talloc_free(service);
129 memcpy(addr, ainfo->ai_addr, sizeof(struct sockaddr));
130 *len = ainfo->ai_addrlen;
132 freeaddrinfo(ainfo);
133 return true;
137 static PyObject *py_socket_accept(pytalloc_Object *self, PyObject *args)
139 int *sock, *new_sock;
140 struct sockaddr addr;
141 socklen_t addrlen;
142 PyObject *pysocket;
143 PyObject *pyaddr;
144 PyObject *pyret;
146 sock = pytalloc_get_ptr(self);
148 new_sock = talloc_zero(NULL, int);
149 if (new_sock == NULL) {
150 return PyErr_NoMemory();
153 *new_sock = swrap_accept(*sock, &addr, &addrlen);
154 if (*new_sock < 0) {
155 return PyErr_SetFromErrno(py_socket_error);
158 if ((pysocket = pytalloc_steal(&PySocket, new_sock)) == NULL) {
159 return PyErr_NoMemory();
162 pyret = PyTuple_New(2);
163 if (pyret == NULL) {
164 Py_DECREF(pysocket);
165 return PyErr_NoMemory();
168 pyaddr = py_socket_addr_to_tuple(&addr, addrlen);
169 if (pyaddr == NULL) {
170 Py_DECREF(pysocket);
171 Py_DECREF(pysocket);
172 return NULL;
175 PyTuple_SetItem(pyret, 0, pysocket);
176 PyTuple_SetItem(pyret, 1, pyaddr);
177 return pyret;
180 static PyObject *py_socket_bind(pytalloc_Object *self, PyObject *args)
182 PyObject *pyaddr;
183 int *sock;
184 int status;
185 struct sockaddr addr;
186 socklen_t addrlen;
188 if (!PyArg_ParseTuple(args, "O:bind", &pyaddr)) {
189 return NULL;
192 if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) {
193 return NULL;
196 sock = pytalloc_get_ptr(self);
198 status = swrap_bind(*sock, &addr, addrlen);
199 if (status < 0) {
200 PyErr_SetString(py_socket_error, "Unable to bind");
201 return NULL;
204 Py_RETURN_NONE;
207 static PyObject *py_socket_close(pytalloc_Object *self, PyObject *args)
209 int *sock;
210 int status;
212 sock = pytalloc_get_ptr(self);
214 status = swrap_close(*sock);
215 if (status < 0) {
216 return PyErr_SetFromErrno(py_socket_error);
219 Py_RETURN_NONE;
222 static PyObject *py_socket_connect(pytalloc_Object *self, PyObject *args)
224 int *sock;
225 PyObject *pyaddr;
226 struct sockaddr addr;
227 socklen_t addrlen;
228 int status;
230 if (!PyArg_ParseTuple(args, "O:connect", &pyaddr)) {
231 return NULL;
234 if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) {
235 return NULL;
238 sock = pytalloc_get_ptr(self);
240 status = swrap_connect(*sock, &addr, addrlen);
241 if (status < 0) {
242 PyErr_SetFromErrno(py_socket_error);
243 return NULL;
246 Py_RETURN_NONE;
249 static PyObject *py_socket_connect_ex(pytalloc_Object *self, PyObject *args)
251 int *sock;
252 PyObject *pyaddr;
253 struct sockaddr addr;
254 socklen_t addrlen;
255 int status;
257 if (!PyArg_ParseTuple(args, "O:connect", &pyaddr)) {
258 return NULL;
261 if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) {
262 return NULL;
265 sock = pytalloc_get_ptr(self);
267 status = swrap_connect(*sock, &addr, addrlen);
268 if (status < 0) {
269 return Py_BuildValue("%d", errno);
272 return Py_BuildValue("%d", 0);
275 static PyObject *py_socket_dup(pytalloc_Object *self, PyObject *args)
277 int *sock, *new_sock;
278 PyObject *pysocket;
280 sock = pytalloc_get_ptr(self);
282 new_sock = talloc_zero(NULL, int);
283 if (new_sock == NULL) {
284 return PyErr_NoMemory();
287 *new_sock = swrap_dup(*sock);
288 if (*new_sock < 0) {
289 return PyErr_SetFromErrno(py_socket_error);
292 pysocket = pytalloc_steal(&PySocket, new_sock);
293 if (pysocket == NULL) {
294 return PyErr_NoMemory();
297 return pysocket;
300 static PyObject *py_socket_dup2(pytalloc_Object *self, PyObject *args)
302 int *sock, *new_sock;
303 PyObject *pysocket;
304 int status;
306 if (!PyArg_ParseTuple(args, "O", &pysocket)) {
307 return NULL;
310 PY_CHECK_TYPE(&PySocket, pysocket, return NULL);
312 sock = pytalloc_get_ptr(self);
313 new_sock = pytalloc_get_ptr(pysocket);
315 status = swrap_dup2(*sock, *new_sock);
316 if (status < 0) {
317 return PyErr_SetFromErrno(py_socket_error);
320 Py_RETURN_NONE;
323 static PyObject *py_socket_fileno(pytalloc_Object *self, PyObject *args)
325 PyErr_SetString(py_socket_error, "Not Supported");
326 return NULL;
329 static PyObject *py_socket_getpeername(pytalloc_Object *self, PyObject *args)
331 int *sock;
332 struct sockaddr addr;
333 socklen_t addrlen;
334 int status;
335 PyObject *pyaddr;
337 sock = pytalloc_get_ptr(self);
339 status = swrap_getpeername(*sock, &addr, &addrlen);
340 if (status < 0) {
341 return PyErr_SetFromErrno(py_socket_error);
344 pyaddr = py_socket_addr_to_tuple(&addr, addrlen);
346 return pyaddr;
349 static PyObject *py_socket_getsockname(pytalloc_Object *self, PyObject *args)
351 int *sock;
352 struct sockaddr addr;
353 socklen_t addrlen;
354 int status;
355 PyObject *pyaddr;
357 sock = pytalloc_get_ptr(self);
359 status = swrap_getsockname(*sock, &addr, &addrlen);
360 if (status < 0) {
361 return PyErr_SetFromErrno(py_socket_error);
364 pyaddr = py_socket_addr_to_tuple(&addr, addrlen);
366 return pyaddr;
369 static PyObject *py_socket_getsockopt(pytalloc_Object *self, PyObject *args)
371 int level, optname;
372 int *sock;
373 socklen_t optlen = 0, newlen;
374 int optval;
375 bool is_integer = false;
376 char *buffer;
377 PyObject *pyret;
378 int status;
380 if (!PyArg_ParseTuple(args, "ii|i:getsockopt", &level, &optname, &optlen)) {
381 return NULL;
384 if (optlen == 0) {
385 optlen = sizeof(int);
386 is_integer = true;
389 buffer = talloc_zero_array(NULL, char, optlen);
390 if (buffer == NULL) {
391 return PyErr_NoMemory();
394 sock = pytalloc_get_ptr(self);
396 status = swrap_getsockopt(*sock, level, optname, (void *)buffer, &newlen);
397 if (status < 0) {
398 talloc_free(buffer);
399 return PyErr_SetFromErrno(py_socket_error);
402 if (is_integer) {
403 optval = *(int *)buffer;
404 pyret = PyInt_FromLong(optval);
405 } else {
406 pyret = PyString_FromStringAndSize(buffer, optlen);
409 talloc_free(buffer);
411 return pyret;
414 static PyObject *py_socket_gettimeout(pytalloc_Object *self, PyObject *args)
416 PyErr_SetString(py_socket_error, "Not Supported");
417 return NULL;
420 static PyObject *py_socket_listen(pytalloc_Object *self, PyObject *args)
422 int backlog;
423 int *sock;
424 int status;
426 if (!PyArg_ParseTuple(args, "i:listen", &backlog)) {
427 return NULL;
430 sock = pytalloc_get_ptr(self);
432 status = swrap_listen(*sock, backlog);
433 if (status < 0) {
434 return PyErr_SetFromErrno(py_socket_error);
437 Py_RETURN_NONE;
440 static PyObject *py_socket_makefile(pytalloc_Object *self, PyObject *args)
442 PyErr_SetString(py_socket_error, "Not Supported");
443 return NULL;
446 static PyObject *py_socket_read(pytalloc_Object *self, PyObject *args)
448 int bufsize, len;
449 int *sock;
450 char *buffer;
451 PyObject *pyret;
453 if (!PyArg_ParseTuple(args, "i:read", &bufsize)) {
454 return NULL;
457 buffer = talloc_zero_array(NULL, char, bufsize);
458 if (buffer == NULL) {
459 return PyErr_NoMemory();
462 sock = pytalloc_get_ptr(self);
464 len = swrap_read(*sock, buffer, bufsize);
465 if (len < 0) {
466 return PyErr_SetFromErrno(py_socket_error);
469 pyret = PyString_FromStringAndSize(buffer, len);
471 talloc_free(buffer);
473 return pyret;
476 static PyObject *py_socket_recv(pytalloc_Object *self, PyObject *args)
478 int bufsize, flags, len;
479 int *sock;
480 char *buffer;
481 PyObject *pyret;
483 if (!PyArg_ParseTuple(args, "ii:recv", &bufsize, &flags)) {
484 return NULL;
487 buffer = talloc_zero_array(NULL, char, bufsize);
488 if (buffer == NULL) {
489 return PyErr_NoMemory();
492 sock = pytalloc_get_ptr(self);
494 len = swrap_recv(*sock, buffer, bufsize, flags);
495 if (len < 0) {
496 return PyErr_SetFromErrno(py_socket_error);
499 pyret = PyString_FromStringAndSize(buffer, len);
501 talloc_free(buffer);
503 return pyret;
506 static PyObject *py_socket_recvfrom(pytalloc_Object *self, PyObject *args)
508 int bufsize, flags, len;
509 int *sock;
510 char *buffer;
511 struct sockaddr from;
512 socklen_t fromlen;
513 PyObject *pybuf, *pyaddr, *pyret;
515 if (!PyArg_ParseTuple(args, "ii:recvfrom", &bufsize, &flags)) {
516 return NULL;
519 buffer = talloc_zero_array(NULL, char, bufsize);
520 if (buffer == NULL) {
521 return PyErr_NoMemory();
524 sock = pytalloc_get_ptr(self);
526 fromlen = sizeof(struct sockaddr);
528 len = swrap_recvfrom(*sock, buffer, bufsize, flags, &from, &fromlen);
529 if (len < 0) {
530 talloc_free(buffer);
531 return PyErr_SetFromErrno(py_socket_error);
534 pybuf = PyString_FromStringAndSize(buffer, len);
535 if (pybuf == NULL) {
536 talloc_free(buffer);
537 return PyErr_NoMemory();
540 talloc_free(buffer);
542 pyaddr = py_socket_addr_to_tuple(&from, fromlen);
543 if (pyaddr == NULL) {
544 Py_DECREF(pybuf);
545 return NULL;
548 pyret = PyTuple_New(2);
549 if (pyret == NULL) {
550 Py_DECREF(pybuf);
551 Py_DECREF(pyaddr);
552 return PyErr_NoMemory();
555 PyTuple_SetItem(pyret, 0, pybuf);
556 PyTuple_SetItem(pyret, 1, pyaddr);
558 return pyret;
561 static PyObject *py_socket_send(pytalloc_Object *self, PyObject *args)
563 char *buffer;
564 int len, flags;
565 int *sock;
566 int status;
568 if (!PyArg_ParseTuple(args, "s#i:sendto", &buffer, &len, &flags)) {
569 return NULL;
572 sock = pytalloc_get_ptr(self);
574 status = swrap_send(*sock, buffer, len, flags);
575 if (status < 0) {
576 PyErr_SetFromErrno(py_socket_error);
577 return NULL;
580 Py_RETURN_NONE;
583 static PyObject *py_socket_sendall(pytalloc_Object *self, PyObject *args)
585 char *buffer;
586 int len, flags;
587 int *sock;
588 int status;
590 if (!PyArg_ParseTuple(args, "s#i:sendall", &buffer, &len, &flags)) {
591 return NULL;
594 sock = pytalloc_get_ptr(self);
596 status = swrap_send(*sock, buffer, len, flags);
597 if (status < 0) {
598 PyErr_SetFromErrno(py_socket_error);
599 return NULL;
602 Py_RETURN_NONE;
605 static PyObject *py_socket_sendto(pytalloc_Object *self, PyObject *args)
607 PyObject *pyaddr;
608 char *buffer;
609 int len, flags;
610 int *sock;
611 struct sockaddr addr;
612 socklen_t addrlen;
613 int status;
615 if (!PyArg_ParseTuple(args, "s#iO:sendto", &buffer, &len, &flags, &pyaddr)) {
616 return NULL;
619 if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) {
620 return NULL;
623 sock = pytalloc_get_ptr(self);
625 status = swrap_sendto(*sock, buffer, len, flags, &addr, addrlen);
626 if (status < 0) {
627 PyErr_SetFromErrno(py_socket_error);
628 return NULL;
631 Py_RETURN_NONE;
634 static PyObject *py_socket_setblocking(pytalloc_Object *self, PyObject *args)
636 PyErr_SetString(py_socket_error, "Not Supported");
637 return NULL;
640 static PyObject *py_socket_setsockopt(pytalloc_Object *self, PyObject *args)
642 int level, optname;
643 int *sock;
644 PyObject *pyval;
645 int optval;
646 Py_ssize_t optlen;
647 char *buffer;
648 int status;
650 if (!PyArg_ParseTuple(args, "iiO:getsockopt", &level, &optname, &pyval)) {
651 return NULL;
654 if (PyInt_Check(pyval)) {
655 optval = PyInt_AsLong(pyval);
656 buffer = (char *)&optval;
657 optlen = sizeof(int);
658 } else {
659 PyString_AsStringAndSize(pyval, &buffer, &optlen);
662 sock = pytalloc_get_ptr(self);
664 status = swrap_setsockopt(*sock, level, optname, (void *)buffer, optlen);
665 if (status < 0) {
666 return PyErr_SetFromErrno(py_socket_error);
669 Py_RETURN_NONE;
672 static PyObject *py_socket_settimeout(pytalloc_Object *self, PyObject *args)
674 PyErr_SetString(py_socket_error, "Not Supported");
675 return NULL;
678 static PyObject *py_socket_shutdown(pytalloc_Object *self, PyObject *args)
680 PyErr_SetString(py_socket_error, "Not Supported");
681 return NULL;
684 static PyObject *py_socket_write(pytalloc_Object *self, PyObject *args)
686 char *buffer;
687 int len;
688 int *sock;
689 int status;
691 if (!PyArg_ParseTuple(args, "s#:write", &buffer, &len)) {
692 return NULL;
695 sock = pytalloc_get_ptr(self);
697 status = swrap_send(*sock, buffer, len, 0);
698 if (status < 0) {
699 PyErr_SetFromErrno(py_socket_error);
700 return NULL;
703 Py_RETURN_NONE;
707 static PyMethodDef py_socket_methods[] = {
708 { "accept", (PyCFunction)py_socket_accept, METH_NOARGS,
709 "accept() -> (socket object, address info)\n\n \
710 Wait for an incoming connection." },
711 { "bind", (PyCFunction)py_socket_bind, METH_VARARGS,
712 "bind(address)\n\n \
713 Bind the socket to a local address." },
714 { "close", (PyCFunction)py_socket_close, METH_NOARGS,
715 "close()\n\n \
716 Close the socket." },
717 { "connect", (PyCFunction)py_socket_connect, METH_VARARGS,
718 "connect(address)\n\n \
719 Connect the socket to a remote address." },
720 { "connect_ex", (PyCFunction)py_socket_connect_ex, METH_VARARGS,
721 "connect_ex(address)\n\n \
722 Connect the socket to a remote address." },
723 { "dup", (PyCFunction)py_socket_dup, METH_VARARGS,
724 "dup() -> socket object\n\n \
725 Return a new socket object connected to the same system resource." },
726 { "dup2", (PyCFunction)py_socket_dup2, METH_VARARGS,
727 "dup2(socket object) -> socket object\n\n \
728 Return a new socket object connected to teh same system resource." },
729 { "fileno", (PyCFunction)py_socket_fileno, METH_NOARGS,
730 "fileno() -> file descriptor\n\n \
731 Return socket's file descriptor." },
732 { "getpeername", (PyCFunction)py_socket_getpeername, METH_NOARGS,
733 "getpeername() -> address info\n\n \
734 Return the address of the remote endpoint." },
735 { "getsockname", (PyCFunction)py_socket_getsockname, METH_NOARGS,
736 "getsockname() -> address info\n\n \
737 Return the address of the local endpoing." },
738 { "getsockopt", (PyCFunction)py_socket_getsockopt, METH_VARARGS,
739 "getsockopt(level, option[, buffersize]) -> value\n\n \
740 Get a socket option." },
741 { "gettimeout", (PyCFunction)py_socket_gettimeout, METH_NOARGS,
742 "gettimeout() -> value\n\n \
743 Return the timeout in seconds associated with socket operations." },
744 { "listen", (PyCFunction)py_socket_listen, METH_VARARGS,
745 "listen(backlog)\n\n \
746 Enable a server to accept connections." },
747 { "makefile", (PyCFunction)py_socket_makefile, METH_NOARGS,
748 "makefile() -> file object\n\n \
749 Return a file object associated with the socket." },
750 { "read", (PyCFunction)py_socket_read, METH_VARARGS,
751 "read(buflen) -> data\n\n \
752 Receive data." },
753 { "recv", (PyCFunction)py_socket_recv, METH_VARARGS,
754 "recv(buflen, flags) -> data\n\n \
755 Receive data." },
756 { "recvfrom", (PyCFunction)py_socket_recvfrom, METH_VARARGS,
757 "recvfrom(buflen, flags) -> (data, sender address)\n\n \
758 Receive data and sender's address." },
759 { "send", (PyCFunction)py_socket_send, METH_VARARGS,
760 "send(data, flags)\n\n \
761 Send data." },
762 { "sendall", (PyCFunction)py_socket_sendall, METH_VARARGS,
763 "sendall(data, flags)\n\n \
764 Send data." },
765 { "sendto", (PyCFunction)py_socket_sendto, METH_VARARGS,
766 "sendto(data, flags, addr)\n\n \
767 Send data to a given address." },
768 { "setblocking", (PyCFunction)py_socket_setblocking, METH_VARARGS,
769 "setblocking(flag)\n\n \
770 Set blocking or non-blocking mode of the socket." },
771 { "setsockopt", (PyCFunction)py_socket_setsockopt, METH_VARARGS,
772 "setsockopt(level, option, value)\n\n \
773 Set a socket option." },
774 { "settimeout", (PyCFunction)py_socket_settimeout, METH_VARARGS,
775 "settimeout(value)\n\n \
776 Set a timeout on socket blocking operations." },
777 { "shutdown", (PyCFunction)py_socket_shutdown, METH_VARARGS,
778 "shutdown(how)\n\n \
779 Shut down one or both halves of the connection." },
780 { "write", (PyCFunction)py_socket_write, METH_VARARGS,
781 "write(data)\n\n \
782 Send data." },
783 { NULL },
787 static PyObject *py_socket_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
789 int family, sock_type, protocol;
790 int *sock;
791 PyObject *pysocket;
793 if (!PyArg_ParseTuple(args, "iii:socket", &family, &sock_type, &protocol)) {
794 return NULL;
797 sock = talloc_zero(NULL, int);
798 if (sock == NULL) {
799 return PyErr_NoMemory();
802 *sock = swrap_socket(family, sock_type, protocol);
803 if (*sock < 0) {
804 return PyErr_SetFromErrno(py_socket_error);
807 if ((pysocket = pytalloc_steal(type, sock)) == NULL) {
808 return PyErr_NoMemory();
811 return pysocket;
815 static PyTypeObject PySocket = {
816 .tp_name = "socket_wrapper.socket",
817 .tp_basicsize = sizeof(pytalloc_Object),
818 .tp_flags = Py_TPFLAGS_DEFAULT,
819 .tp_methods = py_socket_methods,
820 .tp_new = py_socket_new,
821 .tp_doc = "socket(family, type, proto) -> socket object\n\n Open a socket of the give type.",
824 static PyObject *py_socket_wrapper_dir(PyObject *self)
826 const char *dir;
828 dir = socket_wrapper_dir();
830 return PyString_FromString(dir);
833 static PyObject *py_socket_wrapper_default_interface(PyObject *self)
835 unsigned int id;
837 id = socket_wrapper_default_iface();
839 return PyInt_FromLong(id);
843 static PyMethodDef py_socket_wrapper_methods[] = {
844 { "dir", (PyCFunction)py_socket_wrapper_dir, METH_NOARGS,
845 "dir() -> path\n\n \
846 Return socket_wrapper directory." },
847 { "default_iface", (PyCFunction)py_socket_wrapper_default_interface, METH_NOARGS,
848 "default_iface() -> id\n\n \
849 Return default interface id." },
850 { NULL },
853 void initsocket_wrapper(void)
855 PyObject *m;
856 char exception_name[] = "socket_wrapper.error";
858 PyTypeObject *talloc_type = pytalloc_GetObjectType();
859 if (talloc_type == NULL) {
860 return;
863 PySocket.tp_base = talloc_type;
864 if (PyType_Ready(&PySocket) < 0) {
865 return;
868 m = Py_InitModule3("socket_wrapper", py_socket_wrapper_methods, "Socket wrapper");
869 if (m == NULL) {
870 return;
873 py_socket_error = PyErr_NewException(exception_name, NULL, NULL);
874 Py_INCREF(py_socket_error);
875 PyModule_AddObject(m, "error", py_socket_error);
877 Py_INCREF(&PySocket);
878 PyModule_AddObject(m, "socket", (PyObject *)&PySocket);