fix up doctests
authorTero Marttila <terom@fixme.fi>
Mon, 17 Aug 2009 19:40:23 +0300
changeset 21 19d212c948e0
parent 20 0e4933d5862e
child 22 f6e8d5e37998
fix up doctests
qmsk/net/sctp/sock.pxd
qmsk/net/sctp/sock.pyx
qmsk/net/socket/socket.pxd
--- a/qmsk/net/sctp/sock.pxd	Mon Aug 17 01:29:31 2009 +0300
+++ b/qmsk/net/sctp/sock.pxd	Mon Aug 17 19:40:23 2009 +0300
@@ -1,6 +1,14 @@
-from qmsk.net.libc cimport __u8, __u16, __u32, __s8, __s16, __s32
+"""
+    The socket-based interface for SCTP.
+
+    http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-15
+"""
+
+#from qmsk.net.libc cimport __u8, __u16, __u32, __s8, __s16, __s32, ssize_t
+from qmsk.net.libc cimport *
 
 cimport qmsk.net.socket.platform as platform
+cimport qmsk.net.socket.socket
 
 # <netinet/sctp.h>
 # this defines the kernel SCTP -> userspace API extensions, such as structure types etc.
@@ -56,6 +64,8 @@
         __u32 sinfo_cumtsn
         sctp_assoc_t sinfo_assoc_id
 
+    # XXX: missing sctp_extrcvinfo
+
     # sctp_sndrcvinfo.sinfo_flags values
     enum sctp_sinfo_flags :
         SCTP_UNORDERED          # Send/receive message unordered
@@ -192,15 +202,76 @@
     
     ctypedef sctp_sn_error sctp_sn_error_t
     
+    
+    ###
+    ### 8   New Interfaces
+    ###
 
-    ## sctp_bindx
+    ## 8.1  sctp_bindx
     enum :
         SCTP_BINDX_ADD_ADDR
         SCTP_BINDX_REM_ADDR
 
-    int c_sctp_bindx "sctp_bindx" (int sd, platform.sockaddr *addrs, int addrcnt, int flags)
+    int sctp_bindx (int sd, platform.sockaddr *addrs, int addrcnt, int flags)
 
-    # XXX: missing return-sctp_assoc_t-id argument!
-    int c_sctp_connectx "sctp_connectx" (int sd, platform.sockaddr *addrs, int addrcnt)
+    ## 8.2 sctp_peeloff
+    int sctp_peeloff (int sd, sctp_assoc_t assoc_id)
+
+    ## 8.3 sctp_getpaddrs
+    int sctp_getpaddrs (int sd, sctp_assoc_t assoc_id, platform.sockaddr **addrs)
+    ## 8.4 sctp_freepaddrs
+    void sctp_freepaddrs (platform.sockaddr *addrs)
+
+    ## 8.5 sctp_getladdrs
+    int sctp_getladdrs (int sd, sctp_assoc_t id, platform.sockaddr **ss)
+    ## 8.6 sctp_freeladdrs
+    void sctp_freeladdrs (platform.sockaddr **ss)
+
+    ## 8.7 sctp_sendmsg
+    ssize_t sctp_sendmsg (
+            int sd,
+            void *msg, size_t len,
+            platform.sockaddr *dst, platform.socklen_t dstlen,
+            uint32_t ppid, uint32_t flags, uint16_t stream_no, uint32_t timetolive, uint32_t context
+    )
+
+    ## 8.8 sctp_Recvmsg
+    ssize_t sctp_recvmsg (
+            int sd,
+            void *msg, size_t len,
+            platform.sockaddr *src, platform.socklen_t *srclen,
+            sctp_sndrcvinfo *sinfo,
+            int *msg_flags
+    )
 
 
+    ## 8.9 sctp_connectx
+    # XXX: missing return-sctp_assoc_t-id argument from RFC!
+    int sctp_connectx (int sd, platform.sockaddr *addrs, int addrcnt)
+
+    ## 8.10 sctp_send
+    int sctp_send (
+            int sd,
+            void *msg, size_t len,
+            sctp_sndrcvinfo *sinfo,
+            int flags
+    )
+
+    ## 8.11 sctp_sendx
+    int sctp_sendx (
+            int sd,
+            void *msg, size_t len,
+            platform.sockaddr *addrs, int addrcnt,
+            sctp_sndrcvinfo *sinfo,
+            int flags
+    )
+
+    ## 8.12 sctp_getaddrlen
+    int sctp_getaddrlen (platform.sa_family_t family)
+
+cdef class sctp_socket (qmsk.net.socket.socket.socket) :
+    """
+        SCTP-specific methods and functionality, built on top of the generic socket interface.
+    """
+
+   
--- a/qmsk/net/sctp/sock.pyx	Mon Aug 17 01:29:31 2009 +0300
+++ b/qmsk/net/sctp/sock.pyx	Mon Aug 17 19:40:23 2009 +0300
@@ -1,10 +1,11 @@
 """
     This C(ython) extension module provides an interface to the libsctp library and associated socket API.
     
-    >>> from __future__ import absolute_import; import socket as _socket
-    >>> from qmsk.net.socket.addr import sockaddr_in
-    >>> s = _socket.socket(_socket.AF_INET, _socket.SOCK_SEQPACKET, 132)
-    >>> sctp_bindx(s.fileno(), [sockaddr_in('127.0.0.1', 1337), sockaddr_in('127.0.0.2')], 0x01)
+    >>> from __future__ import absolute_import;
+    >>> from qmsk.net.socket.address import sockaddr_in
+    >>> from qmsk.net.socket.constants import *
+    >>> s = sctp_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)
+    >>> s.sctp_bindx([sockaddr_in('127.0.0.1', 1337), sockaddr_in('127.0.0.2')], 0x01)
     >>>
 
 """
@@ -53,48 +54,59 @@
         # move to next
         addr_ptr += sa_len
 
-def sctp_bindx (int sd, object addrs, int flags) :
-    """
-        Bind the given SOCK_SEQPACKET to the given set of sock.addr.sockaddr's.
-
-            sd          the system socket FD
-            addresses   the list of qmsk.net.sock.addr.sockaddr's
-            flags       one of SCTP_BINDX_ADD/REM_ADDR
-        
-    """
-
-    # ensure that addrs stays the same... ?
-    addrs = tuple(addrs)
-
-    # alloc buffer to hold all the sockaddr_*'s
-    cdef char *addr_buf = <char *> libc.alloca(addrsoup_len(addrs))
-
-    # store
-    addrsoup_store(addrs, addr_buf)
+cdef class sctp_socket (qmsk.net.socket.socket.socket) :
 
-    # then call
-    if c_sctp_bindx(sd, <platform.sockaddr *> addr_buf, len(addrs), flags) < 0 :
-        raise_errno('sctp_bindx')
-
-def sctp_connectx (int sd, object addrs) :
-    """
-        Connect the given SOCK_SEQPACKET to the given set of remote sock.addr.sockaddr's.
-
-            sd          the system socket FD
-            addresses   the list of qmsk.net.sock.addr.sockaddr's
-        
-    """
+    def __init__ (self, int family = platform.AF_INET, int socktype = platform.SOCK_SEQPACKET, int protocol = IPPROTO_SCTP, int fd = -1) :
+        """
+            Same behaviour as socket.__init__, but different defaults.
+        """
 
-    # ensure that addrs stays the same... ?
-    addrs = tuple(addrs)
-
-    # alloc buffer to hold all the sockaddr_*'s
-    cdef char *addr_buf = <char *> libc.alloca(addrsoup_len(addrs))
+        qmsk.net.socket.socket.socket.__init__(self, family, socktype, protocol, fd)
 
-    # store
-    addrsoup_store(addrs, addr_buf)
+    def sctp_bindx (self, object addrs, int flags) :
+        """
+            Bind this IPPROTO_SCTP socket to the given set of local addresses.
 
-    # then call
-    if c_sctp_connectx(sd, <platform.sockaddr *> addr_buf, len(addrs)) < 0 :
-        raise_errno('sctp_connectx')
+            This may be called multiple times on a socket, even after bind(), to change the set of local addresses.
+            This may affect ongoing associations, or only new associations.
 
+                addresses   the list of sockaddr's
+                flags       one of SCTP_BINDX_ADD/REM_ADDR
+            
+        """
+
+        # ensure that addrs stays the same... ?
+        addrs = tuple(addrs)
+
+        # alloc buffer to hold all the sockaddr_*'s
+        cdef char *addr_buf = <char *> libc.alloca(addrsoup_len(addrs))
+
+        # store
+        addrsoup_store(addrs, addr_buf)
+
+        # then call
+        if sctp_bindx(self.fd, <platform.sockaddr *> addr_buf, len(addrs), flags) :
+            raise_errno('sctp_bindx')
+
+    def sctp_connectx (self, int sd, object addrs) :
+        """
+            Establish an association with the given set of remote sockaddr's.
+
+                addresses   the list of sockaddr's
+            
+        """
+
+        # ensure that addrs stays the same... ?
+        addrs = tuple(addrs)
+
+        # alloc buffer to hold all the sockaddr_*'s
+        cdef char *addr_buf = <char *> libc.alloca(addrsoup_len(addrs))
+
+        # store
+        addrsoup_store(addrs, addr_buf)
+
+        # then call
+        if sctp_connectx(self.fd, <platform.sockaddr *> addr_buf, len(addrs)) :
+            raise_errno('sctp_connectx')
+
+
--- a/qmsk/net/socket/socket.pxd	Mon Aug 17 01:29:31 2009 +0300
+++ b/qmsk/net/socket/socket.pxd	Mon Aug 17 19:40:23 2009 +0300
@@ -8,7 +8,7 @@
     """
         Represents a single OS-level socket
         
-        >>> from qmsk.net.socket import addr
+        >>> from qmsk.net.socket import address as addr
         >>> from qmsk.net.socket.constants import *
 
         >>> s = socket(1337)
@@ -33,6 +33,15 @@
           ...
         OSError: [Errno 111] Connection refused
         
+
+        >>> s1 = socket(AF_INET, SOCK_STREAM); s2 = socket(AF_INET, SOCK_STREAM)
+        >>> s1.listen(1);
+        >>> s2.connect(s1.getsockname())
+        >>> s12, s12_addr = s1.accept()
+        >>> s12_addr == s12.getpeername() == s2.getsockname()
+        True
+        >>> s1.close(); s2.close()
+
     """
 
     cdef readonly socket_t fd