def test_socket_error_on_accept2(self, monkeypatch):
def error(*args):
called.times += 1
called.args = args
logger = Mock()
called = MockUtils.Placeholder()
logger.error = error
monkeypatch.setattr('relaax.server.rlx_server.rlx_port.log', logger)
if sys.platform != 'win32':
monkeypatch.setattr(os, 'fork', lambda: 0)
monkeypatch.setattr(socket, 'socket', lambda af, st: self.socket)
self.socket.accept = lambda: MockUtils.raise_(socket.error(errno.ENOMEM, "fatal error message"))
try:
RLXPort.listen(('localhost', 7000))
assert False
except Exception as e:
assert called.args == ('Could not accept new connection (fatal error message)',)
assert called.times == 1
assert str(e) == '[Errno %d] fatal error message' % errno.ENOMEM
python类ENOMEM的实例源码
def test_main_failed_exec(monkeypatch, capsys):
def mock_execvpe(file, args, env):
raise OSError(errno.ENOMEM, "It did not work, Michael")
monkeypatch.setattr('os.execvpe', mock_execvpe)
def check_run_main(dirname):
project_dir_disable_dedicated_env(dirname)
result = main(Args(directory=dirname))
assert 1 == result
with_directory_contents_completing_project_file(
{DEFAULT_PROJECT_FILENAME: """
commands:
default:
conda_app_entry: python --version
"""}, check_run_main)
out, err = capsys.readouterr()
assert "" == out
assert 'Failed to execute' in err
assert 'It did not work, Michael' in err
def test_main_failed_exec(monkeypatch, capsys):
def mock_execvpe(file, args, env):
raise OSError(errno.ENOMEM, "It did not work, Michael")
monkeypatch.setattr('os.execvpe', mock_execvpe)
def check_run_main(dirname):
project_dir_disable_dedicated_env(dirname)
result = main(Args(directory=dirname))
assert 1 == result
with_directory_contents_completing_project_file(
{DEFAULT_PROJECT_FILENAME: """
commands:
default:
conda_app_entry: python --version
"""}, check_run_main)
out, err = capsys.readouterr()
assert "" == out
assert 'Failed to execute' in err
assert 'It did not work, Michael' in err
def __init__(self, dbfile, use_mmap=True, basepos=0):
self._file = dbfile
self.is_closed = False
# Seek to the end to get total file size (to check if mmap is OK)
dbfile.seek(0, os.SEEK_END)
filesize = self._file.tell()
dbfile.seek(basepos)
self._diroffset = self._file.read_long()
self._dirlength = self._file.read_int()
self._file.seek(self._diroffset)
self._dir = self._file.read_pickle()
self._options = self._file.read_pickle()
self._locks = {}
self._source = None
use_mmap = (
use_mmap
and hasattr(self._file, "fileno") # check file is a real file
and filesize < sys.maxsize # check fit on 32-bit Python
)
if mmap and use_mmap:
# Try to open the entire segment as a memory-mapped object
try:
fileno = self._file.fileno()
self._source = mmap.mmap(fileno, 0, access=mmap.ACCESS_READ)
except (mmap.error, OSError):
e = sys.exc_info()[1]
# If we got an error because there wasn't enough memory to
# open the map, ignore it and fall through, we'll just use the
# (slower) "sub-file" implementation
if e.errno == errno.ENOMEM:
pass
else:
raise
else:
# If that worked, we can close the file handle we were given
self._file.close()
self._file = None
def _accept_connection(self, protocol_factory, sock,
sslcontext=None, server=None):
try:
conn, addr = sock.accept()
if self._debug:
logger.debug("%r got a new connection from %r: %r",
server, addr, conn)
conn.setblocking(False)
except (BlockingIOError, InterruptedError, ConnectionAbortedError):
pass # False alarm.
except OSError as exc:
# There's nowhere to send the error, so just log it.
if exc.errno in (errno.EMFILE, errno.ENFILE,
errno.ENOBUFS, errno.ENOMEM):
# Some platforms (e.g. Linux keep reporting the FD as
# ready, so we remove the read handler temporarily.
# We'll try again in a while.
self.call_exception_handler({
'message': 'socket.accept() out of system resource',
'exception': exc,
'socket': sock,
})
self.remove_reader(sock.fileno())
self.call_later(constants.ACCEPT_RETRY_DELAY,
self._start_serving,
protocol_factory, sock, sslcontext, server)
else:
raise # The event loop will catch, log and ignore it.
else:
extra = {'peername': addr}
accept = self._accept_connection2(protocol_factory, conn, extra,
sslcontext, server)
self.create_task(accept)
def handle_accept_socket_exeption(cls, error):
if error.errno in (errno.EWOULDBLOCK, errno.EAGAIN):
# Try again
return True # continue accept loop
elif error.errno == errno.EPERM:
# Netfilter on Linux may have rejected the
# connection, but we get told to try to accept()
# anyway.
return True # continue accept loop
elif error.errno in (errno.EMFILE, errno.ENOBUFS, errno.ENFILE,
errno.ENOMEM, errno.ECONNABORTED):
# Linux gives EMFILE when a process is not allowed to
# allocate any more file descriptors. *BSD and Win32
# give (WSA)ENOBUFS. Linux can also give ENFILE if the
# system is out of inodes, or ENOMEM if there is
# insufficient memory to allocate a new dentry.
# ECONNABORTED is documented as possible on all
# relevant platforms (Linux, Windows, macOS, and the
# BSDs) but occurs only on the BSDs. It occurs when a
# client sends a FIN or RST after the server sends a
# SYN|ACK but before application code calls accept(2).
# On Linux, calling accept(2) on such a listener
# returns a connection that fails as though the it were
# terminated after being fully established. This
# appears to be an implementation choice (see
# inet_accept in inet/ipv4/af_inet.c). On macOS X,
# such a listener is not considered readable, so
# accept(2) will never be called. Calling accept(2) on
# such a listener, however, does not return at all.
log.error("Could not accept new connection (%s)" % error.strerror)
return False # break accept loop
def __init__(self, dbfile, use_mmap=True, basepos=0):
self._file = dbfile
self.is_closed = False
# Seek to the end to get total file size (to check if mmap is OK)
dbfile.seek(0, os.SEEK_END)
filesize = self._file.tell()
dbfile.seek(basepos)
self._diroffset = self._file.read_long()
self._dirlength = self._file.read_int()
self._file.seek(self._diroffset)
self._dir = self._file.read_pickle()
self._options = self._file.read_pickle()
self._locks = {}
self._source = None
use_mmap = (
use_mmap
and hasattr(self._file, "fileno") # check file is a real file
and filesize < sys.maxsize # check fit on 32-bit Python
)
if mmap and use_mmap:
# Try to open the entire segment as a memory-mapped object
try:
fileno = self._file.fileno()
self._source = mmap.mmap(fileno, 0, access=mmap.ACCESS_READ)
except (mmap.error, OSError):
e = sys.exc_info()[1]
# If we got an error because there wasn't enough memory to
# open the map, ignore it and fall through, we'll just use the
# (slower) "sub-file" implementation
if e.errno == errno.ENOMEM:
pass
else:
raise
else:
# If that worked, we can close the file handle we were given
self._file.close()
self._file = None
def __init__(self, dbfile, use_mmap=True, basepos=0):
self._file = dbfile
self.is_closed = False
# Seek to the end to get total file size (to check if mmap is OK)
dbfile.seek(0, os.SEEK_END)
filesize = self._file.tell()
dbfile.seek(basepos)
self._diroffset = self._file.read_long()
self._dirlength = self._file.read_int()
self._file.seek(self._diroffset)
self._dir = self._file.read_pickle()
self._options = self._file.read_pickle()
self._locks = {}
self._source = None
use_mmap = (
use_mmap
and hasattr(self._file, "fileno") # check file is a real file
and filesize < sys.maxsize # check fit on 32-bit Python
)
if mmap and use_mmap:
# Try to open the entire segment as a memory-mapped object
try:
fileno = self._file.fileno()
self._source = mmap.mmap(fileno, 0, access=mmap.ACCESS_READ)
except (mmap.error, OSError):
e = sys.exc_info()[1]
# If we got an error because there wasn't enough memory to
# open the map, ignore it and fall through, we'll just use the
# (slower) "sub-file" implementation
if e.errno == errno.ENOMEM:
pass
else:
raise
else:
# If that worked, we can close the file handle we were given
self._file.close()
self._file = None
def updateCharMap(screen):
global hichar
ttyno = '4'
tty = open('/dev/tty' + screen, 'rb')
GIO_UNIMAP = 0x4B66
VT_GETHIFONTMASK = 0x560D
himask = array("H", (0,))
ioctl(tty, VT_GETHIFONTMASK, himask)
hichar, = unpack_from("@H", himask)
sz = 512
line = ''
while True:
try:
unipairs = array("H", [0]*(2*sz))
unimapdesc = array("B", pack("@HP", sz, unipairs.buffer_info()[0]))
ioctl(tty.fileno(), GIO_UNIMAP, unimapdesc)
break
except IOError as e:
if e.errno != errno.ENOMEM:
raise
sz *= 2
tty.close()
ncodes, = unpack_from("@H", unimapdesc)
utable = unpack_from("@%dH" % (2*ncodes), unipairs)
for u, b in zip(utable[::2], utable[1::2]):
if charmap.get(b) is None:
charmap[b] = chr(u)
def _accept_connection(self, protocol_factory, sock,
sslcontext=None, server=None, backlog=100):
# This method is only called once for each event loop tick where the
# listening socket has triggered an EVENT_READ. There may be multiple
# connections waiting for an .accept() so it is called in a loop.
# See https://bugs.python.org/issue27906 for more details.
for _ in range(backlog):
try:
conn, addr = sock.accept()
if self._debug:
logger.debug("%r got a new connection from %r: %r",
server, addr, conn)
conn.setblocking(False)
except (BlockingIOError, InterruptedError, ConnectionAbortedError):
# Early exit because the socket accept buffer is empty.
return None
except OSError as exc:
# There's nowhere to send the error, so just log it.
if exc.errno in (errno.EMFILE, errno.ENFILE,
errno.ENOBUFS, errno.ENOMEM):
# Some platforms (e.g. Linux keep reporting the FD as
# ready, so we remove the read handler temporarily.
# We'll try again in a while.
self.call_exception_handler({
'message': 'socket.accept() out of system resource',
'exception': exc,
'socket': sock,
})
self._remove_reader(sock.fileno())
self.call_later(constants.ACCEPT_RETRY_DELAY,
self._start_serving,
protocol_factory, sock, sslcontext, server,
backlog)
else:
raise # The event loop will catch, log and ignore it.
else:
extra = {'peername': addr}
accept = self._accept_connection2(protocol_factory, conn, extra,
sslcontext, server)
self.create_task(accept)
def _accept_connection(self, protocol_factory, sock,
sslcontext=None, server=None):
try:
conn, addr = sock.accept()
if self._debug:
logger.debug("%r got a new connection from %r: %r",
server, addr, conn)
conn.setblocking(False)
except (BlockingIOError, InterruptedError, ConnectionAbortedError):
pass # False alarm.
except OSError as exc:
# There's nowhere to send the error, so just log it.
if exc.errno in (errno.EMFILE, errno.ENFILE,
errno.ENOBUFS, errno.ENOMEM):
# Some platforms (e.g. Linux keep reporting the FD as
# ready, so we remove the read handler temporarily.
# We'll try again in a while.
self.call_exception_handler({
'message': 'socket.accept() out of system resource',
'exception': exc,
'socket': sock,
})
self.remove_reader(sock.fileno())
self.call_later(constants.ACCEPT_RETRY_DELAY,
self._start_serving,
protocol_factory, sock, sslcontext, server)
else:
raise # The event loop will catch, log and ignore it.
else:
extra = {'peername': addr}
accept = self._accept_connection2(protocol_factory, conn, extra,
sslcontext, server)
self.create_task(accept)
def __init__(self, dbfile, use_mmap=True, basepos=0):
self._file = dbfile
self.is_closed = False
# Seek to the end to get total file size (to check if mmap is OK)
dbfile.seek(0, os.SEEK_END)
filesize = self._file.tell()
dbfile.seek(basepos)
self._diroffset = self._file.read_long()
self._dirlength = self._file.read_int()
self._file.seek(self._diroffset)
self._dir = self._file.read_pickle()
self._options = self._file.read_pickle()
self._locks = {}
self._source = None
use_mmap = (
use_mmap
and hasattr(self._file, "fileno") # check file is a real file
and filesize < sys.maxsize # check fit on 32-bit Python
)
if mmap and use_mmap:
# Try to open the entire segment as a memory-mapped object
try:
fileno = self._file.fileno()
self._source = mmap.mmap(fileno, 0, access=mmap.ACCESS_READ)
except (mmap.error, OSError):
e = sys.exc_info()[1]
# If we got an error because there wasn't enough memory to
# open the map, ignore it and fall through, we'll just use the
# (slower) "sub-file" implementation
if e.errno == errno.ENOMEM:
pass
else:
raise
else:
# If that worked, we can close the file handle we were given
self._file.close()
self._file = None
def _accept_connection(self, protocol_factory, sock,
sslcontext=None, server=None):
try:
conn, addr = sock.accept()
if self._debug:
logger.debug("%r got a new connection from %r: %r",
server, addr, conn)
conn.setblocking(False)
except (BlockingIOError, InterruptedError, ConnectionAbortedError):
pass # False alarm.
except OSError as exc:
# There's nowhere to send the error, so just log it.
# TODO: Someone will want an error handler for this.
if exc.errno in (errno.EMFILE, errno.ENFILE,
errno.ENOBUFS, errno.ENOMEM):
# Some platforms (e.g. Linux keep reporting the FD as
# ready, so we remove the read handler temporarily.
# We'll try again in a while.
self.call_exception_handler({
'message': 'socket.accept() out of system resource',
'exception': exc,
'socket': sock,
})
self.remove_reader(sock.fileno())
self.call_later(constants.ACCEPT_RETRY_DELAY,
self._start_serving,
protocol_factory, sock, sslcontext, server)
else:
raise # The event loop will catch, log and ignore it.
else:
if sslcontext:
self._make_ssl_transport(
conn, protocol_factory(), sslcontext, None,
server_side=True, extra={'peername': addr}, server=server)
else:
self._make_socket_transport(
conn, protocol_factory(), extra={'peername': addr},
server=server)
# It's now up to the protocol to handle the connection.
def out_of_memory():
"""Return an out of memory message, for use in a MemoryError handler."""
# figure out how much memory we're using (note that we could run out
# of memory while doing this, so check for that.
vsz = None
try:
vmusage = __getvmusage()
if vmusage is not None:
vsz = bytes_to_str(vmusage, fmt="{num:.0f}{unit}")
except (MemoryError, EnvironmentError) as __e:
if isinstance(__e, EnvironmentError) and \
__e.errno != errno.ENOMEM:
raise
if vsz is not None:
error = """\
There is not enough memory to complete the requested operation. At least
{vsz} of virtual memory was in use by this command before it ran out of memory.
You must add more memory (swap or physical) or allow the system to access more
existing memory, or quit other programs that may be consuming memory, and try
the operation again."""
else:
error = """\
There is not enough memory to complete the requested operation. You must
add more memory (swap or physical) or allow the system to access more existing
memory, or quit other programs that may be consuming memory, and try the
operation again."""
return _(error).format(**locals())
# EmptyI for argument defaults
def handle_errors(func, *args, **kwargs):
"""Catch exceptions raised by the main program function and then print
a message and/or exit with an appropriate return code.
"""
traceback_str = misc.get_traceback_message()
try:
# Out of memory errors can be raised as EnvironmentErrors with
# an errno of ENOMEM, so in order to handle those exceptions
# with other errnos, we nest this try block and have the outer
# one handle the other instances.
try:
__ret = func(*args, **kwargs)
except (MemoryError, EnvironmentError) as __e:
if isinstance(__e, EnvironmentError) and \
__e.errno != errno.ENOMEM:
raise
error("\n" + misc.out_of_memory())
__ret = EXIT_OOPS
except SystemExit as __e:
raise __e
except (PipeError, KeyboardInterrupt):
# Don't display any messages here to prevent possible further
# broken pipe (EPIPE) errors.
__ret = EXIT_OOPS
except:
traceback.print_exc()
error(traceback_str)
__ret = 99
return __ret
def handle_errors(func, *args, **kwargs):
"""Catch exceptions raised by the main program function and then print
a message and/or exit with an appropriate return code.
"""
traceback_str = misc.get_traceback_message()
try:
# Out of memory errors can be raised as EnvironmentErrors with
# an errno of ENOMEM, so in order to handle those exceptions
# with other errnos, we nest this try block and have the outer
# one handle the other instances.
try:
__ret = func(*args, **kwargs)
except (MemoryError, EnvironmentError) as __e:
if isinstance(__e, EnvironmentError) and \
__e.errno != errno.ENOMEM:
raise
error("\n" + misc.out_of_memory())
__ret = EXIT_OOPS
except SystemExit as __e:
raise __e
except (PipeError, KeyboardInterrupt):
# Don't display any messages here to prevent possible further
# broken pipe (EPIPE) errors.
__ret = EXIT_OOPS
except apx.VersionException as __e:
error(_("The sysrepo command appears out of sync with the "
"libraries provided\nby pkg:/package/pkg. The client "
"version is {client} while the library\nAPI version is "
"{api}.").format(client=__e.received_version,
api=__e.expected_version))
__ret = EXIT_OOPS
except:
traceback.print_exc()
error(traceback_str)
__ret = 99
return __ret
def __init__(self, dbfile, use_mmap=True, basepos=0):
self._file = dbfile
self.is_closed = False
# Seek to the end to get total file size (to check if mmap is OK)
dbfile.seek(0, os.SEEK_END)
filesize = self._file.tell()
dbfile.seek(basepos)
self._diroffset = self._file.read_long()
self._dirlength = self._file.read_int()
self._file.seek(self._diroffset)
self._dir = self._file.read_pickle()
self._options = self._file.read_pickle()
self._locks = {}
self._source = None
use_mmap = (
use_mmap
and hasattr(self._file, "fileno") # check file is a real file
and filesize < sys.maxsize # check fit on 32-bit Python
)
if mmap and use_mmap:
# Try to open the entire segment as a memory-mapped object
try:
fileno = self._file.fileno()
self._source = mmap.mmap(fileno, 0, access=mmap.ACCESS_READ)
except (mmap.error, OSError):
e = sys.exc_info()[1]
# If we got an error because there wasn't enough memory to
# open the map, ignore it and fall through, we'll just use the
# (slower) "sub-file" implementation
if e.errno == errno.ENOMEM:
pass
else:
raise
else:
# If that worked, we can close the file handle we were given
self._file.close()
self._file = None
def _spawnChild(self, sock):
"""
Spawn a single child. Returns True if successful, False otherwise.
"""
# This socket pair is used for very simple communication between
# the parent and its children.
parent, child = socket.socketpair()
parent.setblocking(0)
setCloseOnExec(parent)
child.setblocking(0)
setCloseOnExec(child)
try:
pid = os.fork()
except OSError, e:
if e[0] in (errno.EAGAIN, errno.ENOMEM):
return False # Can't fork anymore.
raise
if not pid:
# Child
child.close()
# Put child into its own process group.
pid = os.getpid()
os.setpgid(pid, pid)
# Restore signal handlers.
self._restoreSignalHandlers()
# Close copies of child sockets.
for f in [x['file'] for x in self._children.values()
if x['file'] is not None]:
f.close()
self._children = {}
try:
# Enter main loop.
self._child(sock, parent)
except KeyboardInterrupt:
pass
sys.exit(0)
else:
# Parent
parent.close()
d = self._children[pid] = {}
d['file'] = child
d['avail'] = True
return True
def _spawnChild(self, sock):
"""
Spawn a single child. Returns True if successful, False otherwise.
"""
# This socket pair is used for very simple communication between
# the parent and its children.
parent, child = socket.socketpair()
parent.setblocking(0)
setCloseOnExec(parent)
child.setblocking(0)
setCloseOnExec(child)
try:
pid = os.fork()
except OSError, e:
if e[0] in (errno.EAGAIN, errno.ENOMEM):
return False # Can't fork anymore.
raise
if not pid:
# Child
child.close()
# Put child into its own process group.
pid = os.getpid()
os.setpgid(pid, pid)
# Restore signal handlers.
self._restoreSignalHandlers()
# Close copies of child sockets.
for f in [x['file'] for x in self._children.values()
if x['file'] is not None]:
f.close()
self._children = {}
try:
# Enter main loop.
self._child(sock, parent)
except KeyboardInterrupt:
pass
sys.exit(0)
else:
# Parent
parent.close()
d = self._children[pid] = {}
d['file'] = child
d['avail'] = True
return True
def handle_errors(func, *args, **kwargs):
"""Catch exceptions raised by the main program function and then print
a message and/or exit with an appropriate return code.
"""
traceback_str = misc.get_traceback_message()
try:
# Out of memory errors can be raised as EnvironmentErrors with
# an errno of ENOMEM, so in order to handle those exceptions
# with other errnos, we nest this try block and have the outer
# one handle the other instances.
try:
__ret = func(*args, **kwargs)
except (MemoryError, EnvironmentError) as __e:
if isinstance(__e, EnvironmentError) and \
__e.errno != errno.ENOMEM:
raise apx._convert_error(__e)
error("\n" + misc.out_of_memory())
__ret = EXIT_OOPS
except SystemExit as __e:
raise __e
except (IOError, PipeError, KeyboardInterrupt) as __e:
# Don't display any messages here to prevent possible further
# broken pipe (EPIPE) errors.
if isinstance(__e, IOError) and __e.errno != errno.EPIPE:
error(str(__e))
__ret = EXIT_OOPS
except apx.VersionException as __e:
error(_("The pkgrepo command appears out of sync with the "
"libraries provided\nby pkg:/package/pkg. The client "
"version is {client} while the library\nAPI version is "
"{api}.").format(client=__e.received_version,
api=__e.expected_version))
__ret = EXIT_OOPS
except apx.BadRepositoryURI as __e:
error(str(__e))
__ret = EXIT_BADOPT
except apx.InvalidOptionError as __e:
error("{0} Supported formats: {1}".format(
str(__e), LISTING_FORMATS))
__ret = EXIT_BADOPT
except (apx.ApiException, sr.RepositoryError) as __e:
error(str(__e))
__ret = EXIT_OOPS
except:
traceback.print_exc()
error(traceback_str)
__ret = 99
return __ret