/pypy/module/_socket/interp_socket.py

https://bitbucket.org/pypy/pypy/ · Python · 752 lines · 612 code · 34 blank · 106 comment · 74 complexity · c5edf6c912871774b60e6f0d63ec7490 MD5 · raw file

  1. import sys
  2. from rpython.rlib import rsocket, rweaklist
  3. from rpython.rlib.rarithmetic import intmask
  4. from rpython.rlib.rsocket import (
  5. RSocket, AF_INET, SOCK_STREAM, SocketError, SocketErrorWithErrno,
  6. RSocketError
  7. )
  8. from rpython.rtyper.lltypesystem import lltype, rffi
  9. from pypy.interpreter import gateway
  10. from pypy.interpreter.baseobjspace import W_Root
  11. from pypy.interpreter.error import OperationError, oefmt
  12. from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
  13. from pypy.interpreter.typedef import (
  14. GetSetProperty, TypeDef, make_weakref_descr
  15. )
  16. # XXX Hack to seperate rpython and pypy
  17. def addr_as_object(addr, fd, space):
  18. if isinstance(addr, rsocket.INETAddress):
  19. return space.newtuple([space.wrap(addr.get_host()),
  20. space.wrap(addr.get_port())])
  21. elif isinstance(addr, rsocket.INET6Address):
  22. return space.newtuple([space.wrap(addr.get_host()),
  23. space.wrap(addr.get_port()),
  24. space.wrap(addr.get_flowinfo()),
  25. space.wrap(addr.get_scope_id())])
  26. elif rsocket.HAS_AF_PACKET and isinstance(addr, rsocket.PacketAddress):
  27. return space.newtuple([space.wrap(addr.get_ifname(fd)),
  28. space.wrap(addr.get_protocol()),
  29. space.wrap(addr.get_pkttype()),
  30. space.wrap(addr.get_hatype()),
  31. space.wrap(addr.get_haddr())])
  32. elif rsocket.HAS_AF_UNIX and isinstance(addr, rsocket.UNIXAddress):
  33. return space.wrap(addr.get_path())
  34. elif rsocket.HAS_AF_NETLINK and isinstance(addr, rsocket.NETLINKAddress):
  35. return space.newtuple([space.wrap(addr.get_pid()),
  36. space.wrap(addr.get_groups())])
  37. # If we don't know the address family, don't raise an
  38. # exception -- return it as a tuple.
  39. from rpython.rlib import _rsocket_rffi as _c
  40. a = addr.lock()
  41. family = rffi.cast(lltype.Signed, a.c_sa_family)
  42. datalen = addr.addrlen - rsocket.offsetof(_c.sockaddr, 'c_sa_data')
  43. rawdata = ''.join([a.c_sa_data[i] for i in range(datalen)])
  44. addr.unlock()
  45. return space.newtuple([space.wrap(family),
  46. space.wrap(rawdata)])
  47. # XXX Hack to seperate rpython and pypy
  48. # XXX a bit of code duplication
  49. def fill_from_object(addr, space, w_address):
  50. from rpython.rlib import _rsocket_rffi as _c
  51. if isinstance(addr, rsocket.INETAddress):
  52. _, w_port = space.unpackiterable(w_address, 2)
  53. port = space.int_w(w_port)
  54. port = make_ushort_port(space, port)
  55. a = addr.lock(_c.sockaddr_in)
  56. rffi.setintfield(a, 'c_sin_port', rsocket.htons(port))
  57. addr.unlock()
  58. elif isinstance(addr, rsocket.INET6Address):
  59. pieces_w = space.unpackiterable(w_address)
  60. if not (2 <= len(pieces_w) <= 4):
  61. raise RSocketError("AF_INET6 address must be a tuple of length 2 "
  62. "to 4, not %d" % len(pieces_w))
  63. port = space.int_w(pieces_w[1])
  64. port = make_ushort_port(space, port)
  65. if len(pieces_w) > 2: flowinfo = space.int_w(pieces_w[2])
  66. else: flowinfo = 0
  67. if len(pieces_w) > 3: scope_id = space.uint_w(pieces_w[3])
  68. else: scope_id = 0
  69. flowinfo = make_unsigned_flowinfo(space, flowinfo)
  70. a = addr.lock(_c.sockaddr_in6)
  71. rffi.setintfield(a, 'c_sin6_port', rsocket.htons(port))
  72. rffi.setintfield(a, 'c_sin6_flowinfo', rsocket.htonl(flowinfo))
  73. rffi.setintfield(a, 'c_sin6_scope_id', scope_id)
  74. addr.unlock()
  75. else:
  76. raise NotImplementedError
  77. # XXX Hack to seperate rpython and pypy
  78. def addr_from_object(family, fd, space, w_address):
  79. if family == rsocket.AF_INET:
  80. w_host, w_port = space.unpackiterable(w_address, 2)
  81. host = space.str_w(w_host)
  82. port = space.int_w(w_port)
  83. port = make_ushort_port(space, port)
  84. return rsocket.INETAddress(host, port)
  85. if family == rsocket.AF_INET6:
  86. pieces_w = space.unpackiterable(w_address)
  87. if not (2 <= len(pieces_w) <= 4):
  88. raise oefmt(space.w_TypeError,
  89. "AF_INET6 address must be a tuple of length 2 "
  90. "to 4, not %d", len(pieces_w))
  91. host = space.str_w(pieces_w[0])
  92. port = space.int_w(pieces_w[1])
  93. port = make_ushort_port(space, port)
  94. if len(pieces_w) > 2: flowinfo = space.int_w(pieces_w[2])
  95. else: flowinfo = 0
  96. if len(pieces_w) > 3: scope_id = space.uint_w(pieces_w[3])
  97. else: scope_id = 0
  98. flowinfo = make_unsigned_flowinfo(space, flowinfo)
  99. return rsocket.INET6Address(host, port, flowinfo, scope_id)
  100. if rsocket.HAS_AF_UNIX and family == rsocket.AF_UNIX:
  101. return rsocket.UNIXAddress(space.str_w(w_address))
  102. if rsocket.HAS_AF_NETLINK and family == rsocket.AF_NETLINK:
  103. w_pid, w_groups = space.unpackiterable(w_address, 2)
  104. return rsocket.NETLINKAddress(space.uint_w(w_pid), space.uint_w(w_groups))
  105. if rsocket.HAS_AF_PACKET and family == rsocket.AF_PACKET:
  106. pieces_w = space.unpackiterable(w_address)
  107. if not (2 <= len(pieces_w) <= 5):
  108. raise oefmt(space.w_TypeError,
  109. "AF_PACKET address must be a tuple of length 2 "
  110. "to 5, not %d", len(pieces_w))
  111. ifname = space.str_w(pieces_w[0])
  112. ifindex = rsocket.PacketAddress.get_ifindex_from_ifname(fd, ifname)
  113. protocol = space.int_w(pieces_w[1])
  114. if len(pieces_w) > 2: pkttype = space.int_w(pieces_w[2])
  115. else: pkttype = 0
  116. if len(pieces_w) > 3: hatype = space.int_w(pieces_w[3])
  117. else: hatype = 0
  118. if len(pieces_w) > 4: haddr = space.str_w(pieces_w[4])
  119. else: haddr = ""
  120. if len(haddr) > 8:
  121. raise oefmt(space.w_ValueError,
  122. "Hardware address must be 8 bytes or less")
  123. if protocol < 0 or protocol > 0xfffff:
  124. raise oefmt(space.w_OverflowError, "protoNumber must be 0-65535.")
  125. return rsocket.PacketAddress(ifindex, protocol, pkttype, hatype, haddr)
  126. raise RSocketError("unknown address family")
  127. # XXX Hack to seperate rpython and pypy
  128. def make_ushort_port(space, port):
  129. assert isinstance(port, int)
  130. if port < 0 or port > 0xffff:
  131. raise oefmt(space.w_OverflowError, "port must be 0-65535.")
  132. return port
  133. def make_unsigned_flowinfo(space, flowinfo):
  134. if flowinfo < 0 or flowinfo > 0xfffff:
  135. raise oefmt(space.w_OverflowError, "flowinfo must be 0-1048575.")
  136. return rffi.cast(lltype.Unsigned, flowinfo)
  137. # XXX Hack to seperate rpython and pypy
  138. def ipaddr_from_object(space, w_sockaddr):
  139. host = space.str_w(space.getitem(w_sockaddr, space.wrap(0)))
  140. addr = rsocket.makeipaddr(host)
  141. fill_from_object(addr, space, w_sockaddr)
  142. return addr
  143. class W_Socket(W_Root):
  144. w_tb = None # String representation of the traceback at creation time
  145. def __init__(self, space, sock):
  146. self.space = space
  147. self.sock = sock
  148. register_socket(space, sock)
  149. if self.space.sys.track_resources:
  150. self.w_tb = self.space.format_traceback()
  151. self.register_finalizer(space)
  152. def _finalize_(self):
  153. is_open = self.sock.fd >= 0
  154. if is_open and self.space.sys.track_resources:
  155. w_repr = self.space.repr(self)
  156. str_repr = self.space.str_w(w_repr)
  157. w_msg = self.space.wrap("WARNING: unclosed " + str_repr)
  158. self.space.resource_warning(w_msg, self.w_tb)
  159. def get_type_w(self, space):
  160. return space.wrap(self.sock.type)
  161. def get_proto_w(self, space):
  162. return space.wrap(self.sock.proto)
  163. def get_family_w(self, space):
  164. return space.wrap(self.sock.family)
  165. def descr_repr(self, space):
  166. fd = intmask(self.sock.fd) # Force to signed type even on Windows.
  167. return space.wrap("<socket object, fd=%d, family=%d,"
  168. " type=%d, protocol=%d>" %
  169. (fd, self.sock.family,
  170. self.sock.type, self.sock.proto))
  171. def accept_w(self, space):
  172. """accept() -> (socket object, address info)
  173. Wait for an incoming connection. Return a new socket representing the
  174. connection, and the address of the client. For IP sockets, the address
  175. info is a pair (hostaddr, port).
  176. """
  177. try:
  178. fd, addr = self.sock.accept()
  179. sock = rsocket.make_socket(
  180. fd, self.sock.family, self.sock.type, self.sock.proto)
  181. return space.newtuple([space.wrap(W_Socket(space, sock)),
  182. addr_as_object(addr, sock.fd, space)])
  183. except SocketError as e:
  184. raise converted_error(space, e)
  185. # convert an Address into an app-level object
  186. def addr_as_object(self, space, address):
  187. return addr_as_object(address, self.sock.fd, space)
  188. # convert an app-level object into an Address
  189. # based on the current socket's family
  190. def addr_from_object(self, space, w_address):
  191. fd = intmask(self.sock.fd)
  192. return addr_from_object(self.sock.family, fd, space, w_address)
  193. def bind_w(self, space, w_addr):
  194. """bind(address)
  195. Bind the socket to a local address. For IP sockets, the address is a
  196. pair (host, port); the host must refer to the local host. For raw packet
  197. sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])
  198. """
  199. try:
  200. self.sock.bind(self.addr_from_object(space, w_addr))
  201. except SocketError as e:
  202. raise converted_error(space, e)
  203. def close_w(self, space):
  204. """close()
  205. Close the socket. It cannot be used after this call.
  206. """
  207. try:
  208. self.sock.close()
  209. except SocketError:
  210. # cpython doesn't return any errors on close
  211. pass
  212. def connect_w(self, space, w_addr):
  213. """connect(address)
  214. Connect the socket to a remote address. For IP sockets, the address
  215. is a pair (host, port).
  216. """
  217. try:
  218. self.sock.connect(self.addr_from_object(space, w_addr))
  219. except SocketError as e:
  220. raise converted_error(space, e)
  221. def connect_ex_w(self, space, w_addr):
  222. """connect_ex(address) -> errno
  223. This is like connect(address), but returns an error code (the errno value)
  224. instead of raising an exception when an error occurs.
  225. """
  226. try:
  227. addr = self.addr_from_object(space, w_addr)
  228. except SocketError as e:
  229. raise converted_error(space, e)
  230. error = self.sock.connect_ex(addr)
  231. return space.wrap(error)
  232. def dup_w(self, space):
  233. try:
  234. sock = self.sock.dup()
  235. return W_Socket(space, sock)
  236. except SocketError as e:
  237. raise converted_error(space, e)
  238. def fileno_w(self, space):
  239. """fileno() -> integer
  240. Return the integer file descriptor of the socket.
  241. """
  242. return space.wrap(intmask(self.sock.fd))
  243. def getpeername_w(self, space):
  244. """getpeername() -> address info
  245. Return the address of the remote endpoint. For IP sockets, the address
  246. info is a pair (hostaddr, port).
  247. """
  248. try:
  249. addr = self.sock.getpeername()
  250. return addr_as_object(addr, self.sock.fd, space)
  251. except SocketError as e:
  252. raise converted_error(space, e)
  253. def getsockname_w(self, space):
  254. """getsockname() -> address info
  255. Return the address of the local endpoint. For IP sockets, the address
  256. info is a pair (hostaddr, port).
  257. """
  258. try:
  259. addr = self.sock.getsockname()
  260. return addr_as_object(addr, self.sock.fd, space)
  261. except SocketError as e:
  262. raise converted_error(space, e)
  263. @unwrap_spec(level=int, optname=int)
  264. def getsockopt_w(self, space, level, optname, w_buflen=None):
  265. """getsockopt(level, option[, buffersize]) -> value
  266. Get a socket option. See the Unix manual for level and option.
  267. If a nonzero buffersize argument is given, the return value is a
  268. string of that length; otherwise it is an integer.
  269. """
  270. if w_buflen is None:
  271. try:
  272. return space.wrap(self.sock.getsockopt_int(level, optname))
  273. except SocketError as e:
  274. raise converted_error(space, e)
  275. buflen = space.int_w(w_buflen)
  276. return space.newbytes(self.sock.getsockopt(level, optname, buflen))
  277. def gettimeout_w(self, space):
  278. """gettimeout() -> timeout
  279. Returns the timeout in floating seconds associated with socket
  280. operations. A timeout of None indicates that timeouts on socket
  281. """
  282. timeout = self.sock.gettimeout()
  283. if timeout < 0.0:
  284. return space.w_None
  285. return space.wrap(timeout)
  286. @unwrap_spec(backlog="c_int")
  287. def listen_w(self, space, backlog):
  288. """listen(backlog)
  289. Enable a server to accept connections. The backlog argument must be at
  290. least 1; it specifies the number of unaccepted connection that the system
  291. will allow before refusing new connections.
  292. """
  293. try:
  294. self.sock.listen(backlog)
  295. except SocketError as e:
  296. raise converted_error(space, e)
  297. @unwrap_spec(w_mode = WrappedDefault("r"),
  298. w_buffsize = WrappedDefault(-1))
  299. def makefile_w(self, space, w_mode=None, w_buffsize=None):
  300. """makefile([mode[, buffersize]]) -> file object
  301. Return a regular file object corresponding to the socket.
  302. The mode and buffersize arguments are as for the built-in open() function.
  303. """
  304. return app_makefile(space, self, w_mode, w_buffsize)
  305. @unwrap_spec(buffersize='nonnegint', flags=int)
  306. def recv_w(self, space, buffersize, flags=0):
  307. """recv(buffersize[, flags]) -> data
  308. Receive up to buffersize bytes from the socket. For the optional flags
  309. argument, see the Unix manual. When no data is available, block until
  310. at least one byte is available or until the remote end is closed. When
  311. the remote end is closed and all data is read, return the empty string.
  312. """
  313. try:
  314. data = self.sock.recv(buffersize, flags)
  315. except SocketError as e:
  316. raise converted_error(space, e)
  317. return space.newbytes(data)
  318. @unwrap_spec(buffersize='nonnegint', flags=int)
  319. def recvfrom_w(self, space, buffersize, flags=0):
  320. """recvfrom(buffersize[, flags]) -> (data, address info)
  321. Like recv(buffersize, flags) but also return the sender's address info.
  322. """
  323. try:
  324. data, addr = self.sock.recvfrom(buffersize, flags)
  325. if addr:
  326. w_addr = addr_as_object(addr, self.sock.fd, space)
  327. else:
  328. w_addr = space.w_None
  329. return space.newtuple([space.newbytes(data), w_addr])
  330. except SocketError as e:
  331. raise converted_error(space, e)
  332. @unwrap_spec(data='bufferstr', flags=int)
  333. def send_w(self, space, data, flags=0):
  334. """send(data[, flags]) -> count
  335. Send a data string to the socket. For the optional flags
  336. argument, see the Unix manual. Return the number of bytes
  337. sent; this may be less than len(data) if the network is busy.
  338. """
  339. try:
  340. count = self.sock.send(data, flags)
  341. except SocketError as e:
  342. raise converted_error(space, e)
  343. return space.wrap(count)
  344. @unwrap_spec(data='bufferstr', flags=int)
  345. def sendall_w(self, space, data, flags=0):
  346. """sendall(data[, flags])
  347. Send a data string to the socket. For the optional flags
  348. argument, see the Unix manual. This calls send() repeatedly
  349. until all data is sent. If an error occurs, it's impossible
  350. to tell how much data has been sent.
  351. """
  352. try:
  353. self.sock.sendall(
  354. data, flags, space.getexecutioncontext().checksignals)
  355. except SocketError as e:
  356. raise converted_error(space, e)
  357. @unwrap_spec(data='bufferstr')
  358. def sendto_w(self, space, data, w_param2, w_param3=None):
  359. """sendto(data[, flags], address) -> count
  360. Like send(data, flags) but allows specifying the destination address.
  361. For IP sockets, the address is a pair (hostaddr, port).
  362. """
  363. if w_param3 is None:
  364. # 2 args version
  365. flags = 0
  366. w_addr = w_param2
  367. else:
  368. # 3 args version
  369. flags = space.int_w(w_param2)
  370. w_addr = w_param3
  371. try:
  372. addr = self.addr_from_object(space, w_addr)
  373. count = self.sock.sendto(data, flags, addr)
  374. except SocketError as e:
  375. raise converted_error(space, e)
  376. return space.wrap(count)
  377. @unwrap_spec(flag=bool)
  378. def setblocking_w(self, flag):
  379. """setblocking(flag)
  380. Set the socket to blocking (flag is true) or non-blocking (false).
  381. setblocking(True) is equivalent to settimeout(None);
  382. setblocking(False) is equivalent to settimeout(0.0).
  383. """
  384. self.sock.setblocking(flag)
  385. @unwrap_spec(level=int, optname=int)
  386. def setsockopt_w(self, space, level, optname, w_optval):
  387. """setsockopt(level, option, value)
  388. Set a socket option. See the Unix manual for level and option.
  389. The value argument can either be an integer or a string.
  390. """
  391. try:
  392. optval = space.c_int_w(w_optval)
  393. except OperationError as e:
  394. if e.async(space):
  395. raise
  396. optval = space.bytes_w(w_optval)
  397. try:
  398. self.sock.setsockopt(level, optname, optval)
  399. except SocketError as e:
  400. raise converted_error(space, e)
  401. return
  402. try:
  403. self.sock.setsockopt_int(level, optname, optval)
  404. except SocketError as e:
  405. raise converted_error(space, e)
  406. def settimeout_w(self, space, w_timeout):
  407. """settimeout(timeout)
  408. Set a timeout on socket operations. 'timeout' can be a float,
  409. giving in seconds, or None. Setting a timeout of None disables
  410. the timeout feature and is equivalent to setblocking(1).
  411. Setting a timeout of zero is the same as setblocking(0).
  412. """
  413. if space.is_w(w_timeout, space.w_None):
  414. timeout = -1.0
  415. else:
  416. timeout = space.float_w(w_timeout)
  417. if timeout < 0.0:
  418. raise oefmt(space.w_ValueError, "Timeout value out of range")
  419. self.sock.settimeout(timeout)
  420. @unwrap_spec(nbytes=int, flags=int)
  421. def recv_into_w(self, space, w_buffer, nbytes=0, flags=0):
  422. rwbuffer = space.getarg_w('w*', w_buffer)
  423. lgt = rwbuffer.getlength()
  424. if nbytes == 0 or nbytes > lgt:
  425. nbytes = lgt
  426. try:
  427. return space.wrap(self.sock.recvinto(rwbuffer, nbytes, flags))
  428. except SocketError as e:
  429. raise converted_error(space, e)
  430. @unwrap_spec(nbytes=int, flags=int)
  431. def recvfrom_into_w(self, space, w_buffer, nbytes=0, flags=0):
  432. rwbuffer = space.getarg_w('w*', w_buffer)
  433. lgt = rwbuffer.getlength()
  434. if nbytes == 0:
  435. nbytes = lgt
  436. elif nbytes > lgt:
  437. raise oefmt(space.w_ValueError,
  438. "nbytes is greater than the length of the buffer")
  439. try:
  440. readlgt, addr = self.sock.recvfrom_into(rwbuffer, nbytes, flags)
  441. if addr:
  442. w_addr = addr_as_object(addr, self.sock.fd, space)
  443. else:
  444. w_addr = space.w_None
  445. return space.newtuple([space.wrap(readlgt), w_addr])
  446. except SocketError as e:
  447. raise converted_error(space, e)
  448. @unwrap_spec(cmd=int)
  449. def ioctl_w(self, space, cmd, w_option):
  450. from rpython.rtyper.lltypesystem import rffi, lltype
  451. from rpython.rlib import rwin32
  452. from rpython.rlib.rsocket import _c
  453. recv_ptr = lltype.malloc(rwin32.LPDWORD.TO, 1, flavor='raw')
  454. try:
  455. if cmd == _c.SIO_RCVALL:
  456. value_size = rffi.sizeof(rffi.INTP)
  457. elif cmd == _c.SIO_KEEPALIVE_VALS:
  458. value_size = rffi.sizeof(_c.tcp_keepalive)
  459. else:
  460. raise oefmt(space.w_ValueError,
  461. "invalid ioctl command %d", cmd)
  462. value_ptr = lltype.malloc(rffi.VOIDP.TO, value_size, flavor='raw')
  463. try:
  464. if cmd == _c.SIO_RCVALL:
  465. option_ptr = rffi.cast(rffi.INTP, value_ptr)
  466. option_ptr[0] = space.int_w(w_option)
  467. elif cmd == _c.SIO_KEEPALIVE_VALS:
  468. w_onoff, w_time, w_interval = space.unpackiterable(w_option, 3)
  469. option_ptr = rffi.cast(lltype.Ptr(_c.tcp_keepalive), value_ptr)
  470. option_ptr.c_onoff = space.uint_w(w_onoff)
  471. option_ptr.c_keepalivetime = space.uint_w(w_time)
  472. option_ptr.c_keepaliveinterval = space.uint_w(w_interval)
  473. res = _c.WSAIoctl(
  474. self.sock.fd, cmd, value_ptr, value_size,
  475. rffi.NULL, 0, recv_ptr, rffi.NULL, rffi.NULL)
  476. if res < 0:
  477. raise converted_error(space, rsocket.last_error())
  478. finally:
  479. if value_ptr:
  480. lltype.free(value_ptr, flavor='raw')
  481. return space.wrap(recv_ptr[0])
  482. finally:
  483. lltype.free(recv_ptr, flavor='raw')
  484. @unwrap_spec(how="c_int")
  485. def shutdown_w(self, space, how):
  486. """shutdown(flag)
  487. Shut down the reading side of the socket (flag == SHUT_RD), the
  488. writing side of the socket (flag == SHUT_WR), or both ends
  489. (flag == SHUT_RDWR).
  490. """
  491. try:
  492. self.sock.shutdown(how)
  493. except SocketError as e:
  494. raise converted_error(space, e)
  495. #------------------------------------------------------------
  496. # Support functions for socket._socketobject
  497. usecount = 1
  498. def _reuse_w(self):
  499. """_resue()
  500. Increase the usecount of the socketobject.
  501. Intended only to be used by socket._socketobject
  502. """
  503. self.usecount += 1
  504. def _drop_w(self, space):
  505. """_drop()
  506. Decrease the usecount of the socketobject. If the
  507. usecount reaches 0 close the socket.
  508. Intended only to be used by socket._socketobject
  509. """
  510. self.usecount -= 1
  511. if self.usecount > 0:
  512. return
  513. self.close_w(space)
  514. app_makefile = gateway.applevel(r'''
  515. def makefile(self, mode="r", buffersize=-1):
  516. """makefile([mode[, buffersize]]) -> file object
  517. Return a regular file object corresponding to the socket.
  518. The mode and buffersize arguments are as for the built-in open() function.
  519. """
  520. import os
  521. newfd = os.dup(self.fileno())
  522. return os.fdopen(newfd, mode, buffersize)
  523. ''', filename =__file__).interphook('makefile')
  524. @unwrap_spec(family=int, type=int, proto=int)
  525. def newsocket(space, w_subtype, family=AF_INET,
  526. type=SOCK_STREAM, proto=0):
  527. self = space.allocate_instance(W_Socket, w_subtype)
  528. try:
  529. sock = RSocket(family, type, proto)
  530. except SocketError as e:
  531. raise converted_error(space, e)
  532. W_Socket.__init__(self, space, sock)
  533. return space.wrap(self)
  534. descr_socket_new = interp2app(newsocket)
  535. # ____________________________________________________________
  536. # Automatic shutdown()/close()
  537. # On some systems, the C library does not guarantee that when the program
  538. # finishes, all data sent so far is really sent even if the socket is not
  539. # explicitly closed. This behavior has been observed on Windows but not
  540. # on Linux, so far.
  541. NEED_EXPLICIT_CLOSE = (sys.platform == 'win32')
  542. class OpenRSockets(rweaklist.RWeakListMixin):
  543. pass
  544. class OpenRSocketsState:
  545. def __init__(self, space):
  546. self.openrsockets = OpenRSockets()
  547. self.openrsockets.initialize()
  548. def getopenrsockets(space):
  549. if NEED_EXPLICIT_CLOSE and space.config.translation.rweakref:
  550. return space.fromcache(OpenRSocketsState).openrsockets
  551. else:
  552. return None
  553. def register_socket(space, socket):
  554. openrsockets = getopenrsockets(space)
  555. if openrsockets is not None:
  556. openrsockets.add_handle(socket)
  557. def close_all_sockets(space):
  558. openrsockets = getopenrsockets(space)
  559. if openrsockets is not None:
  560. for sock_wref in openrsockets.get_all_handles():
  561. sock = sock_wref()
  562. if sock is not None:
  563. try:
  564. sock.close()
  565. except SocketError:
  566. pass
  567. # ____________________________________________________________
  568. # Error handling
  569. class SocketAPI:
  570. def __init__(self, space):
  571. self.w_error = space.new_exception_class(
  572. "_socket.error", space.w_IOError)
  573. self.w_herror = space.new_exception_class(
  574. "_socket.herror", self.w_error)
  575. self.w_gaierror = space.new_exception_class(
  576. "_socket.gaierror", self.w_error)
  577. self.w_timeout = space.new_exception_class(
  578. "_socket.timeout", self.w_error)
  579. self.errors_w = {'error': self.w_error,
  580. 'herror': self.w_herror,
  581. 'gaierror': self.w_gaierror,
  582. 'timeout': self.w_timeout,
  583. }
  584. def get_exception(self, applevelerrcls):
  585. return self.errors_w[applevelerrcls]
  586. def get_error(space, name):
  587. return space.fromcache(SocketAPI).get_exception(name)
  588. def converted_error(space, e):
  589. message = e.get_msg()
  590. w_exception_class = get_error(space, e.applevelerrcls)
  591. if isinstance(e, SocketErrorWithErrno):
  592. w_exception = space.call_function(w_exception_class, space.wrap(e.errno),
  593. space.wrap(message))
  594. else:
  595. w_exception = space.call_function(w_exception_class, space.wrap(message))
  596. return OperationError(w_exception_class, w_exception)
  597. # ____________________________________________________________
  598. socketmethodnames = """
  599. accept bind close connect connect_ex dup fileno
  600. getpeername getsockname getsockopt gettimeout listen makefile
  601. recv recvfrom send sendall sendto setblocking
  602. setsockopt settimeout shutdown _reuse _drop recv_into recvfrom_into
  603. """.split()
  604. # Remove non-implemented methods
  605. for name in ('dup',):
  606. if not hasattr(RSocket, name):
  607. socketmethodnames.remove(name)
  608. if hasattr(rsocket._c, 'WSAIoctl'):
  609. socketmethodnames.append('ioctl')
  610. socketmethods = {}
  611. for methodname in socketmethodnames:
  612. method = getattr(W_Socket, methodname + '_w')
  613. socketmethods[methodname] = interp2app(method)
  614. W_Socket.typedef = TypeDef("_socket.socket",
  615. __doc__ = """\
  616. socket([family[, type[, proto]]]) -> socket object
  617. Open a socket of the given type. The family argument specifies the
  618. address family; it defaults to AF_INET. The type argument specifies
  619. whether this is a stream (SOCK_STREAM, this is the default)
  620. or datagram (SOCK_DGRAM) socket. The protocol argument defaults to 0,
  621. specifying the default protocol. Keyword arguments are accepted.
  622. A socket object represents one endpoint of a network connection.
  623. Methods of socket objects (keyword arguments not allowed):
  624. accept() -- accept a connection, returning new socket and client address
  625. bind(addr) -- bind the socket to a local address
  626. close() -- close the socket
  627. connect(addr) -- connect the socket to a remote address
  628. connect_ex(addr) -- connect, return an error code instead of an exception
  629. dup() -- return a new socket object identical to the current one [*]
  630. fileno() -- return underlying file descriptor
  631. getpeername() -- return remote address [*]
  632. getsockname() -- return local address
  633. getsockopt(level, optname[, buflen]) -- get socket options
  634. gettimeout() -- return timeout or None
  635. listen(n) -- start listening for incoming connections
  636. makefile([mode, [bufsize]]) -- return a file object for the socket [*]
  637. recv(buflen[, flags]) -- receive data
  638. recvfrom(buflen[, flags]) -- receive data and sender's address
  639. sendall(data[, flags]) -- send all data
  640. send(data[, flags]) -- send data, may not send all of it
  641. sendto(data[, flags], addr) -- send data to a given address
  642. setblocking(0 | 1) -- set or clear the blocking I/O flag
  643. setsockopt(level, optname, value) -- set socket options
  644. settimeout(None | float) -- set or clear the timeout
  645. shutdown(how) -- shut down traffic in one or both directions
  646. [*] not available on all platforms!""",
  647. __new__ = descr_socket_new,
  648. __weakref__ = make_weakref_descr(W_Socket),
  649. __repr__ = interp2app(W_Socket.descr_repr),
  650. type = GetSetProperty(W_Socket.get_type_w),
  651. proto = GetSetProperty(W_Socket.get_proto_w),
  652. family = GetSetProperty(W_Socket.get_family_w),
  653. ** socketmethods
  654. )