[pypy-svn] r20885 - in pypy/dist/pypy/module/_socket: . rpython test

nik at codespeak.net nik at codespeak.net
Thu Dec 8 12:38:42 CET 2005


Author: nik
Date: Thu Dec  8 12:38:40 2005
New Revision: 20885

Modified:
   pypy/dist/pypy/module/_socket/interp_socket.py
   pypy/dist/pypy/module/_socket/rpython/rsocket.py
   pypy/dist/pypy/module/_socket/test/test_socket2.py
Log:
(ale, nik)

implemented socket.fileno() and socket.close()


Modified: pypy/dist/pypy/module/_socket/interp_socket.py
==============================================================================
--- pypy/dist/pypy/module/_socket/interp_socket.py	(original)
+++ pypy/dist/pypy/module/_socket/interp_socket.py	Thu Dec  8 12:38:40 2005
@@ -1,4 +1,4 @@
-import _socket, socket, errno, sys
+import _socket, socket, errno, os, sys
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.error import OperationError
@@ -642,6 +642,7 @@
         self.type = type
         self.proto = proto
         self.timeout = getstate(space).defaulttimeout
+        self.closed = False
 
     def accept(self, space):
         """accept() -> (socket object, address info)
@@ -677,10 +678,15 @@
 
         Close the socket.  It cannot be used after this call.
         """
-        if self.fd is not None:
-            fd = self.fd
-            self.fd = None
-            fd.close()
+        if not self.closed:
+            try:
+                # Reusing the os.close primitive to save us from writing a 
+                # socket-specific close primitive. This might not be perfectly
+                # cross-platform (Windows?).
+                os.close(self.fd)
+            except OSError, e:
+                raise w_get_socketerror(space, e.strerror, e.errno)
+            self.closed = True
     close.unwrap_spec = ['self', ObjSpace]
 
     def connect(self, space, w_addr):
@@ -729,7 +735,10 @@
 
         Return the integer file descriptor of the socket.
         """
-        return space.wrap(self.fd.fileno())
+        if not self.closed:
+            return space.wrap(self.fd)
+        else:
+            raise w_get_socketerror(space, "Bad file descriptor", errno.EBADF)
     fileno.unwrap_spec = ['self', ObjSpace]
 
     def getpeername(self, space):

Modified: pypy/dist/pypy/module/_socket/rpython/rsocket.py
==============================================================================
--- pypy/dist/pypy/module/_socket/rpython/rsocket.py	(original)
+++ pypy/dist/pypy/module/_socket/rpython/rsocket.py	Thu Dec  8 12:38:40 2005
@@ -4,6 +4,8 @@
 
 import socket
 
+keep_sockets_alive = []
+
 class ADDRINFO(object):
     # a simulated addrinfo structure from C, i.e. a chained list
     # returned by getaddrinfo()
@@ -27,4 +29,8 @@
     return ADDRINFO(host, port, family, socktype, proto, flags)
 
 def newsocket(family, type, protocol):
-    return socket.socket(family, type, protocol).fileno()
+    s = socket.socket(family, type, protocol)
+    # HACK: We have to prevent GC to collect the socket object because we don't
+    # want it to be closed.
+    keep_sockets_alive.append(s)
+    return s.fileno()

Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py
==============================================================================
--- pypy/dist/pypy/module/_socket/test/test_socket2.py	(original)
+++ pypy/dist/pypy/module/_socket/test/test_socket2.py	Thu Dec  8 12:38:40 2005
@@ -263,8 +263,34 @@
     assert space.unwrap(w_t) is None
 
 def app_test_newsocket_error():
-    import socket
-    raises (socket.error, socket.socket, 10001, socket.SOCK_STREAM, 0)
+    import _socket
+    raises(_socket.error, _socket.socket, 10001, _socket.SOCK_STREAM, 0)
+
+def app_test_socket_fileno():
+    import _socket
+    s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
+    assert s.fileno() > -1
+    assert isinstance(s.fileno(), int)
+
+def app_test_socket_close():
+    import _socket, errno
+    s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
+    fileno = s.fileno()
+    s.close()
+    s.close()
+    try:
+        s.fileno()
+    except _socket.error, ex:
+        assert ex.args[0], errno.EBADF
+    else:
+        assert 0
+
+def app_test_socket_close_error():
+    import _socket, os
+    s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
+    os.close(s.fileno())
+    raises(_socket.error, s.close)
+
 
 class AppTestSocket:
     def setup_class(cls):



More information about the Pypy-commit mailing list