except ImportError:
signal = None
+from tornado.platform.auto import set_close_exec
+
try:
import fcntl
except ImportError:
if os.name == 'nt':
from tornado.platform import windows
- from tornado.platform import windows as fcntl
else:
raise
+
+
class IOLoop(object):
"""A level-triggered I/O loop.
def __init__(self, impl=None):
self._impl = impl or _poll()
if hasattr(self._impl, 'fileno'):
- self._set_close_exec(self._impl.fileno())
+ set_close_exec(self._impl.fileno())
self._handlers = {}
self._events = {}
self._callbacks = []
r, w = os.pipe()
self._set_nonblocking(r)
self._set_nonblocking(w)
- self._set_close_exec(r)
- self._set_close_exec(w)
+ set_close_exec(r)
+ set_close_exec(w)
self._waker_reader = os.fdopen(r, "rb", 0)
self._waker_writer = os.fdopen(w, "wb", 0)
else:
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
- def _set_close_exec(self, fd):
- flags = fcntl.fcntl(fd, fcntl.F_GETFD)
- fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
-
class _Timeout(object):
"""An IOLoop timeout, a UNIX timestamp and a callback"""
"""Miscellaneous network utility code."""
-import os
import socket
-try:
- import fcntl
-except ImportError:
- if os.name == 'nt':
- from tornado.platform import windows as fcntl
- else:
- raise
+from tornado.platform.auto import set_close_exec
def bind_sockets(port, address=None, family=socket.AF_UNSPEC, backlog=128):
"""Creates listening sockets bound to the given port and address.
0, flags):
af, socktype, proto, canonname, sockaddr = res
sock = socket.socket(af, socktype, proto)
- flags = fcntl.fcntl(sock.fileno(), fcntl.F_GETFD)
- flags |= fcntl.FD_CLOEXEC
- fcntl.fcntl(sock.fileno(), fcntl.F_SETFD, flags)
+ set_close_exec(sock.fileno())
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if af == socket.AF_INET6:
# On linux, ipv6 sockets accept ipv4 too by default,
--- /dev/null
+#!/usr/bin/env python
+#
+# Copyright 2011 Facebook
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""Implementation of platform-specific functionality.
+
+For each function or class described in `tornado.platform.interface`,
+the appropriate platform-specific implementation exists in this module.
+Most code that needs access to this functionality should do e.g.::
+
+ from tornado.platform.auto import set_close_exec
+"""
+
+import os
+
+if os.name == 'nt':
+ from .windows import set_close_exec
+else:
+ from .posix import set_close_exec
--- /dev/null
+#!/usr/bin/env python
+#
+# Copyright 2011 Facebook
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""Interfaces for platform-specific functionality.
+
+This module exists primarily for documentation purposes and as base classes
+for other tornado.platform modules. Most code should import the appropriate
+implementation from `tornado.platform.auto`.
+"""
+
+def set_close_exec(fd):
+ """Sets the close-on-exec bit (``FD_CLOEXEC``)for a file descriptor."""
+ raise NotImplementedError()
--- /dev/null
+#!/usr/bin/env python
+#
+# Copyright 2011 Facebook
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""Posix implementations of platform-specific functionality."""
+
+import fcntl
+
+def set_close_exec(fd):
+ flags = fcntl.fcntl(fd, fcntl.F_GETFD)
+ fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
import ctypes
import ctypes.wintypes
-import os
import socket
import errno
-
-# See: http://msdn.microsoft.com/en-us/library/ms738573(VS.85).aspx
-ioctlsocket = ctypes.windll.ws2_32.ioctlsocket
-ioctlsocket.argtypes = (ctypes.wintypes.HANDLE, ctypes.wintypes.LONG, ctypes.wintypes.ULONG)
-ioctlsocket.restype = ctypes.c_int
-
# See: http://msdn.microsoft.com/en-us/library/ms724935(VS.85).aspx
SetHandleInformation = ctypes.windll.kernel32.SetHandleInformation
SetHandleInformation.argtypes = (ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD, ctypes.wintypes.DWORD)
HANDLE_FLAG_INHERIT = 0x00000001
-F_GETFD = 1
-F_SETFD = 2
-F_GETFL = 3
-F_SETFL = 4
-
-FD_CLOEXEC = 1
-
-os.O_NONBLOCK = 2048
-
-FIONBIO = 126
-
-
-def fcntl(fd, op, arg=0):
- if op == F_GETFD or op == F_GETFL:
- return 0
- elif op == F_SETFD:
- # Check that the flag is CLOEXEC and translate
- if arg == FD_CLOEXEC:
- success = SetHandleInformation(fd, HANDLE_FLAG_INHERIT, 0)
- if not success:
- raise ctypes.GetLastError()
- else:
- raise ValueError("Unsupported arg")
- #elif op == F_SETFL:
- ## Check that the flag is NONBLOCK and translate
- #if arg == os.O_NONBLOCK:
- ##pass
- #result = ioctlsocket(fd, FIONBIO, 1)
- #if result != 0:
- #raise ctypes.GetLastError()
- #else:
- #raise ValueError("Unsupported arg")
- else:
- raise ValueError("Unsupported op")
+def set_close_exec(fd):
+ success = SetHandleInformation(fd, HANDLE_FLAG_INHERIT, 0)
+ if not success:
+ raise ctypes.GetLastError()
class Pipe(object):