]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Clean up hacky fcntl emulation for windows.
authorBen Darnell <ben@bendarnell.com>
Tue, 5 Jul 2011 03:37:52 +0000 (20:37 -0700)
committerBen Darnell <ben@bendarnell.com>
Tue, 5 Jul 2011 03:37:52 +0000 (20:37 -0700)
tornado/ioloop.py
tornado/netutil.py
tornado/platform/auto.py [new file with mode: 0644]
tornado/platform/interface.py [new file with mode: 0644]
tornado/platform/posix.py [new file with mode: 0644]
tornado/platform/windows.py

index c8396fd4eb0ce23a6d0656990a9b9dd55aae4d39..4bf64fc20deb3f82dee4d667b0f8bb29c6502357 100644 (file)
@@ -43,14 +43,17 @@ try:
 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.
@@ -110,7 +113,7 @@ class IOLoop(object):
     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 = []
@@ -126,8 +129,8 @@ class IOLoop(object):
             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:
@@ -420,10 +423,6 @@ class IOLoop(object):
         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"""
index 2b177ad1eafd0fa50eb268c6bdc9ebaf753bdb17..6d6c5ce11007cf47041a570727a31333605a41ec 100644 (file)
 
 """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.
@@ -58,9 +51,7 @@ def bind_sockets(port, address=None, family=socket.AF_UNSPEC, backlog=128):
                                   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,
diff --git a/tornado/platform/auto.py b/tornado/platform/auto.py
new file mode 100644 (file)
index 0000000..9bc411d
--- /dev/null
@@ -0,0 +1,31 @@
+#!/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
diff --git a/tornado/platform/interface.py b/tornado/platform/interface.py
new file mode 100644 (file)
index 0000000..fb5e618
--- /dev/null
@@ -0,0 +1,26 @@
+#!/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()
diff --git a/tornado/platform/posix.py b/tornado/platform/posix.py
new file mode 100644 (file)
index 0000000..673660d
--- /dev/null
@@ -0,0 +1,23 @@
+#!/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)
index 7e8bedc2c2e84a7a1ee92f2dc4afaf543968a244..e138dc1842cff76bd23b9028ca9ef595df1099ad 100644 (file)
@@ -3,16 +3,9 @@
 
 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)
@@ -21,40 +14,10 @@ SetHandleInformation.restype = ctypes.wintypes.BOOL
 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):