/pypy/module/_socket/interp_func.py

https://bitbucket.org/pypy/pypy/ · Python · 316 lines · 306 code · 4 blank · 6 comment · 2 complexity · 99d8cc841837e5500c67e7806f2ca148 MD5 · raw file

  1. from rpython.rlib import rsocket
  2. from rpython.rlib.rsocket import SocketError, INVALID_SOCKET
  3. from rpython.rlib.rarithmetic import intmask
  4. from pypy.interpreter.error import OperationError, oefmt
  5. from pypy.interpreter.gateway import unwrap_spec, WrappedDefault
  6. from pypy.module._socket.interp_socket import (
  7. converted_error, W_Socket, addr_as_object, ipaddr_from_object
  8. )
  9. def gethostname(space):
  10. """gethostname() -> string
  11. Return the current host name.
  12. """
  13. try:
  14. res = rsocket.gethostname()
  15. except SocketError as e:
  16. raise converted_error(space, e)
  17. return space.wrap(res)
  18. @unwrap_spec(host=str)
  19. def gethostbyname(space, host):
  20. """gethostbyname(host) -> address
  21. Return the IP address (a string of the form '255.255.255.255') for a host.
  22. """
  23. try:
  24. addr = rsocket.gethostbyname(host)
  25. ip = addr.get_host()
  26. except SocketError as e:
  27. raise converted_error(space, e)
  28. return space.wrap(ip)
  29. def common_wrapgethost(space, (name, aliases, address_list)):
  30. aliases = [space.wrap(alias) for alias in aliases]
  31. address_list = [space.wrap(addr.get_host()) for addr in address_list]
  32. return space.newtuple([space.wrap(name),
  33. space.newlist(aliases),
  34. space.newlist(address_list)])
  35. @unwrap_spec(host=str)
  36. def gethostbyname_ex(space, host):
  37. """gethostbyname_ex(host) -> (name, aliaslist, addresslist)
  38. Return the true host name, a list of aliases, and a list of IP addresses,
  39. for a host. The host argument is a string giving a host name or IP number.
  40. """
  41. try:
  42. res = rsocket.gethostbyname_ex(host)
  43. except SocketError as e:
  44. raise converted_error(space, e)
  45. return common_wrapgethost(space, res)
  46. @unwrap_spec(host=str)
  47. def gethostbyaddr(space, host):
  48. """gethostbyaddr(host) -> (name, aliaslist, addresslist)
  49. Return the true host name, a list of aliases, and a list of IP addresses,
  50. for a host. The host argument is a string giving a host name or IP number.
  51. """
  52. try:
  53. res = rsocket.gethostbyaddr(host)
  54. except SocketError as e:
  55. raise converted_error(space, e)
  56. return common_wrapgethost(space, res)
  57. @unwrap_spec(name=str, w_proto = WrappedDefault(None))
  58. def getservbyname(space, name, w_proto):
  59. """getservbyname(servicename[, protocolname]) -> integer
  60. Return a port number from a service name and protocol name.
  61. The optional protocol name, if given, should be 'tcp' or 'udp',
  62. otherwise any protocol will match.
  63. """
  64. if space.is_w(w_proto, space.w_None):
  65. proto = None
  66. else:
  67. proto = space.str_w(w_proto)
  68. try:
  69. port = rsocket.getservbyname(name, proto)
  70. except SocketError as e:
  71. raise converted_error(space, e)
  72. return space.wrap(port)
  73. @unwrap_spec(port=int, w_proto = WrappedDefault(None))
  74. def getservbyport(space, port, w_proto):
  75. """getservbyport(port[, protocolname]) -> string
  76. Return the service name from a port number and protocol name.
  77. The optional protocol name, if given, should be 'tcp' or 'udp',
  78. otherwise any protocol will match.
  79. """
  80. if space.is_w(w_proto, space.w_None):
  81. proto = None
  82. else:
  83. proto = space.str_w(w_proto)
  84. if port < 0 or port > 0xffff:
  85. raise oefmt(space.w_ValueError, "getservbyport: port must be 0-65535.")
  86. try:
  87. service = rsocket.getservbyport(port, proto)
  88. except SocketError as e:
  89. raise converted_error(space, e)
  90. return space.wrap(service)
  91. @unwrap_spec(name=str)
  92. def getprotobyname(space, name):
  93. """getprotobyname(name) -> integer
  94. Return the protocol number for the named protocol. (Rarely used.)
  95. """
  96. try:
  97. proto = rsocket.getprotobyname(name)
  98. except SocketError as e:
  99. raise converted_error(space, e)
  100. return space.wrap(proto)
  101. @unwrap_spec(flags=int)
  102. def getnameinfo(space, w_sockaddr, flags):
  103. """getnameinfo(sockaddr, flags) --> (host, port)
  104. Get host and port for a sockaddr."""
  105. try:
  106. addr = ipaddr_from_object(space, w_sockaddr)
  107. host, servport = rsocket.getnameinfo(addr, flags)
  108. except SocketError as e:
  109. raise converted_error(space, e)
  110. return space.newtuple([space.wrap(host), space.wrap(servport)])
  111. @unwrap_spec(fd=int, family=int, type=int, proto=int)
  112. def fromfd(space, fd, family, type, proto=0):
  113. """fromfd(fd, family, type[, proto]) -> socket object
  114. Create a socket object from the given file descriptor.
  115. The remaining arguments are the same as for socket().
  116. """
  117. try:
  118. sock = rsocket.fromfd(fd, family, type, proto)
  119. except SocketError as e:
  120. raise converted_error(space, e)
  121. return space.wrap(W_Socket(space, sock))
  122. @unwrap_spec(family=int, type=int, proto=int)
  123. def socketpair(space, family=rsocket.socketpair_default_family,
  124. type =rsocket.SOCK_STREAM,
  125. proto =0):
  126. """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
  127. Create a pair of socket objects from the sockets returned by the platform
  128. socketpair() function.
  129. The arguments are the same as for socket() except the default family is
  130. AF_UNIX if defined on the platform; otherwise, the default is AF_INET.
  131. """
  132. try:
  133. sock1, sock2 = rsocket.socketpair(family, type, proto)
  134. except SocketError as e:
  135. raise converted_error(space, e)
  136. return space.newtuple([
  137. space.wrap(W_Socket(space, sock1)),
  138. space.wrap(W_Socket(space, sock2))
  139. ])
  140. # The following 4 functions refuse all negative numbers, like CPython 2.6.
  141. # They could also check that the argument is not too large, but CPython 2.6
  142. # is not doing that consistently.
  143. @unwrap_spec(x="c_uint")
  144. def ntohs(space, x):
  145. """ntohs(integer) -> integer
  146. Convert a 16-bit integer from network to host byte order.
  147. """
  148. return space.wrap(rsocket.ntohs(intmask(x)))
  149. @unwrap_spec(x="c_uint")
  150. def ntohl(space, x):
  151. """ntohl(integer) -> integer
  152. Convert a 32-bit integer from network to host byte order.
  153. """
  154. return space.wrap(rsocket.ntohl(x))
  155. @unwrap_spec(x="c_uint")
  156. def htons(space, x):
  157. """htons(integer) -> integer
  158. Convert a 16-bit integer from host to network byte order.
  159. """
  160. return space.wrap(rsocket.htons(intmask(x)))
  161. @unwrap_spec(x="c_uint")
  162. def htonl(space, x):
  163. """htonl(integer) -> integer
  164. Convert a 32-bit integer from host to network byte order.
  165. """
  166. return space.wrap(rsocket.htonl(x))
  167. @unwrap_spec(ip=str)
  168. def inet_aton(space, ip):
  169. """inet_aton(string) -> packed 32-bit IP representation
  170. Convert an IP address in string format (123.45.67.89) to the 32-bit packed
  171. binary format used in low-level network functions.
  172. """
  173. try:
  174. buf = rsocket.inet_aton(ip)
  175. except SocketError as e:
  176. raise converted_error(space, e)
  177. return space.newbytes(buf)
  178. @unwrap_spec(packed=str)
  179. def inet_ntoa(space, packed):
  180. """inet_ntoa(packed_ip) -> ip_address_string
  181. Convert an IP address from 32-bit packed binary format to string format
  182. """
  183. try:
  184. ip = rsocket.inet_ntoa(packed)
  185. except SocketError as e:
  186. raise converted_error(space, e)
  187. return space.wrap(ip)
  188. @unwrap_spec(family=int, ip=str)
  189. def inet_pton(space, family, ip):
  190. """inet_pton(family, ip) -> packed IP address string
  191. Convert an IP address from string format to a packed string suitable
  192. for use with low-level network functions.
  193. """
  194. try:
  195. buf = rsocket.inet_pton(family, ip)
  196. except SocketError as e:
  197. raise converted_error(space, e)
  198. return space.newbytes(buf)
  199. @unwrap_spec(family=int, packed=str)
  200. def inet_ntop(space, family, packed):
  201. """inet_ntop(family, packed_ip) -> string formatted IP address
  202. Convert a packed IP address of the given family to string format.
  203. """
  204. try:
  205. ip = rsocket.inet_ntop(family, packed)
  206. except SocketError as e:
  207. raise converted_error(space, e)
  208. except ValueError:
  209. raise oefmt(space.w_ValueError,
  210. "invalid length of packed IP address string")
  211. return space.wrap(ip)
  212. @unwrap_spec(family=int, socktype=int, proto=int, flags=int)
  213. def getaddrinfo(space, w_host, w_port,
  214. family=rsocket.AF_UNSPEC, socktype=0, proto=0, flags=0):
  215. """getaddrinfo(host, port [, family, socktype, proto, flags])
  216. -> list of (family, socktype, proto, canonname, sockaddr)
  217. Resolve host and port into addrinfo struct.
  218. """
  219. # host can be None, string or unicode
  220. if space.is_w(w_host, space.w_None):
  221. host = None
  222. elif space.isinstance_w(w_host, space.w_str):
  223. host = space.bytes_w(w_host)
  224. elif space.isinstance_w(w_host, space.w_unicode):
  225. w_shost = space.call_method(w_host, "encode", space.wrap("idna"))
  226. host = space.bytes_w(w_shost)
  227. else:
  228. raise oefmt(space.w_TypeError,
  229. "getaddrinfo() argument 1 must be string or None")
  230. # port can be None, int or string
  231. if space.is_w(w_port, space.w_None):
  232. port = None
  233. elif space.isinstance_w(w_port, space.w_int) or space.isinstance_w(w_port, space.w_long):
  234. port = str(space.int_w(w_port))
  235. elif space.isinstance_w(w_port, space.w_str):
  236. port = space.bytes_w(w_port)
  237. else:
  238. raise oefmt(space.w_TypeError,
  239. "getaddrinfo() argument 2 must be integer or string")
  240. try:
  241. lst = rsocket.getaddrinfo(host, port, family, socktype,
  242. proto, flags)
  243. except SocketError as e:
  244. raise converted_error(space, e)
  245. lst1 = [space.newtuple([space.wrap(family),
  246. space.wrap(socktype),
  247. space.wrap(protocol),
  248. space.wrap(canonname),
  249. addr_as_object(addr, INVALID_SOCKET, space)]) # -1 as per cpython
  250. for (family, socktype, protocol, canonname, addr) in lst]
  251. return space.newlist(lst1)
  252. def getdefaulttimeout(space):
  253. """getdefaulttimeout() -> timeout
  254. Returns the default timeout in floating seconds for new socket objects.
  255. A value of None indicates that new socket objects have no timeout.
  256. When the socket module is first imported, the default is None.
  257. """
  258. timeout = rsocket.getdefaulttimeout()
  259. if timeout < 0.0:
  260. return space.w_None
  261. return space.wrap(timeout)
  262. def setdefaulttimeout(space, w_timeout):
  263. if space.is_w(w_timeout, space.w_None):
  264. timeout = -1.0
  265. else:
  266. timeout = space.float_w(w_timeout)
  267. if timeout < 0.0:
  268. raise oefmt(space.w_ValueError, "Timeout value out of range")
  269. rsocket.setdefaulttimeout(timeout)