25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
2.8KB

  1. os_orig = __import__("os")
  2. import errno
  3. socket = __import__("socket")
  4. from eventlet import greenio
  5. from eventlet.support import get_errno
  6. from eventlet import greenthread
  7. from eventlet import hubs
  8. from eventlet.patcher import slurp_properties
  9. __all__ = os_orig.__all__
  10. __patched__ = ['fdopen', 'read', 'write', 'wait', 'waitpid', 'open']
  11. slurp_properties(
  12. os_orig,
  13. globals(),
  14. ignore=__patched__,
  15. srckeys=dir(os_orig))
  16. def fdopen(fd, *args, **kw):
  17. """fdopen(fd [, mode='r' [, bufsize]]) -> file_object
  18. Return an open file object connected to a file descriptor."""
  19. if not isinstance(fd, int):
  20. raise TypeError('fd should be int, not %r' % fd)
  21. try:
  22. return greenio.GreenPipe(fd, *args, **kw)
  23. except IOError as e:
  24. raise OSError(*e.args)
  25. __original_read__ = os_orig.read
  26. def read(fd, n):
  27. """read(fd, buffersize) -> string
  28. Read a file descriptor."""
  29. while True:
  30. try:
  31. return __original_read__(fd, n)
  32. except (OSError, IOError) as e:
  33. if get_errno(e) != errno.EAGAIN:
  34. raise
  35. except socket.error as e:
  36. if get_errno(e) == errno.EPIPE:
  37. return ''
  38. raise
  39. try:
  40. hubs.trampoline(fd, read=True)
  41. except hubs.IOClosed:
  42. return ''
  43. __original_write__ = os_orig.write
  44. def write(fd, st):
  45. """write(fd, string) -> byteswritten
  46. Write a string to a file descriptor.
  47. """
  48. while True:
  49. try:
  50. return __original_write__(fd, st)
  51. except (OSError, IOError) as e:
  52. if get_errno(e) != errno.EAGAIN:
  53. raise
  54. except socket.error as e:
  55. if get_errno(e) != errno.EPIPE:
  56. raise
  57. hubs.trampoline(fd, write=True)
  58. def wait():
  59. """wait() -> (pid, status)
  60. Wait for completion of a child process."""
  61. return waitpid(0, 0)
  62. __original_waitpid__ = os_orig.waitpid
  63. def waitpid(pid, options):
  64. """waitpid(...)
  65. waitpid(pid, options) -> (pid, status)
  66. Wait for completion of a given child process."""
  67. if options & os_orig.WNOHANG != 0:
  68. return __original_waitpid__(pid, options)
  69. else:
  70. new_options = options | os_orig.WNOHANG
  71. while True:
  72. rpid, status = __original_waitpid__(pid, new_options)
  73. if rpid and status >= 0:
  74. return rpid, status
  75. greenthread.sleep(0.01)
  76. __original_open__ = os_orig.open
  77. def open(file, flags, mode=0o777, dir_fd=None):
  78. """ Wrap os.open
  79. This behaves identically, but collaborates with
  80. the hub's notify_opened protocol.
  81. """
  82. if dir_fd is not None:
  83. fd = __original_open__(file, flags, mode, dir_fd=dir_fd)
  84. else:
  85. fd = __original_open__(file, flags, mode)
  86. hubs.notify_opened(fd)
  87. return fd