PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/rpython/rlib/_rsocket_rffi.py

https://bitbucket.org/pypy/pypy/
Python | 691 lines | 579 code | 78 blank | 34 comment | 55 complexity | cdb6137375759bf299d4e1235b85ba11 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from rpython.rtyper.lltypesystem import rffi
  2. from rpython.rtyper.lltypesystem import lltype
  3. from rpython.rtyper.tool import rffi_platform as platform
  4. from rpython.rtyper.lltypesystem.rffi import CCHARP
  5. from rpython.translator.tool.cbuild import ExternalCompilationInfo
  6. from rpython.translator.platform import platform as target_platform
  7. from rpython.rlib.rarithmetic import intmask, r_uint
  8. import os,sys
  9. _POSIX = os.name == "posix"
  10. _WIN32 = sys.platform == "win32"
  11. _MSVC = target_platform.name == "msvc"
  12. _MINGW = target_platform.name == "mingw32"
  13. _SOLARIS = sys.platform == "sunos5"
  14. _MACOSX = sys.platform == "darwin"
  15. _HAS_AF_PACKET = sys.platform.startswith('linux') # only Linux for now
  16. if _POSIX:
  17. includes = ('sys/types.h',
  18. 'sys/socket.h',
  19. 'sys/un.h',
  20. 'sys/poll.h',
  21. 'sys/select.h',
  22. 'sys/types.h',
  23. 'netinet/in.h',
  24. 'netinet/tcp.h',
  25. 'unistd.h',
  26. 'fcntl.h',
  27. 'stdio.h',
  28. 'netdb.h',
  29. 'arpa/inet.h',
  30. 'stdint.h',
  31. 'errno.h',
  32. )
  33. if _HAS_AF_PACKET:
  34. includes += ('netpacket/packet.h',
  35. 'sys/ioctl.h',
  36. 'net/if.h')
  37. cond_includes = [('AF_NETLINK', 'linux/netlink.h')]
  38. libraries = ()
  39. calling_conv = 'c'
  40. HEADER = ''.join(['#include <%s>\n' % filename for filename in includes])
  41. COND_HEADER = ''.join(['#ifdef %s\n#include <%s>\n#endif\n' % cond_include
  42. for cond_include in cond_includes])
  43. if _SOLARIS:
  44. libraries = libraries + ('socket', 'nsl')
  45. if _WIN32:
  46. includes = ()
  47. libraries = ('ws2_32',)
  48. calling_conv = 'win'
  49. header_lines = [
  50. '#include <WinSock2.h>',
  51. '#include <WS2tcpip.h>',
  52. # winsock2 defines AF_UNIX, but not sockaddr_un
  53. '#undef AF_UNIX',
  54. ]
  55. if _MSVC:
  56. header_lines.extend([
  57. '#include <Mstcpip.h>',
  58. # these types do not exist on microsoft compilers
  59. 'typedef int ssize_t;',
  60. 'typedef unsigned __int16 uint16_t;',
  61. 'typedef unsigned __int32 uint32_t;',
  62. ])
  63. else: # MINGW
  64. includes = ('stdint.h',)
  65. header_lines.extend([
  66. '''\
  67. #ifndef _WIN32_WINNT
  68. #define _WIN32_WINNT 0x0501
  69. #endif''',
  70. '#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)',
  71. '#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)',
  72. '#define RCVALL_OFF 0',
  73. '#define RCVALL_ON 1',
  74. '#define RCVALL_SOCKETLEVELONLY 2',
  75. '''\
  76. #ifndef __MINGW32__
  77. struct tcp_keepalive {
  78. u_long onoff;
  79. u_long keepalivetime;
  80. u_long keepaliveinterval;
  81. };
  82. #endif
  83. '''
  84. ])
  85. HEADER = '\n'.join(header_lines)
  86. COND_HEADER = ''
  87. constants = {}
  88. eci = ExternalCompilationInfo(
  89. post_include_bits = [HEADER, COND_HEADER],
  90. includes = includes,
  91. libraries = libraries,
  92. )
  93. class CConfig:
  94. _compilation_info_ = eci
  95. # constants
  96. linux = platform.Defined('linux')
  97. WIN32 = platform.Defined('_WIN32')
  98. O_RDONLY = platform.DefinedConstantInteger('O_RDONLY')
  99. O_WRONLY = platform.DefinedConstantInteger('O_WRONLY')
  100. O_RDWR = platform.DefinedConstantInteger('O_RDWR')
  101. O_NONBLOCK = platform.DefinedConstantInteger('O_NONBLOCK')
  102. F_GETFL = platform.DefinedConstantInteger('F_GETFL')
  103. F_SETFL = platform.DefinedConstantInteger('F_SETFL')
  104. FIONBIO = platform.DefinedConstantInteger('FIONBIO')
  105. INVALID_SOCKET = platform.DefinedConstantInteger('INVALID_SOCKET')
  106. INET_ADDRSTRLEN = platform.DefinedConstantInteger('INET_ADDRSTRLEN')
  107. INET6_ADDRSTRLEN= platform.DefinedConstantInteger('INET6_ADDRSTRLEN')
  108. EINTR = platform.DefinedConstantInteger('EINTR')
  109. WSAEINTR = platform.DefinedConstantInteger('WSAEINTR')
  110. EINPROGRESS = platform.DefinedConstantInteger('EINPROGRESS')
  111. WSAEINPROGRESS = platform.DefinedConstantInteger('WSAEINPROGRESS')
  112. EWOULDBLOCK = platform.DefinedConstantInteger('EWOULDBLOCK')
  113. WSAEWOULDBLOCK = platform.DefinedConstantInteger('WSAEWOULDBLOCK')
  114. EAFNOSUPPORT = platform.DefinedConstantInteger('EAFNOSUPPORT')
  115. WSAEAFNOSUPPORT = platform.DefinedConstantInteger('WSAEAFNOSUPPORT')
  116. EISCONN = platform.DefinedConstantInteger('EISCONN')
  117. WSAEISCONN = platform.DefinedConstantInteger('WSAEISCONN')
  118. constant_names = '''
  119. AF_AAL5 AF_APPLETALK AF_ASH AF_ATMPVC AF_ATMSVC AF_AX25 AF_BLUETOOTH AF_BRIDGE
  120. AD_DECnet AF_ECONET AF_INET AF_INET6 AF_IPX AF_IRDA AF_KEY AF_LLC AF_NETBEUI
  121. AF_NETLINK AF_NETROM AF_PACKET AF_PPPOX AF_ROSE AF_ROUTE AF_SECURITY AF_SNA
  122. AF_UNIX AF_WANPIPE AF_X25 AF_UNSPEC
  123. AI_ADDRCONFIG AI_ALL AI_CANONNAME AI_DEFAULT AI_MASK AI_NUMERICHOST
  124. AI_NUMERICSERV AI_PASSIVE AI_V4MAPPED AI_V4MAPPED_CFG
  125. BTPROTO_L2CAP BTPROTO_SCO BTPROTO_RFCOMM
  126. EAI_ADDRFAMILY EAI_AGAIN EAI_BADFLAGS EAI_BADHINTS EAI_FAIL EAI_FAMILY EAI_MAX
  127. EAI_MEMORY EAI_NODATA EAI_NONAME EAI_OVERFLOW EAI_PROTOCOL EAI_SERVICE
  128. EAI_SOCKTYPE EAI_SYSTEM
  129. IPPROTO_AH IPPROTO_BIP IPPROTO_DSTOPTS IPPROTO_EGP IPPROTO_EON IPPROTO_ESP
  130. IPPROTO_FRAGMENT IPPROTO_GGP IPPROTO_GRE IPPROTO_HELLO IPPROTO_HOPOPTS
  131. IPPROTO_ICMPV6 IPPROTO_IDP IPPROTO_IGMP IPPROTO_IPCOMP IPPROTO_IPIP
  132. IPPROTO_IPV4 IPPROTO_IPV6 IPPROTO_MAX IPPROTO_MOBILE IPPROTO_ND IPPROTO_NONE
  133. IPPROTO_PIM IPPROTO_PUP IPPROTO_ROUTING IPPROTO_RSVP IPPROTO_TCP IPPROTO_TP
  134. IPPROTO_VRRP IPPROTO_XTP
  135. IPV6_CHECKSUM IPV6_DONTFRAG IPV6_DSTOPTS IPV6_HOPLIMIT IPV6_HOPOPTS
  136. IPV6_JOIN_GROUP IPV6_LEAVE_GROUP IPV6_MULTICAST_HOPS IPV6_MULTICAST_IF
  137. IPV6_MULTICAST_LOOP IPV6_NEXTHOP IPV6_PATHMTU IPV6_PKTINFO IPV6_RECVDSTOPTS
  138. IPV6_RECVHOPLIMIT IPV6_RECVHOPOPTS IPV6_RECVPATHMTU IPV6_RECVPKTINFO
  139. IPV6_RECVRTHDR IPV6_RECVTCLASS IPV6_RTHDR IPV6_RTHDRDSTOPTS IPV6_RTHDR_TYPE_0
  140. IPV6_TCLASS IPV6_UNICAST_HOPS IPV6_USE_MIN_MTU IPV6_V6ONLY
  141. IP_ADD_MEMBERSHIP IP_DEFAULT_MULTICAST_LOOP IP_DEFAULT_MULTICAST_TTL
  142. IP_DROP_MEMBERSHIP IP_HDRINCL IP_MAX_MEMBERSHIPS IP_MULTICAST_IF
  143. IP_MULTICAST_LOOP IP_MULTICAST_TTL IP_OPTIONS IP_RECVDSTADDR IP_RECVOPTS
  144. IP_RECVRETOPTS IP_RETOPTS IP_TOS IP_TTL
  145. MSG_BTAG MSG_ETAG MSG_CTRUNC MSG_DONTROUTE MSG_DONTWAIT MSG_EOR MSG_OOB
  146. MSG_PEEK MSG_TRUNC MSG_WAITALL
  147. NI_DGRAM NI_MAXHOST NI_MAXSERV NI_NAMEREQD NI_NOFQDN NI_NUMERICHOST
  148. NI_NUMERICSERV
  149. NETLINK_ROUTE NETLINK_SKIP NETLINK_W1 NETLINK_USERSOCK NETLINK_FIREWALL
  150. NETLINK_TCPDIAG NETLINK_NFLOG NETLINK_XFRM NETLINK_ARPD NETLINK_ROUTE6
  151. NETLINK_IP6_FW NETLINK_DNRTMSG NETLINK_TAPBASE
  152. PACKET_HOST PACKET_BROADCAST PACKET_MULTICAST PACKET_OTHERHOST PACKET_OUTGOING
  153. PACKET_LOOPBACK PACKET_FASTROUTE
  154. SOCK_DGRAM SOCK_RAW SOCK_RDM SOCK_SEQPACKET SOCK_STREAM
  155. SOL_SOCKET SOL_IPX SOL_AX25 SOL_ATALK SOL_NETROM SOL_ROSE
  156. SO_ACCEPTCONN SO_BROADCAST SO_DEBUG SO_DONTROUTE SO_ERROR SO_EXCLUSIVEADDRUSE
  157. SO_KEEPALIVE SO_LINGER SO_OOBINLINE SO_RCVBUF SO_RCVLOWAT SO_RCVTIMEO
  158. SO_REUSEADDR SO_REUSEPORT SO_SNDBUF SO_SNDLOWAT SO_SNDTIMEO SO_TYPE
  159. SO_USELOOPBACK
  160. TCP_CORK TCP_DEFER_ACCEPT TCP_INFO TCP_KEEPCNT TCP_KEEPIDLE TCP_KEEPINTVL
  161. TCP_LINGER2 TCP_MAXSEG TCP_NODELAY TCP_QUICKACK TCP_SYNCNT TCP_WINDOW_CLAMP
  162. IPX_TYPE
  163. POLLIN POLLPRI POLLOUT POLLERR POLLHUP POLLNVAL
  164. POLLRDNORM POLLRDBAND POLLWRNORM POLLWEBAND POLLMSG
  165. FD_READ FD_WRITE FD_ACCEPT FD_CONNECT FD_CLOSE
  166. WSA_WAIT_TIMEOUT WSA_WAIT_FAILED INFINITE
  167. FD_CONNECT_BIT FD_CLOSE_BIT
  168. WSA_IO_PENDING WSA_IO_INCOMPLETE WSA_INVALID_HANDLE
  169. WSA_INVALID_PARAMETER WSA_NOT_ENOUGH_MEMORY WSA_OPERATION_ABORTED
  170. SIO_RCVALL SIO_KEEPALIVE_VALS
  171. SIOCGIFNAME SIOCGIFINDEX
  172. '''.split()
  173. for name in constant_names:
  174. setattr(CConfig, name, platform.DefinedConstantInteger(name))
  175. if _WIN32:
  176. # some SDKs define these values with an enum, #ifdef won't work
  177. for name in ('RCVALL_ON', 'RCVALL_OFF', 'RCVALL_SOCKETLEVELONLY'):
  178. setattr(CConfig, name, platform.ConstantInteger(name))
  179. constant_names.append(name)
  180. constants["BDADDR_ANY"] = "00:00:00:00:00:00"
  181. constants["BDADDR_LOCAL"] = "00:00:00:FF:FF:FF"
  182. constants_w_defaults = [('SOL_IP', 0),
  183. ('SOL_TCP', 6),
  184. ('SOL_UDP', 17),
  185. ('SOMAXCONN', 5),
  186. ('IPPROTO_IP', 6),
  187. ('IPPROTO_ICMP', 1),
  188. ('IPPROTO_TCP', 6),
  189. ('IPPROTO_UDP', 17),
  190. ('IPPROTO_RAW', 255),
  191. ('IPPORT_RESERVED', 1024),
  192. ('IPPORT_USERRESERVED', 5000),
  193. ('INADDR_ANY', 0x00000000),
  194. ('INADDR_BROADCAST', 0xffffffff),
  195. ('INADDR_LOOPBACK', 0x7F000001),
  196. ('INADDR_UNSPEC_GROUP', 0xe0000000),
  197. ('INADDR_ALLHOSTS_GROUP', 0xe0000001),
  198. ('INADDR_MAX_LOCAL_GROUP', 0xe00000ff),
  199. ('INADDR_NONE', 0xffffffff),
  200. ('SHUT_RD', 0),
  201. ('SHUT_WR', 1),
  202. ('SHUT_RDWR', 2),
  203. ('POLLIN', 1),
  204. ('POLLPRI', 2),
  205. ('POLLOUT', 4),
  206. ('POLLERR', 8),
  207. ('POLLHUP', 16),
  208. ('FD_SETSIZE', 64),
  209. ]
  210. for name, default in constants_w_defaults:
  211. setattr(CConfig, name, platform.DefinedConstantInteger(name))
  212. # types
  213. if _MSVC:
  214. socketfd_type = rffi.UINT
  215. else:
  216. socketfd_type = rffi.INT
  217. CConfig.uint16_t = platform.SimpleType('uint16_t', rffi.USHORT)
  218. CConfig.uint32_t = platform.SimpleType('uint32_t', rffi.UINT)
  219. CConfig.size_t = platform.SimpleType('size_t', rffi.INT)
  220. CConfig.ssize_t = platform.SimpleType('ssize_t', rffi.INT)
  221. CConfig.socklen_t = platform.SimpleType('socklen_t', rffi.INT)
  222. sockaddr_ptr = lltype.Ptr(lltype.ForwardReference())
  223. addrinfo_ptr = lltype.Ptr(lltype.ForwardReference())
  224. # struct types
  225. CConfig.sockaddr = platform.Struct('struct sockaddr',
  226. [('sa_family', rffi.INT),
  227. ('sa_data', rffi.CFixedArray(rffi.CHAR, 1))])
  228. CConfig.in_addr = platform.Struct('struct in_addr',
  229. [('s_addr', rffi.UINT)])
  230. CConfig.in6_addr = platform.Struct('struct in6_addr',
  231. [('s6_addr', rffi.CFixedArray(rffi.CHAR, 16))])
  232. CConfig.sockaddr_in = platform.Struct('struct sockaddr_in',
  233. [('sin_family', rffi.INT),
  234. ('sin_port', rffi.USHORT),
  235. ('sin_addr', CConfig.in_addr)])
  236. CConfig.sockaddr_in6 = platform.Struct('struct sockaddr_in6',
  237. [('sin6_family', rffi.INT),
  238. ('sin6_port', rffi.USHORT),
  239. ('sin6_flowinfo', rffi.INT),
  240. ('sin6_addr', CConfig.in6_addr),
  241. ('sin6_scope_id', rffi.INT)])
  242. CConfig.sockaddr_un = platform.Struct('struct sockaddr_un',
  243. [('sun_family', rffi.INT),
  244. ('sun_path', rffi.CFixedArray(rffi.CHAR, 1))],
  245. ifdef='AF_UNIX')
  246. CConfig.sockaddr_nl = platform.Struct('struct sockaddr_nl',
  247. [('nl_family', rffi.INT),
  248. ('nl_pid', rffi.INT),
  249. ('nl_groups', rffi.INT)],
  250. ifdef='AF_NETLINK')
  251. CConfig.addrinfo = platform.Struct('struct addrinfo',
  252. [('ai_flags', rffi.INT),
  253. ('ai_family', rffi.INT),
  254. ('ai_socktype', rffi.INT),
  255. ('ai_protocol', rffi.INT),
  256. ('ai_addrlen', rffi.INT),
  257. ('ai_addr', sockaddr_ptr),
  258. ('ai_canonname', CCHARP),
  259. ('ai_next', addrinfo_ptr)])
  260. CConfig.hostent = platform.Struct('struct hostent',
  261. [('h_name', CCHARP),
  262. ('h_aliases', rffi.CCHARPP),
  263. ('h_addrtype', rffi.INT),
  264. ('h_length', rffi.INT),
  265. ('h_addr_list', rffi.CCHARPP),
  266. ])
  267. CConfig.servent = platform.Struct('struct servent',
  268. [('s_name', CCHARP),
  269. ('s_port', rffi.INT),
  270. ('s_proto', CCHARP),
  271. ])
  272. CConfig.protoent = platform.Struct('struct protoent',
  273. [('p_proto', rffi.INT),
  274. ])
  275. if _POSIX:
  276. CConfig.nfds_t = platform.SimpleType('nfds_t')
  277. CConfig.pollfd = platform.Struct('struct pollfd',
  278. [('fd', socketfd_type),
  279. ('events', rffi.SHORT),
  280. ('revents', rffi.SHORT)])
  281. if _HAS_AF_PACKET:
  282. CConfig.sockaddr_ll = platform.Struct('struct sockaddr_ll',
  283. [('sll_family', rffi.INT),
  284. ('sll_ifindex', rffi.INT),
  285. ('sll_protocol', rffi.INT),
  286. ('sll_pkttype', rffi.INT),
  287. ('sll_hatype', rffi.INT),
  288. ('sll_addr', rffi.CFixedArray(rffi.CHAR, 8)),
  289. ('sll_halen', rffi.INT)])
  290. CConfig.ifreq = platform.Struct('struct ifreq',
  291. [('ifr_ifindex', rffi.INT),
  292. ('ifr_name', rffi.CFixedArray(rffi.CHAR, 8))])
  293. if _WIN32:
  294. CConfig.WSAEVENT = platform.SimpleType('WSAEVENT', rffi.VOIDP)
  295. CConfig.WSANETWORKEVENTS = platform.Struct(
  296. 'struct _WSANETWORKEVENTS',
  297. [('lNetworkEvents', rffi.LONG),
  298. ('iErrorCode', rffi.CFixedArray(rffi.INT, 10)), #FD_MAX_EVENTS
  299. ])
  300. CConfig.WSAPROTOCOL_INFO = platform.Struct(
  301. 'WSAPROTOCOL_INFOA',
  302. []) # Struct is just passed between functions
  303. CConfig.FROM_PROTOCOL_INFO = platform.DefinedConstantInteger(
  304. 'FROM_PROTOCOL_INFO')
  305. CConfig.timeval = platform.Struct('struct timeval',
  306. [('tv_sec', rffi.LONG),
  307. ('tv_usec', rffi.LONG)])
  308. fd_set = rffi.COpaquePtr('fd_set', compilation_info=eci)
  309. if _WIN32:
  310. CConfig.WSAData = platform.Struct('struct WSAData',
  311. [('wVersion', rffi.USHORT),
  312. ('wHighVersion', rffi.USHORT),
  313. ('szDescription', rffi.CFixedArray(lltype.Char, 1)), # (WSADESCRIPTION_LEN+1)
  314. ('szSystemStatus', rffi.CFixedArray(lltype.Char, 1)), # (WSASYS_STATUS_LEN+1)
  315. ('iMaxSockets', rffi.USHORT),
  316. ('iMaxUdpDg', rffi.USHORT),
  317. ('lpVendorInfo', CCHARP)])
  318. CConfig.tcp_keepalive = platform.Struct(
  319. 'struct tcp_keepalive',
  320. [('onoff', rffi.ULONG),
  321. ('keepalivetime', rffi.ULONG),
  322. ('keepaliveinterval', rffi.ULONG)])
  323. class cConfig:
  324. pass
  325. cConfig.__dict__.update(platform.configure(CConfig))
  326. sockaddr_ptr.TO.become(cConfig.sockaddr)
  327. addrinfo_ptr.TO.become(cConfig.addrinfo)
  328. # fill in missing constants with reasonable defaults
  329. cConfig.NI_MAXHOST = cConfig.NI_MAXHOST or 1025
  330. cConfig.NI_MAXSERV = cConfig.NI_MAXSERV or 32
  331. cConfig.INET_ADDRSTRLEN = cConfig.INET_ADDRSTRLEN or 16
  332. for name in constant_names:
  333. value = getattr(cConfig, name)
  334. if value is not None:
  335. constants[name] = value
  336. for name, default in constants_w_defaults:
  337. value = getattr(cConfig, name)
  338. if value is not None:
  339. constants[name] = value
  340. else:
  341. constants[name] = default
  342. if not _HAS_AF_PACKET and 'AF_PACKET' in constants:
  343. del constants['AF_PACKET']
  344. constants['has_ipv6'] = True # This is a configuration option in CPython
  345. for name, value in constants.items():
  346. if isinstance(value, long):
  347. if r_uint(value) == value:
  348. constants[name] = intmask(value)
  349. locals().update(constants)
  350. O_RDONLY = cConfig.O_RDONLY
  351. O_WRONLY = cConfig.O_WRONLY
  352. O_RDWR = cConfig.O_RDWR
  353. O_NONBLOCK = cConfig.O_NONBLOCK
  354. F_GETFL = cConfig.F_GETFL
  355. F_SETFL = cConfig.F_SETFL
  356. FIONBIO = cConfig.FIONBIO
  357. INET_ADDRSTRLEN = cConfig.INET_ADDRSTRLEN
  358. INET6_ADDRSTRLEN = cConfig.INET6_ADDRSTRLEN
  359. EINTR = cConfig.EINTR or cConfig.WSAEINTR
  360. EINPROGRESS = cConfig.EINPROGRESS or cConfig.WSAEINPROGRESS
  361. EWOULDBLOCK = cConfig.EWOULDBLOCK or cConfig.WSAEWOULDBLOCK
  362. EAFNOSUPPORT = cConfig.EAFNOSUPPORT or cConfig.WSAEAFNOSUPPORT
  363. EISCONN = cConfig.EISCONN or cConfig.WSAEISCONN
  364. linux = cConfig.linux
  365. WIN32 = cConfig.WIN32
  366. assert WIN32 == _WIN32
  367. if _MSVC:
  368. def invalid_socket(fd):
  369. return fd == INVALID_SOCKET
  370. INVALID_SOCKET = r_uint(cConfig.INVALID_SOCKET)
  371. else:
  372. def invalid_socket(fd):
  373. return fd < 0
  374. INVALID_SOCKET = -1
  375. uint16_t = cConfig.uint16_t
  376. uint32_t = cConfig.uint32_t
  377. size_t = cConfig.size_t
  378. ssize_t = cConfig.ssize_t
  379. socklen_t = cConfig.socklen_t
  380. sockaddr = cConfig.sockaddr
  381. #sockaddr_size = sizeof(sockaddr)
  382. sockaddr_in = cConfig.sockaddr_in
  383. sockaddr_in6 = cConfig.sockaddr_in6
  384. sockaddr_un = cConfig.sockaddr_un
  385. if cConfig.sockaddr_nl is not None:
  386. sockaddr_nl = cConfig.sockaddr_nl
  387. in_addr = cConfig.in_addr
  388. #in_addr_size = sizeof(in_addr)
  389. in6_addr = cConfig.in6_addr
  390. addrinfo = cConfig.addrinfo
  391. if _POSIX:
  392. nfds_t = cConfig.nfds_t
  393. pollfd = cConfig.pollfd
  394. if _HAS_AF_PACKET:
  395. sockaddr_ll = cConfig.sockaddr_ll
  396. ifreq = cConfig.ifreq
  397. if WIN32:
  398. WSAEVENT = cConfig.WSAEVENT
  399. WSANETWORKEVENTS = cConfig.WSANETWORKEVENTS
  400. SAVE_ERR = rffi.RFFI_SAVE_WSALASTERROR
  401. else:
  402. SAVE_ERR = rffi.RFFI_SAVE_ERRNO
  403. timeval = cConfig.timeval
  404. def external(name, args, result, **kwds):
  405. return rffi.llexternal(name, args, result, compilation_info=eci,
  406. calling_conv=calling_conv, **kwds)
  407. def external_c(name, args, result, **kwargs):
  408. return rffi.llexternal(name, args, result, compilation_info=eci,
  409. calling_conv='c', **kwargs)
  410. if _POSIX:
  411. dup = external('dup', [socketfd_type], socketfd_type, save_err=SAVE_ERR)
  412. gai_strerror = external('gai_strerror', [rffi.INT], CCHARP)
  413. #h_errno = c_int.in_dll(socketdll, 'h_errno')
  414. #
  415. #hstrerror = socketdll.hstrerror
  416. #hstrerror.argtypes = [c_int]
  417. #hstrerror.restype = c_char_p
  418. socket = external('socket', [rffi.INT, rffi.INT, rffi.INT], socketfd_type,
  419. save_err=SAVE_ERR)
  420. if WIN32:
  421. socketclosename = 'closesocket'
  422. else:
  423. socketclosename = 'close'
  424. socketclose = external(socketclosename, [socketfd_type], rffi.INT,
  425. releasegil=False, save_err=SAVE_ERR)
  426. socketclose_no_errno = external(socketclosename, [socketfd_type], rffi.INT,
  427. releasegil=False)
  428. socketconnect = external('connect', [socketfd_type, sockaddr_ptr, socklen_t],
  429. rffi.INT, save_err=SAVE_ERR)
  430. getaddrinfo = external('getaddrinfo', [CCHARP, CCHARP,
  431. addrinfo_ptr,
  432. lltype.Ptr(rffi.CArray(addrinfo_ptr))], rffi.INT)
  433. freeaddrinfo = external('freeaddrinfo', [addrinfo_ptr], lltype.Void)
  434. getnameinfo = external('getnameinfo', [sockaddr_ptr, socklen_t, CCHARP,
  435. size_t, CCHARP, size_t, rffi.INT], rffi.INT)
  436. if sys.platform.startswith("openbsd") or sys.platform.startswith("darwin"):
  437. htonl = external('htonl', [rffi.UINT], rffi.UINT, releasegil=False, macro=True)
  438. htons = external('htons', [rffi.USHORT], rffi.USHORT, releasegil=False, macro=True)
  439. ntohl = external('ntohl', [rffi.UINT], rffi.UINT, releasegil=False, macro=True)
  440. ntohs = external('ntohs', [rffi.USHORT], rffi.USHORT, releasegil=False, macro=True)
  441. else:
  442. htonl = external('htonl', [rffi.UINT], rffi.UINT, releasegil=False)
  443. htons = external('htons', [rffi.USHORT], rffi.USHORT, releasegil=False)
  444. ntohl = external('ntohl', [rffi.UINT], rffi.UINT, releasegil=False)
  445. ntohs = external('ntohs', [rffi.USHORT], rffi.USHORT, releasegil=False)
  446. if _POSIX:
  447. inet_aton = external('inet_aton', [CCHARP, lltype.Ptr(in_addr)],
  448. rffi.INT)
  449. inet_ntoa = external('inet_ntoa', [in_addr], rffi.CCHARP)
  450. if _POSIX:
  451. inet_pton = external('inet_pton', [rffi.INT, rffi.CCHARP,
  452. rffi.VOIDP], rffi.INT,
  453. save_err=SAVE_ERR)
  454. inet_ntop = external('inet_ntop', [rffi.INT, rffi.VOIDP, CCHARP,
  455. socklen_t], CCHARP,
  456. save_err=SAVE_ERR)
  457. inet_addr = external('inet_addr', [rffi.CCHARP], rffi.UINT)
  458. socklen_t_ptr = lltype.Ptr(rffi.CFixedArray(socklen_t, 1))
  459. socketaccept = external('accept', [socketfd_type, sockaddr_ptr,
  460. socklen_t_ptr], socketfd_type,
  461. save_err=SAVE_ERR)
  462. socketbind = external('bind', [socketfd_type, sockaddr_ptr, socklen_t],
  463. rffi.INT, save_err=SAVE_ERR)
  464. socketlisten = external('listen', [socketfd_type, rffi.INT], rffi.INT,
  465. save_err=SAVE_ERR)
  466. socketgetpeername = external('getpeername', [socketfd_type,
  467. sockaddr_ptr, socklen_t_ptr], rffi.INT,
  468. save_err=SAVE_ERR)
  469. socketgetsockname = external('getsockname', [socketfd_type,
  470. sockaddr_ptr, socklen_t_ptr], rffi.INT,
  471. save_err=SAVE_ERR)
  472. socketgetsockopt = external('getsockopt', [socketfd_type, rffi.INT,
  473. rffi.INT, rffi.VOIDP, socklen_t_ptr], rffi.INT,
  474. save_err=SAVE_ERR)
  475. socketsetsockopt = external('setsockopt', [socketfd_type, rffi.INT,
  476. rffi.INT, rffi.VOIDP, socklen_t], rffi.INT,
  477. save_err=SAVE_ERR)
  478. socketrecv = external('recv', [socketfd_type, rffi.VOIDP, rffi.INT,
  479. rffi.INT], ssize_t, save_err=SAVE_ERR)
  480. recvfrom = external('recvfrom', [socketfd_type, rffi.VOIDP, size_t,
  481. rffi.INT, sockaddr_ptr, socklen_t_ptr], rffi.INT,
  482. save_err=SAVE_ERR)
  483. send = external('send', [socketfd_type, rffi.CCHARP, size_t, rffi.INT],
  484. ssize_t, save_err=SAVE_ERR)
  485. sendto = external('sendto', [socketfd_type, rffi.VOIDP, size_t, rffi.INT,
  486. sockaddr_ptr, socklen_t], ssize_t,
  487. save_err=SAVE_ERR)
  488. socketshutdown = external('shutdown', [socketfd_type, rffi.INT], rffi.INT,
  489. save_err=SAVE_ERR)
  490. gethostname = external('gethostname', [rffi.CCHARP, rffi.INT], rffi.INT,
  491. save_err=SAVE_ERR)
  492. gethostbyname = external('gethostbyname', [rffi.CCHARP],
  493. lltype.Ptr(cConfig.hostent))
  494. gethostbyaddr = external('gethostbyaddr', [rffi.VOIDP, rffi.INT, rffi.INT], lltype.Ptr(cConfig.hostent))
  495. getservbyname = external('getservbyname', [rffi.CCHARP, rffi.CCHARP], lltype.Ptr(cConfig.servent))
  496. getservbyport = external('getservbyport', [rffi.INT, rffi.CCHARP], lltype.Ptr(cConfig.servent))
  497. getprotobyname = external('getprotobyname', [rffi.CCHARP], lltype.Ptr(cConfig.protoent))
  498. if _POSIX:
  499. fcntl = external('fcntl', [socketfd_type, rffi.INT, rffi.INT], rffi.INT)
  500. socketpair_t = rffi.CArray(socketfd_type)
  501. socketpair = external('socketpair', [rffi.INT, rffi.INT, rffi.INT,
  502. lltype.Ptr(socketpair_t)], rffi.INT,
  503. save_err=SAVE_ERR)
  504. if _HAS_AF_PACKET:
  505. ioctl = external('ioctl', [socketfd_type, rffi.INT, lltype.Ptr(ifreq)],
  506. rffi.INT)
  507. if _WIN32:
  508. ioctlsocket = external('ioctlsocket',
  509. [socketfd_type, rffi.LONG, rffi.ULONGP],
  510. rffi.INT)
  511. select = external('select',
  512. [rffi.INT, fd_set, fd_set,
  513. fd_set, lltype.Ptr(timeval)],
  514. rffi.INT,
  515. save_err=SAVE_ERR)
  516. FD_CLR = external_c('FD_CLR', [rffi.INT, fd_set], lltype.Void, macro=True)
  517. FD_ISSET = external_c('FD_ISSET', [rffi.INT, fd_set], rffi.INT, macro=True)
  518. FD_SET = external_c('FD_SET', [rffi.INT, fd_set], lltype.Void, macro=True)
  519. FD_ZERO = external_c('FD_ZERO', [fd_set], lltype.Void, macro=True)
  520. if _POSIX:
  521. pollfdarray = rffi.CArray(pollfd)
  522. poll = external('poll', [lltype.Ptr(pollfdarray), nfds_t, rffi.INT],
  523. rffi.INT, save_err=SAVE_ERR)
  524. # workaround for Mac OS/X on which poll() seems to behave a bit strangely
  525. # (see test_recv_send_timeout in pypy.module._socket.test.test_sock_app)
  526. # https://issues.apache.org/bugzilla/show_bug.cgi?id=34332
  527. poll_may_be_broken = _MACOSX
  528. elif WIN32:
  529. from rpython.rlib import rwin32
  530. #
  531. # The following is for rpython.rlib.rpoll
  532. #
  533. WSAEVENT_ARRAY = rffi.CArray(WSAEVENT)
  534. WSACreateEvent = external('WSACreateEvent', [], WSAEVENT)
  535. WSACloseEvent = external('WSACloseEvent', [WSAEVENT], rffi.INT)
  536. WSAEventSelect = external('WSAEventSelect',
  537. [socketfd_type, WSAEVENT, rffi.LONG],
  538. rffi.INT)
  539. WSAWaitForMultipleEvents = external('WSAWaitForMultipleEvents',
  540. [rffi.LONG, lltype.Ptr(WSAEVENT_ARRAY),
  541. rffi.INT, rffi.LONG, rffi.INT],
  542. rffi.ULONG)
  543. WSAEnumNetworkEvents = external('WSAEnumNetworkEvents',
  544. [socketfd_type, WSAEVENT,
  545. lltype.Ptr(WSANETWORKEVENTS)],
  546. rffi.INT)
  547. WSAIoctl = external('WSAIoctl',
  548. [socketfd_type, rwin32.DWORD,
  549. rffi.VOIDP, rwin32.DWORD,
  550. rffi.VOIDP, rwin32.DWORD,
  551. rwin32.LPDWORD, rffi.VOIDP, rffi.VOIDP],
  552. rffi.INT, save_err=SAVE_ERR)
  553. tcp_keepalive = cConfig.tcp_keepalive
  554. WSAPROTOCOL_INFO = cConfig.WSAPROTOCOL_INFO
  555. FROM_PROTOCOL_INFO = cConfig.FROM_PROTOCOL_INFO
  556. WSADuplicateSocket = external('WSADuplicateSocketA',
  557. [socketfd_type, rwin32.DWORD,
  558. lltype.Ptr(WSAPROTOCOL_INFO)],
  559. rffi.INT, save_err=SAVE_ERR)
  560. WSASocket = external('WSASocketA',
  561. [rffi.INT, rffi.INT, rffi.INT,
  562. lltype.Ptr(WSAPROTOCOL_INFO),
  563. rwin32.DWORD, rwin32.DWORD],
  564. socketfd_type, save_err=SAVE_ERR)
  565. if WIN32:
  566. WSAData = cConfig.WSAData
  567. WSAStartup = external('WSAStartup', [rwin32.WORD, lltype.Ptr(WSAData)],
  568. rffi.INT)
  569. _WSAGetLastError = external('WSAGetLastError', [], rwin32.DWORD,
  570. _nowrapper=True, sandboxsafe=True)
  571. geterrno = rwin32.GetLastError_saved
  572. # In tests, the first call to GetLastError is always wrong, because error
  573. # is hidden by operations in ll2ctypes. Call it now.
  574. _WSAGetLastError()
  575. def socket_strerror_str(errno):
  576. return rwin32.FormatError(errno)
  577. def gai_strerror_str(errno):
  578. return rwin32.FormatError(errno)
  579. # WinSock does not use a bitmask in select, and uses
  580. # socket handles greater than FD_SETSIZE
  581. MAX_FD_SIZE = None
  582. else:
  583. from rpython.rlib.rposix import get_saved_errno as geterrno
  584. socket_strerror_str = os.strerror
  585. def gai_strerror_str(errno):
  586. return rffi.charp2str(gai_strerror(errno))
  587. MAX_FD_SIZE = FD_SETSIZE