File: os.py

package info (click to toggle)
python-eventlet 0.26.1-7%2Bdeb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 2,916 kB
  • sloc: python: 24,898; makefile: 98
file content (120 lines) | stat: -rw-r--r-- 3,399 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
os_orig = __import__("os")
import errno
socket = __import__("socket")

from eventlet import greenio
from eventlet.support import get_errno
from eventlet import greenthread
from eventlet import hubs
from eventlet.patcher import slurp_properties

__all__ = os_orig.__all__
__patched__ = ['fdopen', 'read', 'write', 'wait', 'waitpid', 'open']

slurp_properties(
    os_orig,
    globals(),
    ignore=__patched__,
    srckeys=dir(os_orig))


def fdopen(fd, *args, **kw):
    """fdopen(fd [, mode='r' [, bufsize]]) -> file_object

    Return an open file object connected to a file descriptor."""
    if not isinstance(fd, int):
        raise TypeError('fd should be int, not %r' % fd)
    try:
        return greenio.GreenPipe(fd, *args, **kw)
    except IOError as e:
        raise OSError(*e.args)

__original_read__ = os_orig.read


def read(fd, n):
    """read(fd, buffersize) -> string

    Read a file descriptor."""
    while True:
        try:
            return __original_read__(fd, n)
        except (OSError, IOError) as e:
            if get_errno(e) != errno.EAGAIN:
                raise
        except socket.error as e:
            if get_errno(e) == errno.EPIPE:
                return ''
            raise
        try:
            hubs.trampoline(fd, read=True)
        except hubs.IOClosed:
            return ''

__original_write__ = os_orig.write


def write(fd, st):
    """write(fd, string) -> byteswritten

    Write a string to a file descriptor.
    """
    while True:
        try:
            return __original_write__(fd, st)
        except (OSError, IOError) as e:
            if get_errno(e) != errno.EAGAIN:
                raise
        except socket.error as e:
            if get_errno(e) != errno.EPIPE:
                raise
        hubs.trampoline(fd, write=True)


def wait():
    """wait() -> (pid, status)

    Wait for completion of a child process."""
    return waitpid(0, 0)

__original_waitpid__ = os_orig.waitpid


def waitpid(pid, options):
    """waitpid(...)
    waitpid(pid, options) -> (pid, status)

    Wait for completion of a given child process."""
    if options & os_orig.WNOHANG != 0:
        return __original_waitpid__(pid, options)
    else:
        new_options = options | os_orig.WNOHANG
        while True:
            rpid, status = __original_waitpid__(pid, new_options)
            if rpid and status >= 0:
                return rpid, status
            greenthread.sleep(0.01)

__original_open__ = os_orig.open


def open(file, flags, mode=0o777, dir_fd=None):
    """ Wrap os.open
        This behaves identically, but collaborates with
        the hub's notify_opened protocol.
    """
    # pathlib workaround #534 pathlib._NormalAccessor wraps `open` in
    # `staticmethod` for py < 3.7 but not 3.7. That means we get here with
    # `file` being a pathlib._NormalAccessor object, and the other arguments
    # shifted.  Fortunately pathlib doesn't use the `dir_fd` argument, so we
    # have space in the parameter list. We use some heuristics to detect this
    # and adjust the parameters (without importing pathlib)
    if type(file).__name__ == '_NormalAccessor':
        file, flags, mode, dir_fd = flags, mode, dir_fd, None

    if dir_fd is not None:
        fd = __original_open__(file, flags, mode, dir_fd=dir_fd)
    else:
        fd = __original_open__(file, flags, mode)
    hubs.notify_opened(fd)
    return fd