If an OSError or IOError are instantiated without an errno value, e.g.
e = OSError(). The existing code would give an IndexError: tuple index
out of range. However there have been cases that the errno attribute
wasn't populated so instead of switching to it this introduces a helper
function to ensure we get the errno value through whatever means
possible.
from tornado.log import app_log, gen_log
from tornado import stack_context
from tornado.util import Configurable
+from tornado.util import errno_from_exception
try:
import signal
# two ways EINTR might be signaled:
# * e.errno == errno.EINTR
# * e.args is like (errno.EINTR, 'Interrupted system call')
- if (getattr(e, 'errno', None) == errno.EINTR or
- (isinstance(getattr(e, 'args', None), tuple) and
- len(e.args) == 2 and e.args[0] == errno.EINTR)):
+ if errno_from_exception(e) == errno.EINTR:
continue
else:
raise
fd_obj, handler_func = self._handlers[fd]
handler_func(fd_obj, events)
except (OSError, IOError) as e:
- if e.args[0] == errno.EPIPE:
+ if errno_from_exception(e) == errno.EPIPE:
# Happens when the client closes the connection
pass
else:
from tornado.log import gen_log, app_log
from tornado.netutil import ssl_wrap_socket, ssl_match_hostname, SSLCertificateError
from tornado import stack_context
-from tornado.util import bytes_type
+from tornado.util import bytes_type, errno_from_exception
try:
from tornado.platform.posix import _set_nonblocking
# returned immediately when attempting to connect to
# localhost, so handle them the same way as an error
# reported later in _handle_connect.
- if (e.args[0] != errno.EINPROGRESS and
- e.args[0] not in _ERRNO_WOULDBLOCK):
+ if (errno_from_exception(e) != errno.EINPROGRESS and
+ errno_from_exception(e) not in _ERRNO_WOULDBLOCK):
gen_log.warning("Connect error on fd %s: %s",
self.socket.fileno(), e)
self.close(exc_info=True)
try:
chunk = os.read(self.fd, self.read_chunk_size)
except (IOError, OSError) as e:
- if e.args[0] in _ERRNO_WOULDBLOCK:
+ if errno_from_exception(e) in _ERRNO_WOULDBLOCK:
return None
- elif e.args[0] == errno.EBADF:
+ elif errno_from_exception(e) == errno.EBADF:
# If the writing half of a pipe is closed, select will
# report it as readable but reads will fail with EBADF.
self.close(exc_info=True)
from tornado.concurrent import dummy_executor, run_on_executor
from tornado.ioloop import IOLoop
from tornado.platform.auto import set_close_exec
-from tornado.util import u, Configurable
+from tornado.util import u, Configurable, errno_from_exception
if hasattr(ssl, 'match_hostname') and hasattr(ssl, 'CertificateError'): # python 3.2+
ssl_match_hostname = ssl.match_hostname
try:
sock = socket.socket(af, socktype, proto)
except socket.error as e:
- if e.args[0] == errno.EAFNOSUPPORT:
+ if errno_from_exception(e) == errno.EAFNOSUPPORT:
continue
raise
set_close_exec(sock.fileno())
try:
st = os.stat(file)
except OSError as err:
- if err.errno != errno.ENOENT:
+ if errno_from_exception(err) != errno.ENOENT:
raise
else:
if stat.S_ISSOCK(st.st_mode):
except socket.error as e:
# EWOULDBLOCK and EAGAIN indicate we have accepted every
# connection that is available.
- if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
+ if errno_from_exception(e) in (errno.EWOULDBLOCK, errno.EAGAIN):
return
# ECONNABORTED indicates that there was a connection
# but it was closed while still in the accept queue.
# (observed on FreeBSD).
- if e.args[0] == errno.ECONNABORTED:
+ if errno_from_exception(e) == errno.ECONNABORTED:
continue
raise
callback(connection, address)
from tornado.log import gen_log
from tornado.platform.auto import set_close_exec
from tornado import stack_context
+from tornado.util import errno_from_exception
try:
long # py2
try:
pid, status = os.wait()
except OSError as e:
- if e.errno == errno.EINTR:
+ if errno_from_exception(e) == errno.EINTR:
continue
raise
if pid not in children:
try:
ret_pid, status = os.waitpid(pid, os.WNOHANG)
except OSError as e:
- if e.args[0] == errno.ECHILD:
+ if errno_from_exception(e) == errno.ECHILD:
return
if ret_pid == 0:
return
from tornado.iostream import IOStream, SSLIOStream
from tornado.netutil import bind_sockets, add_accept_handler, ssl_wrap_socket
from tornado import process
+from tornado.util import errno_from_exception
class TCPServer(object):
# SSLIOStream._do_ssl_handshake).
# To test this behavior, try nmap with the -sT flag.
# https://github.com/facebook/tornado/pull/750
- if err.args[0] in (errno.ECONNABORTED, errno.EINVAL):
+ if errno_from_exception(err) in (errno.ECONNABORTED, errno.EINVAL):
return connection.close()
else:
raise
""")
+def errno_from_exception(e):
+ """Provides the errno from an Exception object.
+
+ There are cases that the errno attribute was not set so we pull
+ the errno out of the args but if someone instatiates an Exception
+ without any args you will get a tuple error. So this function
+ abstracts all that behavior to give you a safe way to get the
+ errno.
+ """
+
+ if hasattr(e, 'errno'):
+ return e.errno
+ elif e.args:
+ return e.args[0]
+ else:
+ return None
+
+
class Configurable(object):
"""Base class for configurable interfaces.