1
# -*- test-case-name: twisted.test.test_fdesc -*-
2
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
3
# See LICENSE for details.
7
Utility functions for dealing with POSIX file descriptors.
18
from twisted.internet.main import CONNECTION_LOST, CONNECTION_DONE
19
from twisted.python.runtime import platformType
21
def setNonBlocking(fd):
23
Make a file descriptor non-blocking.
25
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
26
flags = flags | os.O_NONBLOCK
27
fcntl.fcntl(fd, fcntl.F_SETFL, flags)
32
Make a file descriptor blocking.
34
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
35
flags = flags & ~os.O_NONBLOCK
36
fcntl.fcntl(fd, fcntl.F_SETFL, flags)
40
# fcntl isn't available on Windows. By default, handles aren't
41
# inherited on Windows, so we can do nothing here.
42
_setCloseOnExec = _unsetCloseOnExec = lambda fd: None
44
def _setCloseOnExec(fd):
46
Make a file descriptor close-on-exec.
48
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
49
flags = flags | fcntl.FD_CLOEXEC
50
fcntl.fcntl(fd, fcntl.F_SETFD, flags)
53
def _unsetCloseOnExec(fd):
55
Make a file descriptor close-on-exec.
57
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
58
flags = flags & ~fcntl.FD_CLOEXEC
59
fcntl.fcntl(fd, fcntl.F_SETFD, flags)
62
def readFromFD(fd, callback):
64
Read from file descriptor, calling callback with resulting data.
66
If successful, call 'callback' with a single argument: the
69
Returns same thing FileDescriptor.doRead would: CONNECTION_LOST,
70
CONNECTION_DONE, or None.
73
@param fd: non-blocking file descriptor to be read from.
74
@param callback: a callable which accepts a single argument. If
75
data is read from the file descriptor it will be called with this
76
data. Handling exceptions from calling the callback is up to the
79
Note that if the descriptor is still connected but no data is read,
80
None will be returned but callback will not be called.
82
@return: CONNECTION_LOST on error, CONNECTION_DONE when fd is
83
closed, otherwise None.
86
output = os.read(fd, 8192)
87
except (OSError, IOError), ioe:
88
if ioe.args[0] in (errno.EAGAIN, errno.EINTR):
91
return CONNECTION_LOST
93
return CONNECTION_DONE
97
def writeToFD(fd, data):
99
Write data to file descriptor.
101
Returns same thing FileDescriptor.writeSomeData would.
104
@param fd: non-blocking file descriptor to be written to.
105
@type data: C{str} or C{buffer}
106
@param data: bytes to write to fd.
108
@return: number of bytes written, or CONNECTION_LOST.
111
return os.write(fd, data)
112
except (OSError, IOError), io:
113
if io.errno in (errno.EAGAIN, errno.EINTR):
115
return CONNECTION_LOST
118
__all__ = ["setNonBlocking", "setBlocking", "readFromFD", "writeToFD"]