252 lines · 6.2 KB · C
RawDownload
/* Socket module header file */ /* Includes needed for the sockaddr_* symbols below */#ifndef MS_WINDOWS#ifdef __VMS#   include <socket.h># else#   include <sys/socket.h># endif# include <netinet/in.h># if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP)))#  include <netinet/tcp.h># endif #else /* MS_WINDOWS */#if _MSC_VER >= 1300# include <winsock2.h># include <ws2tcpip.h># define HAVE_ADDRINFO# define HAVE_SOCKADDR_STORAGE# define HAVE_GETADDRINFO# define HAVE_GETNAMEINFO# define ENABLE_IPV6#else# include <winsock.h>#endif#endif #ifdef HAVE_SYS_UN_H# include <sys/un.h>#else# undef AF_UNIX#endif #ifdef HAVE_LINUX_NETLINK_H# ifdef HAVE_ASM_TYPES_H#  include <asm/types.h># endif# include <linux/netlink.h>#else#  undef AF_NETLINK#endif #ifdef HAVE_BLUETOOTH_BLUETOOTH_H#include <bluetooth/bluetooth.h>#include <bluetooth/rfcomm.h>#include <bluetooth/l2cap.h>#include <bluetooth/sco.h>#endif #ifdef HAVE_BLUETOOTH_H#include <bluetooth.h>#endif #ifdef HAVE_NETPACKET_PACKET_H# include <sys/ioctl.h># include <net/if.h># include <netpacket/packet.h>#endif #ifndef Py__SOCKET_H#define Py__SOCKET_H#ifdef __cplusplusextern "C" {#endif /* Python module and C API name */#define PySocket_MODULE_NAME	"_socket"#define PySocket_CAPI_NAME	"CAPI" /* Abstract the socket file descriptor type */#ifdef MS_WINDOWStypedef SOCKET SOCKET_T;#	ifdef MS_WIN64#		define SIZEOF_SOCKET_T 8#	else#		define SIZEOF_SOCKET_T 4#	endif#elsetypedef int SOCKET_T;#	define SIZEOF_SOCKET_T SIZEOF_INT#endif /* Socket address */typedef union sock_addr {	struct sockaddr_in in;#ifdef AF_UNIX	struct sockaddr_un un;#endif#ifdef AF_NETLINK	struct sockaddr_nl nl;#endif#ifdef ENABLE_IPV6	struct sockaddr_in6 in6;	struct sockaddr_storage storage;#endif#ifdef HAVE_BLUETOOTH_BLUETOOTH_H	struct sockaddr_l2 bt_l2;	struct sockaddr_rc bt_rc;	struct sockaddr_sco bt_sco;#endif#ifdef HAVE_NETPACKET_PACKET_H	struct sockaddr_ll ll;#endif} sock_addr_t; /* The object holding a socket.  It holds some extra information,   like the address family, which is used to decode socket address   arguments properly. */ typedef struct {	PyObject_HEAD	SOCKET_T sock_fd;	/* Socket file descriptor */	int sock_family;	/* Address family, e.g., AF_INET */	int sock_type;		/* Socket type, e.g., SOCK_STREAM */	int sock_proto;		/* Protocol type, usually 0 */	PyObject *(*errorhandler)(void); /* Error handler; checks					    errno, returns NULL and					    sets a Python exception */	double sock_timeout;		 /* Operation timeout in seconds;					    0.0 means non-blocking */} PySocketSockObject; /* --- C API ----------------------------------------------------*/ /* Short explanation of what this C API export mechanism does   and how it works:     The _ssl module needs access to the type object defined in     the _socket module. Since cross-DLL linking introduces a lot of    problems on many platforms, the "trick" is to wrap the    C API of a module in a struct which then gets exported to    other modules via a PyCObject.     The code in socketmodule.c defines this struct (which currently    only contains the type object reference, but could very    well also include other C APIs needed by other modules)    and exports it as PyCObject via the module dictionary    under the name "CAPI".     Other modules can now include the socketmodule.h file    which defines the needed C APIs to import and set up    a static copy of this struct in the importing module.     After initialization, the importing module can then    access the C APIs from the _socket module by simply    referring to the static struct, e.g.     Load _socket module and its C API; this sets up the global    PySocketModule:    	if (PySocketModule_ImportModuleAndAPI())	    return;      Now use the C API as if it were defined in the using    module:         if (!PyArg_ParseTuple(args, "O!|zz:ssl", 			      PySocketModule.Sock_Type, 			      (PyObject*)&Sock,			      &key_file, &cert_file))	    return NULL;     Support could easily be extended to export more C APIs/symbols    this way. Currently, only the type object is exported,     other candidates would be socket constructors and socket    access functions. */ /* C API for usage by other Python modules */typedef struct {	PyTypeObject *Sock_Type;        PyObject *error;} PySocketModule_APIObject; /* XXX The net effect of the following appears to be to define a function   XXX named PySocketModule_APIObject in _ssl.c.  It's unclear why it isn't   XXX defined there directly.     >>> It's defined here because other modules might also want to use   >>> the C API. */#ifndef PySocket_BUILDING_SOCKET /* --- C API ----------------------------------------------------*/ /* Interfacestructure to C API for other modules.   Call PySocketModule_ImportModuleAndAPI() to initialize this   structure. After that usage is simple:    if (!PyArg_ParseTuple(args, "O!|zz:ssl",                         &PySocketModule.Sock_Type, (PyObject*)&Sock,	 		 &key_file, &cert_file)) 	 return NULL;   ...*/ staticPySocketModule_APIObject PySocketModule; /* You *must* call this before using any of the functions in   PySocketModule and check its outcome; otherwise all accesses will   result in a segfault. Returns 0 on success. */ #ifndef DPRINTF# define DPRINTF if (0) printf#endif staticint PySocketModule_ImportModuleAndAPI(void){	PyObject *mod = 0, *v = 0;	char *apimodule = PySocket_MODULE_NAME;	char *apiname = PySocket_CAPI_NAME;	void *api; 	DPRINTF("Importing the %s C API...\n", apimodule);	mod = PyImport_ImportModule(apimodule);	if (mod == NULL)		goto onError;	DPRINTF(" %s package found\n", apimodule);	v = PyObject_GetAttrString(mod, apiname);	if (v == NULL)		goto onError;	Py_DECREF(mod);	DPRINTF(" API object %s found\n", apiname);	api = PyCObject_AsVoidPtr(v);	if (api == NULL)		goto onError;	Py_DECREF(v);	memcpy(&PySocketModule, api, sizeof(PySocketModule));	DPRINTF(" API object loaded and initialized.\n");	return 0;  onError:	DPRINTF(" not found.\n");	Py_XDECREF(mod);	Py_XDECREF(v);	return -1;} #endif /* !PySocket_BUILDING_SOCKET */ #ifdef __cplusplus}#endif#endif /* !Py__SOCKET_H */