_socketio.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. """
  2. SocketIO imported from socket module in Python 3.
  3. Copyright (c) 2001-2013 Python Software Foundation; All Rights Reserved.
  4. """
  5. from socket import *
  6. import io
  7. import errno
  8. __all__ = ['SocketIO']
  9. EINTR = errno.EINTR
  10. _blocking_errnos = (errno.EAGAIN, errno.EWOULDBLOCK)
  11. class SocketIO(io.RawIOBase):
  12. """Raw I/O implementation for stream sockets.
  13. This class supports the makefile() method on sockets. It provides
  14. the raw I/O interface on top of a socket object.
  15. """
  16. # One might wonder why not let FileIO do the job instead. There are two
  17. # main reasons why FileIO is not adapted:
  18. # - it wouldn't work under Windows (where you can't used read() and
  19. # write() on a socket handle)
  20. # - it wouldn't work with socket timeouts (FileIO would ignore the
  21. # timeout and consider the socket non-blocking)
  22. # XXX More docs
  23. def __init__(self, sock, mode):
  24. if mode not in ("r", "w", "rw", "rb", "wb", "rwb"):
  25. raise ValueError("invalid mode: %r" % mode)
  26. io.RawIOBase.__init__(self)
  27. self._sock = sock
  28. if "b" not in mode:
  29. mode += "b"
  30. self._mode = mode
  31. self._reading = "r" in mode
  32. self._writing = "w" in mode
  33. self._timeout_occurred = False
  34. def readinto(self, b):
  35. """Read up to len(b) bytes into the writable buffer *b* and return
  36. the number of bytes read. If the socket is non-blocking and no bytes
  37. are available, None is returned.
  38. If *b* is non-empty, a 0 return value indicates that the connection
  39. was shutdown at the other end.
  40. """
  41. self._checkClosed()
  42. self._checkReadable()
  43. if self._timeout_occurred:
  44. raise IOError("cannot read from timed out object")
  45. while True:
  46. try:
  47. return self._sock.recv_into(b)
  48. except timeout:
  49. self._timeout_occurred = True
  50. raise
  51. except error as e:
  52. n = e.args[0]
  53. if n == EINTR:
  54. continue
  55. if n in _blocking_errnos:
  56. return None
  57. raise
  58. def write(self, b):
  59. """Write the given bytes or bytearray object *b* to the socket
  60. and return the number of bytes written. This can be less than
  61. len(b) if not all data could be written. If the socket is
  62. non-blocking and no bytes could be written None is returned.
  63. """
  64. self._checkClosed()
  65. self._checkWritable()
  66. try:
  67. return self._sock.send(b)
  68. except error as e:
  69. # XXX what about EINTR?
  70. if e.args[0] in _blocking_errnos:
  71. return None
  72. raise
  73. def readable(self):
  74. """True if the SocketIO is open for reading.
  75. """
  76. if self.closed:
  77. raise ValueError("I/O operation on closed socket.")
  78. return self._reading
  79. def writable(self):
  80. """True if the SocketIO is open for writing.
  81. """
  82. if self.closed:
  83. raise ValueError("I/O operation on closed socket.")
  84. return self._writing
  85. def seekable(self):
  86. """True if the SocketIO is open for seeking.
  87. """
  88. if self.closed:
  89. raise ValueError("I/O operation on closed socket.")
  90. return super().seekable()
  91. def fileno(self):
  92. """Return the file descriptor of the underlying socket.
  93. """
  94. self._checkClosed()
  95. return self._sock.fileno()
  96. @property
  97. def name(self):
  98. if not self.closed:
  99. return self.fileno()
  100. else:
  101. return -1
  102. @property
  103. def mode(self):
  104. return self._mode
  105. def close(self):
  106. """Close the SocketIO object. This doesn't close the underlying
  107. socket, except if all references to it have disappeared.
  108. """
  109. if self.closed:
  110. return
  111. io.RawIOBase.close(self)
  112. self._sock._decref_socketios()
  113. self._sock = None