2011-10-14 17:24:16 +11:00
/*
* Copyright ( C ) Amitay Isaacs 2011
*
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
*
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
*
* 3. Neither the name of the author nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ` ` AS IS ' ' AND
* ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT
* LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE .
*
*/
/*
Python interface to socket wrapper library .
Passes all socket communication over unix domain sockets if the environment
variable SOCKET_WRAPPER_DIR is set .
*/
# include <Python.h>
# include <pytalloc.h>
# include "replace/replace.h"
# include "system/network.h"
# include "socket_wrapper.h"
2011-11-19 12:59:01 +01:00
/* There's no Py_ssize_t in 2.4, apparently */
# if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
typedef int Py_ssize_t ;
typedef inquiry lenfunc ;
typedef intargfunc ssizeargfunc ;
# endif
2011-10-14 17:24:16 +11:00
# ifndef Py_RETURN_NONE
# define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
# endif
# ifndef Py_TYPE /* Py_TYPE is only available on Python > 2.6 */
# define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
# endif
# ifndef PY_CHECK_TYPE
# define PY_CHECK_TYPE(type, var, fail) \
if ( ! PyObject_TypeCheck ( var , type ) ) { \
PyErr_Format ( PyExc_TypeError , __location__ " : Expected type '%s' for '%s' of type '%s' " , ( type ) - > tp_name , # var , Py_TYPE ( var ) - > tp_name ) ; \
fail ; \
}
# endif
staticforward PyTypeObject PySocket ;
static PyObject * py_socket_error ;
void initsocket_wrapper ( void ) ;
static PyObject * py_socket_addr_to_tuple ( struct sockaddr * addr , socklen_t len )
{
char host [ 256 ] ;
char service [ 8 ] ;
int status ;
PyObject * pyaddr ;
status = getnameinfo ( addr , len , host , 255 , service , 7 , NI_NUMERICHOST | NI_NUMERICSERV ) ;
if ( status < 0 ) {
PyErr_SetString ( py_socket_error , gai_strerror ( status ) ) ;
return NULL ;
}
pyaddr = PyTuple_New ( 2 ) ;
if ( pyaddr = = NULL ) {
return PyErr_NoMemory ( ) ;
}
PyTuple_SetItem ( pyaddr , 0 , PyString_FromString ( host ) ) ;
PyTuple_SetItem ( pyaddr , 1 , PyInt_FromLong ( atoi ( service ) ) ) ;
return pyaddr ;
}
static bool py_socket_tuple_to_addr ( PyObject * pyaddr , struct sockaddr * addr , socklen_t * len )
{
const char * host ;
char * service ;
in_port_t port ;
struct addrinfo * ainfo ;
int status ;
if ( ! PyTuple_Check ( pyaddr ) ) {
PyErr_SetString ( PyExc_TypeError , " Expected a tuple " ) ;
return false ;
}
if ( ! PyArg_ParseTuple ( pyaddr , " sH " , & host , & port ) ) {
return false ;
}
service = talloc_asprintf ( NULL , " %d " , port ) ;
if ( service = = NULL ) {
PyErr_NoMemory ( ) ;
return false ;
}
status = getaddrinfo ( host , service , NULL , & ainfo ) ;
if ( status < 0 ) {
talloc_free ( service ) ;
PyErr_SetString ( py_socket_error , gai_strerror ( status ) ) ;
return false ;
}
talloc_free ( service ) ;
memcpy ( addr , ainfo - > ai_addr , sizeof ( struct sockaddr ) ) ;
* len = ainfo - > ai_addrlen ;
freeaddrinfo ( ainfo ) ;
return true ;
}
static PyObject * py_socket_accept ( pytalloc_Object * self , PyObject * args )
{
int * sock , * new_sock ;
struct sockaddr addr ;
socklen_t addrlen ;
PyObject * pysocket ;
PyObject * pyaddr ;
PyObject * pyret ;
sock = pytalloc_get_ptr ( self ) ;
new_sock = talloc_zero ( NULL , int ) ;
if ( new_sock = = NULL ) {
return PyErr_NoMemory ( ) ;
}
* new_sock = swrap_accept ( * sock , & addr , & addrlen ) ;
if ( * new_sock < 0 ) {
return PyErr_SetFromErrno ( py_socket_error ) ;
}
if ( ( pysocket = pytalloc_steal ( & PySocket , new_sock ) ) = = NULL ) {
return PyErr_NoMemory ( ) ;
}
pyret = PyTuple_New ( 2 ) ;
if ( pyret = = NULL ) {
Py_DECREF ( pysocket ) ;
return PyErr_NoMemory ( ) ;
}
pyaddr = py_socket_addr_to_tuple ( & addr , addrlen ) ;
if ( pyaddr = = NULL ) {
Py_DECREF ( pysocket ) ;
Py_DECREF ( pysocket ) ;
return NULL ;
}
PyTuple_SetItem ( pyret , 0 , pysocket ) ;
PyTuple_SetItem ( pyret , 1 , pyaddr ) ;
return pyret ;
}
static PyObject * py_socket_bind ( pytalloc_Object * self , PyObject * args )
{
PyObject * pyaddr ;
int * sock ;
int status ;
struct sockaddr addr ;
socklen_t addrlen ;
if ( ! PyArg_ParseTuple ( args , " O:bind " , & pyaddr ) ) {
return NULL ;
}
if ( ! py_socket_tuple_to_addr ( pyaddr , & addr , & addrlen ) ) {
return NULL ;
}
sock = pytalloc_get_ptr ( self ) ;
status = swrap_bind ( * sock , & addr , addrlen ) ;
if ( status < 0 ) {
PyErr_SetString ( py_socket_error , " Unable to bind " ) ;
return NULL ;
}
Py_RETURN_NONE ;
}
static PyObject * py_socket_close ( pytalloc_Object * self , PyObject * args )
{
int * sock ;
int status ;
sock = pytalloc_get_ptr ( self ) ;
status = swrap_close ( * sock ) ;
if ( status < 0 ) {
return PyErr_SetFromErrno ( py_socket_error ) ;
}
Py_RETURN_NONE ;
}
static PyObject * py_socket_connect ( pytalloc_Object * self , PyObject * args )
{
int * sock ;
PyObject * pyaddr ;
struct sockaddr addr ;
socklen_t addrlen ;
int status ;
if ( ! PyArg_ParseTuple ( args , " O:connect " , & pyaddr ) ) {
return NULL ;
}
if ( ! py_socket_tuple_to_addr ( pyaddr , & addr , & addrlen ) ) {
return NULL ;
}
sock = pytalloc_get_ptr ( self ) ;
status = swrap_connect ( * sock , & addr , addrlen ) ;
if ( status < 0 ) {
PyErr_SetFromErrno ( py_socket_error ) ;
return NULL ;
}
Py_RETURN_NONE ;
}
static PyObject * py_socket_connect_ex ( pytalloc_Object * self , PyObject * args )
{
int * sock ;
PyObject * pyaddr ;
struct sockaddr addr ;
socklen_t addrlen ;
int status ;
if ( ! PyArg_ParseTuple ( args , " O:connect " , & pyaddr ) ) {
return NULL ;
}
if ( ! py_socket_tuple_to_addr ( pyaddr , & addr , & addrlen ) ) {
return NULL ;
}
sock = pytalloc_get_ptr ( self ) ;
status = swrap_connect ( * sock , & addr , addrlen ) ;
if ( status < 0 ) {
return Py_BuildValue ( " %d " , errno ) ;
}
return Py_BuildValue ( " %d " , 0 ) ;
}
static PyObject * py_socket_dup ( pytalloc_Object * self , PyObject * args )
{
int * sock , * new_sock ;
PyObject * pysocket ;
sock = pytalloc_get_ptr ( self ) ;
new_sock = talloc_zero ( NULL , int ) ;
if ( new_sock = = NULL ) {
return PyErr_NoMemory ( ) ;
}
* new_sock = swrap_dup ( * sock ) ;
if ( * new_sock < 0 ) {
return PyErr_SetFromErrno ( py_socket_error ) ;
}
pysocket = pytalloc_steal ( & PySocket , new_sock ) ;
if ( pysocket = = NULL ) {
return PyErr_NoMemory ( ) ;
}
return pysocket ;
}
static PyObject * py_socket_dup2 ( pytalloc_Object * self , PyObject * args )
{
int * sock , * new_sock ;
PyObject * pysocket ;
int status ;
if ( ! PyArg_ParseTuple ( args , " O " , & pysocket ) ) {
return NULL ;
}
PY_CHECK_TYPE ( & PySocket , pysocket , return NULL ) ;
sock = pytalloc_get_ptr ( self ) ;
new_sock = pytalloc_get_ptr ( pysocket ) ;
status = swrap_dup2 ( * sock , * new_sock ) ;
if ( status < 0 ) {
return PyErr_SetFromErrno ( py_socket_error ) ;
}
Py_RETURN_NONE ;
}
static PyObject * py_socket_fileno ( pytalloc_Object * self , PyObject * args )
{
PyErr_SetString ( py_socket_error , " Not Supported " ) ;
return NULL ;
}
static PyObject * py_socket_getpeername ( pytalloc_Object * self , PyObject * args )
{
int * sock ;
struct sockaddr addr ;
socklen_t addrlen ;
int status ;
PyObject * pyaddr ;
sock = pytalloc_get_ptr ( self ) ;
status = swrap_getpeername ( * sock , & addr , & addrlen ) ;
if ( status < 0 ) {
return PyErr_SetFromErrno ( py_socket_error ) ;
}
pyaddr = py_socket_addr_to_tuple ( & addr , addrlen ) ;
return pyaddr ;
}
static PyObject * py_socket_getsockname ( pytalloc_Object * self , PyObject * args )
{
int * sock ;
struct sockaddr addr ;
socklen_t addrlen ;
int status ;
PyObject * pyaddr ;
sock = pytalloc_get_ptr ( self ) ;
status = swrap_getsockname ( * sock , & addr , & addrlen ) ;
if ( status < 0 ) {
return PyErr_SetFromErrno ( py_socket_error ) ;
}
pyaddr = py_socket_addr_to_tuple ( & addr , addrlen ) ;
return pyaddr ;
}
static PyObject * py_socket_getsockopt ( pytalloc_Object * self , PyObject * args )
{
int level , optname ;
int * sock ;
2012-02-05 16:42:41 +01:00
socklen_t optlen = 0 , newlen ;
2011-10-14 17:24:16 +11:00
int optval ;
bool is_integer = false ;
char * buffer ;
PyObject * pyret ;
int status ;
if ( ! PyArg_ParseTuple ( args , " ii|i:getsockopt " , & level , & optname , & optlen ) ) {
return NULL ;
}
2012-02-05 16:42:41 +01:00
if ( optlen = = 0 ) {
2011-10-14 17:24:16 +11:00
optlen = sizeof ( int ) ;
is_integer = true ;
}
buffer = talloc_zero_array ( NULL , char , optlen ) ;
if ( buffer = = NULL ) {
return PyErr_NoMemory ( ) ;
}
sock = pytalloc_get_ptr ( self ) ;
status = swrap_getsockopt ( * sock , level , optname , ( void * ) buffer , & newlen ) ;
if ( status < 0 ) {
talloc_free ( buffer ) ;
return PyErr_SetFromErrno ( py_socket_error ) ;
}
if ( is_integer ) {
optval = * ( int * ) buffer ;
pyret = PyInt_FromLong ( optval ) ;
} else {
pyret = PyString_FromStringAndSize ( buffer , optlen ) ;
}
talloc_free ( buffer ) ;
return pyret ;
}
static PyObject * py_socket_gettimeout ( pytalloc_Object * self , PyObject * args )
{
PyErr_SetString ( py_socket_error , " Not Supported " ) ;
return NULL ;
}
static PyObject * py_socket_listen ( pytalloc_Object * self , PyObject * args )
{
int backlog ;
int * sock ;
int status ;
if ( ! PyArg_ParseTuple ( args , " i:listen " , & backlog ) ) {
return NULL ;
}
sock = pytalloc_get_ptr ( self ) ;
status = swrap_listen ( * sock , backlog ) ;
if ( status < 0 ) {
return PyErr_SetFromErrno ( py_socket_error ) ;
}
Py_RETURN_NONE ;
}
static PyObject * py_socket_makefile ( pytalloc_Object * self , PyObject * args )
{
PyErr_SetString ( py_socket_error , " Not Supported " ) ;
return NULL ;
}
static PyObject * py_socket_read ( pytalloc_Object * self , PyObject * args )
{
int bufsize , len ;
int * sock ;
char * buffer ;
PyObject * pyret ;
if ( ! PyArg_ParseTuple ( args , " i:read " , & bufsize ) ) {
return NULL ;
}
buffer = talloc_zero_array ( NULL , char , bufsize ) ;
if ( buffer = = NULL ) {
return PyErr_NoMemory ( ) ;
}
sock = pytalloc_get_ptr ( self ) ;
len = swrap_read ( * sock , buffer , bufsize ) ;
if ( len < 0 ) {
return PyErr_SetFromErrno ( py_socket_error ) ;
}
pyret = PyString_FromStringAndSize ( buffer , len ) ;
talloc_free ( buffer ) ;
return pyret ;
}
static PyObject * py_socket_recv ( pytalloc_Object * self , PyObject * args )
{
int bufsize , flags , len ;
int * sock ;
char * buffer ;
PyObject * pyret ;
if ( ! PyArg_ParseTuple ( args , " ii:recv " , & bufsize , & flags ) ) {
return NULL ;
}
buffer = talloc_zero_array ( NULL , char , bufsize ) ;
if ( buffer = = NULL ) {
return PyErr_NoMemory ( ) ;
}
sock = pytalloc_get_ptr ( self ) ;
len = swrap_recv ( * sock , buffer , bufsize , flags ) ;
if ( len < 0 ) {
return PyErr_SetFromErrno ( py_socket_error ) ;
}
pyret = PyString_FromStringAndSize ( buffer , len ) ;
talloc_free ( buffer ) ;
return pyret ;
}
static PyObject * py_socket_recvfrom ( pytalloc_Object * self , PyObject * args )
{
int bufsize , flags , len ;
int * sock ;
char * buffer ;
struct sockaddr from ;
socklen_t fromlen ;
PyObject * pybuf , * pyaddr , * pyret ;
if ( ! PyArg_ParseTuple ( args , " ii:recvfrom " , & bufsize , & flags ) ) {
return NULL ;
}
buffer = talloc_zero_array ( NULL , char , bufsize ) ;
if ( buffer = = NULL ) {
return PyErr_NoMemory ( ) ;
}
sock = pytalloc_get_ptr ( self ) ;
fromlen = sizeof ( struct sockaddr ) ;
len = swrap_recvfrom ( * sock , buffer , bufsize , flags , & from , & fromlen ) ;
if ( len < 0 ) {
talloc_free ( buffer ) ;
return PyErr_SetFromErrno ( py_socket_error ) ;
}
pybuf = PyString_FromStringAndSize ( buffer , len ) ;
if ( pybuf = = NULL ) {
talloc_free ( buffer ) ;
return PyErr_NoMemory ( ) ;
}
talloc_free ( buffer ) ;
pyaddr = py_socket_addr_to_tuple ( & from , fromlen ) ;
if ( pyaddr = = NULL ) {
Py_DECREF ( pybuf ) ;
return NULL ;
}
pyret = PyTuple_New ( 2 ) ;
if ( pyret = = NULL ) {
Py_DECREF ( pybuf ) ;
Py_DECREF ( pyaddr ) ;
return PyErr_NoMemory ( ) ;
}
PyTuple_SetItem ( pyret , 0 , pybuf ) ;
PyTuple_SetItem ( pyret , 1 , pyaddr ) ;
return pyret ;
}
static PyObject * py_socket_send ( pytalloc_Object * self , PyObject * args )
{
char * buffer ;
int len , flags ;
int * sock ;
int status ;
if ( ! PyArg_ParseTuple ( args , " s#i:sendto " , & buffer , & len , & flags ) ) {
return NULL ;
}
sock = pytalloc_get_ptr ( self ) ;
status = swrap_send ( * sock , buffer , len , flags ) ;
if ( status < 0 ) {
PyErr_SetFromErrno ( py_socket_error ) ;
return NULL ;
}
Py_RETURN_NONE ;
}
static PyObject * py_socket_sendall ( pytalloc_Object * self , PyObject * args )
{
char * buffer ;
int len , flags ;
int * sock ;
int status ;
if ( ! PyArg_ParseTuple ( args , " s#i:sendall " , & buffer , & len , & flags ) ) {
return NULL ;
}
sock = pytalloc_get_ptr ( self ) ;
status = swrap_send ( * sock , buffer , len , flags ) ;
if ( status < 0 ) {
PyErr_SetFromErrno ( py_socket_error ) ;
return NULL ;
}
Py_RETURN_NONE ;
}
static PyObject * py_socket_sendto ( pytalloc_Object * self , PyObject * args )
{
PyObject * pyaddr ;
char * buffer ;
int len , flags ;
int * sock ;
struct sockaddr addr ;
socklen_t addrlen ;
int status ;
if ( ! PyArg_ParseTuple ( args , " s#iO:sendto " , & buffer , & len , & flags , & pyaddr ) ) {
return NULL ;
}
if ( ! py_socket_tuple_to_addr ( pyaddr , & addr , & addrlen ) ) {
return NULL ;
}
sock = pytalloc_get_ptr ( self ) ;
status = swrap_sendto ( * sock , buffer , len , flags , & addr , addrlen ) ;
if ( status < 0 ) {
PyErr_SetFromErrno ( py_socket_error ) ;
return NULL ;
}
Py_RETURN_NONE ;
}
static PyObject * py_socket_setblocking ( pytalloc_Object * self , PyObject * args )
{
PyErr_SetString ( py_socket_error , " Not Supported " ) ;
return NULL ;
}
static PyObject * py_socket_setsockopt ( pytalloc_Object * self , PyObject * args )
{
int level , optname ;
int * sock ;
PyObject * pyval ;
int optval ;
Py_ssize_t optlen ;
char * buffer ;
int status ;
if ( ! PyArg_ParseTuple ( args , " iiO:getsockopt " , & level , & optname , & pyval ) ) {
return NULL ;
}
if ( PyInt_Check ( pyval ) ) {
optval = PyInt_AsLong ( pyval ) ;
buffer = ( char * ) & optval ;
optlen = sizeof ( int ) ;
} else {
PyString_AsStringAndSize ( pyval , & buffer , & optlen ) ;
}
sock = pytalloc_get_ptr ( self ) ;
status = swrap_setsockopt ( * sock , level , optname , ( void * ) buffer , optlen ) ;
if ( status < 0 ) {
return PyErr_SetFromErrno ( py_socket_error ) ;
}
Py_RETURN_NONE ;
}
static PyObject * py_socket_settimeout ( pytalloc_Object * self , PyObject * args )
{
PyErr_SetString ( py_socket_error , " Not Supported " ) ;
return NULL ;
}
static PyObject * py_socket_shutdown ( pytalloc_Object * self , PyObject * args )
{
PyErr_SetString ( py_socket_error , " Not Supported " ) ;
return NULL ;
}
static PyObject * py_socket_write ( pytalloc_Object * self , PyObject * args )
{
char * buffer ;
int len ;
int * sock ;
int status ;
if ( ! PyArg_ParseTuple ( args , " s#:write " , & buffer , & len ) ) {
return NULL ;
}
sock = pytalloc_get_ptr ( self ) ;
status = swrap_send ( * sock , buffer , len , 0 ) ;
if ( status < 0 ) {
PyErr_SetFromErrno ( py_socket_error ) ;
return NULL ;
}
Py_RETURN_NONE ;
}
static PyMethodDef py_socket_methods [ ] = {
{ " accept " , ( PyCFunction ) py_socket_accept , METH_NOARGS ,
" accept() -> (socket object, address info) \n \n \
Wait for an incoming connection . " },
{ " bind " , ( PyCFunction ) py_socket_bind , METH_VARARGS ,
" bind(address) \n \n \
Bind the socket to a local address . " },
{ " close " , ( PyCFunction ) py_socket_close , METH_NOARGS ,
" close() \n \n \
Close the socket . " },
{ " connect " , ( PyCFunction ) py_socket_connect , METH_VARARGS ,
" connect(address) \n \n \
Connect the socket to a remote address . " },
{ " connect_ex " , ( PyCFunction ) py_socket_connect_ex , METH_VARARGS ,
" connect_ex(address) \n \n \
Connect the socket to a remote address . " },
{ " dup " , ( PyCFunction ) py_socket_dup , METH_VARARGS ,
" dup() -> socket object \n \n \
Return a new socket object connected to the same system resource . " },
{ " dup2 " , ( PyCFunction ) py_socket_dup2 , METH_VARARGS ,
" dup2(socket object) -> socket object \n \n \
Return a new socket object connected to teh same system resource . " },
{ " fileno " , ( PyCFunction ) py_socket_fileno , METH_NOARGS ,
" fileno() -> file descriptor \n \n \
Return socket ' s file descriptor . " },
{ " getpeername " , ( PyCFunction ) py_socket_getpeername , METH_NOARGS ,
" getpeername() -> address info \n \n \
Return the address of the remote endpoint . " },
{ " getsockname " , ( PyCFunction ) py_socket_getsockname , METH_NOARGS ,
" getsockname() -> address info \n \n \
Return the address of the local endpoing . " },
{ " getsockopt " , ( PyCFunction ) py_socket_getsockopt , METH_VARARGS ,
" getsockopt(level, option[, buffersize]) -> value \n \n \
Get a socket option . " },
{ " gettimeout " , ( PyCFunction ) py_socket_gettimeout , METH_NOARGS ,
" gettimeout() -> value \n \n \
Return the timeout in seconds associated with socket operations . " },
{ " listen " , ( PyCFunction ) py_socket_listen , METH_VARARGS ,
" listen(backlog) \n \n \
Enable a server to accept connections . " },
{ " makefile " , ( PyCFunction ) py_socket_makefile , METH_NOARGS ,
" makefile() -> file object \n \n \
Return a file object associated with the socket . " },
{ " read " , ( PyCFunction ) py_socket_read , METH_VARARGS ,
" read(buflen) -> data \n \n \
Receive data . " },
{ " recv " , ( PyCFunction ) py_socket_recv , METH_VARARGS ,
" recv(buflen, flags) -> data \n \n \
Receive data . " },
{ " recvfrom " , ( PyCFunction ) py_socket_recvfrom , METH_VARARGS ,
" recvfrom(buflen, flags) -> (data, sender address) \n \n \
Receive data and sender ' s address . " },
{ " send " , ( PyCFunction ) py_socket_send , METH_VARARGS ,
" send(data, flags) \n \n \
Send data . " },
{ " sendall " , ( PyCFunction ) py_socket_sendall , METH_VARARGS ,
" sendall(data, flags) \n \n \
Send data . " },
{ " sendto " , ( PyCFunction ) py_socket_sendto , METH_VARARGS ,
" sendto(data, flags, addr) \n \n \
Send data to a given address . " },
{ " setblocking " , ( PyCFunction ) py_socket_setblocking , METH_VARARGS ,
" setblocking(flag) \n \n \
Set blocking or non - blocking mode of the socket . " },
{ " setsockopt " , ( PyCFunction ) py_socket_setsockopt , METH_VARARGS ,
" setsockopt(level, option, value) \n \n \
Set a socket option . " },
{ " settimeout " , ( PyCFunction ) py_socket_settimeout , METH_VARARGS ,
" settimeout(value) \n \n \
Set a timeout on socket blocking operations . " },
{ " shutdown " , ( PyCFunction ) py_socket_shutdown , METH_VARARGS ,
" shutdown(how) \n \n \
Shut down one or both halves of the connection . " },
{ " write " , ( PyCFunction ) py_socket_write , METH_VARARGS ,
" write(data) \n \n \
Send data . " },
{ NULL } ,
} ;
static PyObject * py_socket_new ( PyTypeObject * type , PyObject * args , PyObject * kwargs )
{
int family , sock_type , protocol ;
int * sock ;
PyObject * pysocket ;
if ( ! PyArg_ParseTuple ( args , " iii:socket " , & family , & sock_type , & protocol ) ) {
return NULL ;
}
sock = talloc_zero ( NULL , int ) ;
if ( sock = = NULL ) {
return PyErr_NoMemory ( ) ;
}
* sock = swrap_socket ( family , sock_type , protocol ) ;
if ( * sock < 0 ) {
return PyErr_SetFromErrno ( py_socket_error ) ;
}
if ( ( pysocket = pytalloc_steal ( type , sock ) ) = = NULL ) {
return PyErr_NoMemory ( ) ;
}
return pysocket ;
}
static PyTypeObject PySocket = {
. tp_name = " socket_wrapper.socket " ,
. tp_basicsize = sizeof ( pytalloc_Object ) ,
. tp_flags = Py_TPFLAGS_DEFAULT ,
. tp_methods = py_socket_methods ,
. tp_new = py_socket_new ,
. tp_doc = " socket(family, type, proto) -> socket object \n \n Open a socket of the give type. " ,
} ;
static PyObject * py_socket_wrapper_dir ( PyObject * self )
{
const char * dir ;
dir = socket_wrapper_dir ( ) ;
return PyString_FromString ( dir ) ;
}
static PyObject * py_socket_wrapper_default_interface ( PyObject * self )
{
unsigned int id ;
id = socket_wrapper_default_iface ( ) ;
return PyInt_FromLong ( id ) ;
}
static PyMethodDef py_socket_wrapper_methods [ ] = {
{ " dir " , ( PyCFunction ) py_socket_wrapper_dir , METH_NOARGS ,
" dir() -> path \n \n \
Return socket_wrapper directory . " },
{ " default_iface " , ( PyCFunction ) py_socket_wrapper_default_interface , METH_NOARGS ,
" default_iface() -> id \n \n \
Return default interface id . " },
{ NULL } ,
} ;
void initsocket_wrapper ( void )
{
PyObject * m ;
char exception_name [ ] = " socket_wrapper.error " ;
PyTypeObject * talloc_type = pytalloc_GetObjectType ( ) ;
if ( talloc_type = = NULL ) {
return ;
}
PySocket . tp_base = talloc_type ;
if ( PyType_Ready ( & PySocket ) < 0 ) {
return ;
}
m = Py_InitModule3 ( " socket_wrapper " , py_socket_wrapper_methods , " Socket wrapper " ) ;
if ( m = = NULL ) {
return ;
}
py_socket_error = PyErr_NewException ( exception_name , NULL , NULL ) ;
Py_INCREF ( py_socket_error ) ;
PyModule_AddObject ( m , " error " , py_socket_error ) ;
Py_INCREF ( & PySocket ) ;
PyModule_AddObject ( m , " socket " , ( PyObject * ) & PySocket ) ;
}