os.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. """
  2. Low-level operating system functions from :mod:`os`.
  3. Cooperative I/O
  4. ===============
  5. This module provides cooperative versions of :func:`os.read` and
  6. :func:`os.write`. These functions are *not* monkey-patched; you
  7. must explicitly call them or monkey patch them yourself.
  8. POSIX functions
  9. ---------------
  10. On POSIX, non-blocking IO is available.
  11. - :func:`nb_read`
  12. - :func:`nb_write`
  13. - :func:`make_nonblocking`
  14. All Platforms
  15. -------------
  16. On non-POSIX platforms (e.g., Windows), non-blocking IO is not
  17. available. On those platforms (and on POSIX), cooperative IO can
  18. be done with the threadpool.
  19. - :func:`tp_read`
  20. - :func:`tp_write`
  21. Child Processes
  22. ===============
  23. The functions :func:`fork` and (on POSIX) :func:`forkpty` and :func:`waitpid` can be used
  24. to manage child processes.
  25. .. warning::
  26. Forking a process that uses greenlets does not eliminate all non-running
  27. greenlets. Any that were scheduled in the hub of the forking thread in the parent
  28. remain scheduled in the child; compare this to how normal threads operate. (This behaviour
  29. may change is a subsequent major release.)
  30. """
  31. from __future__ import absolute_import
  32. import os
  33. import sys
  34. from gevent.hub import get_hub, reinit
  35. from gevent._compat import PY3
  36. from gevent._util import copy_globals
  37. import errno
  38. EAGAIN = getattr(errno, 'EAGAIN', 11)
  39. try:
  40. import fcntl
  41. except ImportError:
  42. fcntl = None
  43. __implements__ = ['fork']
  44. __extensions__ = ['tp_read', 'tp_write']
  45. _read = os.read
  46. _write = os.write
  47. ignored_errors = [EAGAIN, errno.EINTR]
  48. if fcntl:
  49. __extensions__ += ['make_nonblocking', 'nb_read', 'nb_write']
  50. def make_nonblocking(fd):
  51. """Put the file descriptor *fd* into non-blocking mode if possible.
  52. :return: A boolean value that evaluates to True if successful."""
  53. flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0)
  54. if not bool(flags & os.O_NONBLOCK):
  55. fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
  56. return True
  57. def nb_read(fd, n):
  58. """Read up to `n` bytes from file descriptor `fd`. Return a string
  59. containing the bytes read. If end-of-file is reached, an empty string
  60. is returned.
  61. The descriptor must be in non-blocking mode.
  62. """
  63. hub, event = None, None
  64. while True:
  65. try:
  66. return _read(fd, n)
  67. except OSError as e:
  68. if e.errno not in ignored_errors:
  69. raise
  70. if not PY3:
  71. sys.exc_clear()
  72. if hub is None:
  73. hub = get_hub()
  74. event = hub.loop.io(fd, 1)
  75. hub.wait(event)
  76. def nb_write(fd, buf):
  77. """Write bytes from buffer `buf` to file descriptor `fd`. Return the
  78. number of bytes written.
  79. The file descriptor must be in non-blocking mode.
  80. """
  81. hub, event = None, None
  82. while True:
  83. try:
  84. return _write(fd, buf)
  85. except OSError as e:
  86. if e.errno not in ignored_errors:
  87. raise
  88. if not PY3:
  89. sys.exc_clear()
  90. if hub is None:
  91. hub = get_hub()
  92. event = hub.loop.io(fd, 2)
  93. hub.wait(event)
  94. def tp_read(fd, n):
  95. """Read up to *n* bytes from file descriptor *fd*. Return a string
  96. containing the bytes read. If end-of-file is reached, an empty string
  97. is returned.
  98. Reading is done using the threadpool.
  99. """
  100. return get_hub().threadpool.apply(_read, (fd, n))
  101. def tp_write(fd, buf):
  102. """Write bytes from buffer *buf* to file descriptor *fd*. Return the
  103. number of bytes written.
  104. Writing is done using the threadpool.
  105. """
  106. return get_hub().threadpool.apply(_write, (fd, buf))
  107. if hasattr(os, 'fork'):
  108. # pylint:disable=function-redefined,redefined-outer-name
  109. _raw_fork = os.fork
  110. def fork_gevent():
  111. """
  112. Forks the process using :func:`os.fork` and prepares the
  113. child process to continue using gevent before returning.
  114. .. note::
  115. The PID returned by this function may not be waitable with
  116. either the original :func:`os.waitpid` or this module's
  117. :func:`waitpid` and it may not generate SIGCHLD signals if
  118. libev child watchers are or ever have been in use. For
  119. example, the :mod:`gevent.subprocess` module uses libev
  120. child watchers (which parts of gevent use libev child
  121. watchers is subject to change at any time). Most
  122. applications should use :func:`fork_and_watch`, which is
  123. monkey-patched as the default replacement for
  124. :func:`os.fork` and implements the ``fork`` function of
  125. this module by default, unless the environment variable
  126. ``GEVENT_NOWAITPID`` is defined before this module is
  127. imported.
  128. .. versionadded:: 1.1b2
  129. """
  130. result = _raw_fork()
  131. if not result:
  132. reinit()
  133. return result
  134. def fork():
  135. """
  136. A wrapper for :func:`fork_gevent` for non-POSIX platforms.
  137. """
  138. return fork_gevent()
  139. if hasattr(os, 'forkpty'):
  140. _raw_forkpty = os.forkpty
  141. def forkpty_gevent():
  142. """
  143. Forks the process using :func:`os.forkpty` and prepares the
  144. child process to continue using gevent before returning.
  145. Returns a tuple (pid, master_fd). The `master_fd` is *not* put into
  146. non-blocking mode.
  147. Availability: Some Unix systems.
  148. .. seealso:: This function has the same limitations as :func:`fork_gevent`.
  149. .. versionadded:: 1.1b5
  150. """
  151. pid, master_fd = _raw_forkpty()
  152. if not pid:
  153. reinit()
  154. return pid, master_fd
  155. forkpty = forkpty_gevent
  156. __implements__.append('forkpty')
  157. __extensions__.append("forkpty_gevent")
  158. if hasattr(os, 'WNOWAIT') or hasattr(os, 'WNOHANG'):
  159. # We can only do this on POSIX
  160. import time
  161. _waitpid = os.waitpid
  162. _WNOHANG = os.WNOHANG
  163. # replaced by the signal module.
  164. _on_child_hook = lambda: None
  165. # {pid -> watcher or tuple(pid, rstatus, timestamp)}
  166. _watched_children = {}
  167. def _on_child(watcher, callback):
  168. # XXX: Could handle tracing here by not stopping
  169. # until the pid is terminated
  170. watcher.stop()
  171. _watched_children[watcher.pid] = (watcher.pid, watcher.rstatus, time.time())
  172. if callback:
  173. callback(watcher)
  174. # dispatch an "event"; used by gevent.signal.signal
  175. _on_child_hook()
  176. # now is as good a time as any to reap children
  177. _reap_children()
  178. def _reap_children(timeout=60):
  179. # Remove all the dead children that haven't been waited on
  180. # for the *timeout* seconds.
  181. # Some platforms queue delivery of SIGCHLD for all children that die;
  182. # in that case, a well-behaved application should call waitpid() for each
  183. # signal.
  184. # Some platforms (linux) only guarantee one delivery if multiple children
  185. # die. On that platform, the well-behave application calls waitpid() in a loop
  186. # until it gets back -1, indicating no more dead children need to be waited for.
  187. # In either case, waitpid should be called the same number of times as dead children,
  188. # thus removing all the watchers when a SIGCHLD arrives. The (generous) timeout
  189. # is to work with applications that neglect to call waitpid and prevent "unlimited"
  190. # growth.
  191. # Note that we don't watch for the case of pid wraparound. That is, we fork a new
  192. # child with the same pid as an existing watcher, but the child is already dead,
  193. # just not waited on yet.
  194. now = time.time()
  195. oldest_allowed = now - timeout
  196. dead = [pid for pid, val
  197. in _watched_children.items()
  198. if isinstance(val, tuple) and val[2] < oldest_allowed]
  199. for pid in dead:
  200. del _watched_children[pid]
  201. def waitpid(pid, options):
  202. """
  203. Wait for a child process to finish.
  204. If the child process was spawned using
  205. :func:`fork_and_watch`, then this function behaves
  206. cooperatively. If not, it *may* have race conditions; see
  207. :func:`fork_gevent` for more information.
  208. The arguments are as for the underlying
  209. :func:`os.waitpid`. Some combinations of *options* may not
  210. be supported cooperatively (as of 1.1 that includes
  211. WUNTRACED). Using a *pid* of 0 to request waiting on only processes
  212. from the current process group is not cooperative.
  213. Availability: POSIX.
  214. .. versionadded:: 1.1b1
  215. .. versionchanged:: 1.2a1
  216. More cases are handled in a cooperative manner.
  217. """
  218. # XXX Does not handle tracing children
  219. # So long as libev's loop doesn't run, it's OK to add
  220. # child watchers. The SIGCHLD handler only feeds events
  221. # for the next iteration of the loop to handle. (And the
  222. # signal handler itself is only called from the next loop
  223. # iteration.)
  224. if pid <= 0:
  225. # magic functions for multiple children.
  226. if pid == -1:
  227. # Any child. If we have one that we're watching and that finished,
  228. # we will use that one. Otherwise, let the OS take care of it.
  229. for k, v in _watched_children.items():
  230. if isinstance(v, tuple):
  231. pid = k
  232. break
  233. if pid <= 0:
  234. # We didn't have one that was ready. If there are
  235. # no funky options set, and the pid was -1
  236. # (meaning any process, not 0, which means process
  237. # group--- libev doesn't know about process
  238. # groups) then we can use a child watcher of pid 0; otherwise,
  239. # pass through to the OS.
  240. if pid == -1 and options == 0:
  241. hub = get_hub()
  242. watcher = hub.loop.child(0, False)
  243. hub.wait(watcher)
  244. return watcher.rpid, watcher.rstatus
  245. # There were funky options/pid, so we must go to the OS.
  246. return _waitpid(pid, options)
  247. if pid in _watched_children:
  248. # yes, we're watching it
  249. if options & _WNOHANG or isinstance(_watched_children[pid], tuple):
  250. # We're either asked not to block, or it already finished, in which
  251. # case blocking doesn't matter
  252. result = _watched_children[pid]
  253. if isinstance(result, tuple):
  254. # it finished. libev child watchers
  255. # are one-shot
  256. del _watched_children[pid]
  257. return result[:2]
  258. # it's not finished
  259. return (0, 0)
  260. else:
  261. # Ok, we need to "block". Do so via a watcher so that we're
  262. # cooperative. We know it's our child, etc, so this should work.
  263. watcher = _watched_children[pid]
  264. # We can't start a watcher that's already started,
  265. # so we can't reuse the existing watcher.
  266. new_watcher = watcher.loop.child(pid, False)
  267. get_hub().wait(new_watcher)
  268. # Ok, so now the new watcher is done. That means
  269. # the old watcher's callback (_on_child) should
  270. # have fired, potentially taking this child out of
  271. # _watched_children (but that could depend on how
  272. # many callbacks there were to run, so use the
  273. # watcher object directly; libev sets all the
  274. # watchers at the same time).
  275. return watcher.rpid, watcher.rstatus
  276. # we're not watching it and it may not even be our child,
  277. # so we must go to the OS to be sure to get the right semantics (exception)
  278. return _waitpid(pid, options)
  279. def fork_and_watch(callback=None, loop=None, ref=False, fork=fork_gevent):
  280. """
  281. Fork a child process and start a child watcher for it in the parent process.
  282. This call cooperates with :func:`waitpid` to enable cooperatively waiting
  283. for children to finish. When monkey-patching, these functions are patched in as
  284. :func:`os.fork` and :func:`os.waitpid`, respectively.
  285. In the child process, this function calls :func:`gevent.hub.reinit` before returning.
  286. Availability: POSIX.
  287. :keyword callback: If given, a callable that will be called with the child watcher
  288. when the child finishes.
  289. :keyword loop: The loop to start the watcher in. Defaults to the
  290. loop of the current hub.
  291. :keyword fork: The fork function. Defaults to :func:`the one defined in this
  292. module <gevent.os.fork_gevent>` (which automatically calls :func:`gevent.hub.reinit`).
  293. Pass the builtin :func:`os.fork` function if you do not need to
  294. initialize gevent in the child process.
  295. .. versionadded:: 1.1b1
  296. .. seealso::
  297. :func:`gevent.monkey.get_original` To access the builtin :func:`os.fork`.
  298. """
  299. pid = fork()
  300. if pid:
  301. # parent
  302. loop = loop or get_hub().loop
  303. watcher = loop.child(pid, ref=ref)
  304. _watched_children[pid] = watcher
  305. watcher.start(_on_child, watcher, callback)
  306. return pid
  307. __extensions__.append('fork_and_watch')
  308. __extensions__.append('fork_gevent')
  309. if 'forkpty' in __implements__:
  310. def forkpty_and_watch(callback=None, loop=None, ref=False, forkpty=forkpty_gevent):
  311. """
  312. Like :func:`fork_and_watch`, except using :func:`forkpty_gevent`.
  313. Availability: Some Unix systems.
  314. .. versionadded:: 1.1b5
  315. """
  316. result = []
  317. def _fork():
  318. pid_and_fd = forkpty()
  319. result.append(pid_and_fd)
  320. return pid_and_fd[0]
  321. fork_and_watch(callback, loop, ref, _fork)
  322. return result[0]
  323. __extensions__.append('forkpty_and_watch')
  324. # Watch children by default
  325. if not os.getenv('GEVENT_NOWAITPID'):
  326. # Broken out into separate functions instead of simple name aliases
  327. # for documentation purposes.
  328. def fork(*args, **kwargs):
  329. """
  330. Forks a child process and starts a child watcher for it in the
  331. parent process so that ``waitpid`` and SIGCHLD work as expected.
  332. This implementation of ``fork`` is a wrapper for :func:`fork_and_watch`
  333. when the environment variable ``GEVENT_NOWAITPID`` is *not* defined.
  334. This is the default and should be used by most applications.
  335. .. versionchanged:: 1.1b2
  336. """
  337. # take any args to match fork_and_watch
  338. return fork_and_watch(*args, **kwargs)
  339. if 'forkpty' in __implements__:
  340. def forkpty(*args, **kwargs):
  341. """
  342. Like :func:`fork`, but using :func:`forkpty_gevent`.
  343. This implementation of ``forkpty`` is a wrapper for :func:`forkpty_and_watch`
  344. when the environment variable ``GEVENT_NOWAITPID`` is *not* defined.
  345. This is the default and should be used by most applications.
  346. .. versionadded:: 1.1b5
  347. """
  348. # take any args to match fork_and_watch
  349. return forkpty_and_watch(*args, **kwargs)
  350. __implements__.append("waitpid")
  351. else:
  352. def fork():
  353. """
  354. Forks a child process, initializes gevent in the child,
  355. but *does not* prepare the parent to wait for the child or receive SIGCHLD.
  356. This implementation of ``fork`` is a wrapper for :func:`fork_gevent`
  357. when the environment variable ``GEVENT_NOWAITPID`` *is* defined.
  358. This is not recommended for most applications.
  359. """
  360. return fork_gevent()
  361. if 'forkpty' in __implements__:
  362. def forkpty():
  363. """
  364. Like :func:`fork`, but using :func:`os.forkpty`
  365. This implementation of ``forkpty`` is a wrapper for :func:`forkpty_gevent`
  366. when the environment variable ``GEVENT_NOWAITPID`` *is* defined.
  367. This is not recommended for most applications.
  368. .. versionadded:: 1.1b5
  369. """
  370. return forkpty_gevent()
  371. __extensions__.append("waitpid")
  372. else:
  373. __implements__.remove('fork')
  374. __imports__ = copy_globals(os, globals(),
  375. names_to_ignore=__implements__ + __extensions__,
  376. dunder_names_to_keep=())
  377. __all__ = list(set(__implements__ + __extensions__))