qmsk/net/socket/socket.pyx
author Tero Marttila <terom@fixme.fi>
Mon, 17 Aug 2009 01:24:28 +0300
changeset 19 e6b670dbfe3b
parent 18 43a57943af9f
child 20 0e4933d5862e
permissions -rw-r--r--
socket.setblocking
7
74fde84264b1 broke Cython with this package magic
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
     1
from qmsk.net.socket.socket cimport *
74fde84264b1 broke Cython with this package magic
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
     2
from qmsk.net.socket.addr cimport sockaddr, build_sockaddr
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
     3
10
94b0d5a208c1 split up socket.platform
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
     4
cimport qmsk.net.socket.platform as platform
11
7ae92c2b433f move libc+py back to qmsk.net.x
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
     5
cimport qmsk.net.libc as libc, qmsk.net.py as py
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
11
7ae92c2b433f move libc+py back to qmsk.net.x
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
     7
from qmsk.net.py cimport raise_errno
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
     9
cdef parse_sockaddr (platform.sockaddr **sa_ptr, platform.socklen_t *sa_len, sockaddr addr, int optional = 0) :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    10
    if addr is not None :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    11
        addr._get_sockaddr(sa_ptr, sa_len)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    13
    elif optional :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    14
        sa_ptr[0] = NULL
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    15
        sa_len[0] = 0
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    16
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    17
    else :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    18
        raise ValueError(addr)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    19
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    20
cdef parse_buf (void **buf_ptr, size_t *buf_len, object buf, int optional = 0) :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    21
    cdef libc.ssize_t tmp_len
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    22
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    23
    if buf is not None :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    24
        # XXX: test that except works right
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
    25
        # XXX: this complains about const...
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    26
        py.PyObject_AsCharBuffer(buf, <char **> buf_ptr, &tmp_len)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    27
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    28
        # XXX: ensure that this is >= 0
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    29
        buf_len[0] = tmp_len
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    30
    
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    31
    elif optional :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    32
        buf_ptr[0] = NULL
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    33
        buf_len[0] = 0
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    34
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    35
    else :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    36
        raise ValueError(buf)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    37
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    38
## helper for socket.recv*
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    39
# XXX: make sure these don't leak the PyString in case of errors...
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    40
cdef struct sockbuf :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    41
    py.PyObject *str
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    42
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    43
cdef char* sockbuf_init (sockbuf *buf, size_t len) :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    44
    """
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    45
        Initialize the sockbuf to contain a PyString that can hold `len` bytes, and return a pointer into its
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    46
        contents as a char*.
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    47
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    48
        Note that this requires use of a try-finally with sockbuf_deinit...
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    49
    """
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    50
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    51
    buf.str = py.PyString_FromStringAndSize(NULL, len)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    52
    
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    53
    return py.PyString_AS_STRING(buf.str)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    54
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    55
cdef object sockbuf_truncate (sockbuf *buf, size_t len) :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    56
    """
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    57
        Truncate the given sockbuf's PyString to the given length, and return the PyObject*
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    58
    """
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    59
    
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    60
    # optimize for the no-need-to-resize case
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    61
    # this also fixes behaviour for zero-length strings (heh), since they're interned and can't be resized
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    62
    if len != py.PyString_GET_SIZE(buf.str) :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    63
        py._PyString_Resize(&buf.str, len)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    64
    
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    65
    return <object> buf.str
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    66
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    67
cdef void sockbuf_deinit (sockbuf *buf) :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    68
    """
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    69
        Release the PyObject.
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    70
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    71
        This is safe if the sockbuf was initialized to zero.
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    72
    """
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    73
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    74
    py.Py_XDECREF(buf.str)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
    75
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
# XXX: do some GIL-releasin'
8
b3880dafbab1 phew, things are working
Tero Marttila <terom@fixme.fi>
parents: 7
diff changeset
    77
cdef class socket :
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
13
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
    79
    def __cinit__ (self) :
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
        """
13
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
    81
            Initialize the socket to set fd to -1, so that we dont't try and close stdin too often :)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
13
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
    84
        self.fd = -1
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
13
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
    86
    def __init__ (self, int family = platform.AF_INET, int socktype = platform.SOCK_STREAM, int protocol = 0, int fd = -1) :
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
        """
13
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
    88
            Create a new socket endpoint with the given family/domain, socktype and optionally, specific protocol,
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
    89
            unless the fd argument is given as >= 0, in which case it used directly.
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
                family      - one of AF_*
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
                socktype    - one of SOCK_*
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
                protocol    - one of IPPROTO_* or zero to select default
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
13
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
    96
        if fd >= 0 :
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
    97
            # given fd
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
    98
            self.fd = fd
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
    99
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   100
        else :
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   101
            # socket()
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   102
            self.fd = platform.socket(family, socktype, protocol)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
        
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
        # trap
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
        if self.fd < 0 :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
            raise_errno('socket')
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   108
    def fileno (self) :
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   109
        """
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   110
            Returns the OS-level file desriptor for this socket as an integer
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   111
        """
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   112
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   113
        return self.fd
19
e6b670dbfe3b socket.setblocking
Tero Marttila <terom@fixme.fi>
parents: 18
diff changeset
   114
    
e6b670dbfe3b socket.setblocking
Tero Marttila <terom@fixme.fi>
parents: 18
diff changeset
   115
    def setblocking (self, bint blocking = True) :
e6b670dbfe3b socket.setblocking
Tero Marttila <terom@fixme.fi>
parents: 18
diff changeset
   116
        """
e6b670dbfe3b socket.setblocking
Tero Marttila <terom@fixme.fi>
parents: 18
diff changeset
   117
            Control the OS-level nonblocking-IO mode flag for this socket.
e6b670dbfe3b socket.setblocking
Tero Marttila <terom@fixme.fi>
parents: 18
diff changeset
   118
e6b670dbfe3b socket.setblocking
Tero Marttila <terom@fixme.fi>
parents: 18
diff changeset
   119
                blocking    - True for normal blocking operation, False to use non-blocking operation
e6b670dbfe3b socket.setblocking
Tero Marttila <terom@fixme.fi>
parents: 18
diff changeset
   120
        """
e6b670dbfe3b socket.setblocking
Tero Marttila <terom@fixme.fi>
parents: 18
diff changeset
   121
        
e6b670dbfe3b socket.setblocking
Tero Marttila <terom@fixme.fi>
parents: 18
diff changeset
   122
        # fcntl magic
e6b670dbfe3b socket.setblocking
Tero Marttila <terom@fixme.fi>
parents: 18
diff changeset
   123
        libc.fcntl_set_flag(self.fd, libc.O_NONBLOCK, not blocking)
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   124
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
    def bind (self, sockaddr addr) :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
            Bind this socket to the given local socket address. The given sockaddr should be of the same or a
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
            compatible address family.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
                addr        - the local address to bind to. The port may be zero to let the system choose an unused
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
                              ephemeral port.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   134
        cdef platform.sockaddr *sa
10
94b0d5a208c1 split up socket.platform
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   135
        cdef platform.socklen_t sa_len
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   136
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   137
        # XXX: require non-NULL addr?
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   138
        parse_sockaddr(&sa, &sa_len, addr, 1)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
        # bind()
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   141
        if platform.bind(self.fd, sa, sa_len) :
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
            raise_errno('bind')
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
    def listen (self, int backlog) :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
            Listen for connections, marking this socket as a passive socket, which can accept incoming connection
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
            requests using sock.accept().
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
            It is customary to call .bind() before .listen().
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
                backlog     - maximum number of pending connections (those not yet .accept()'d).
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
        
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
        # listen()
10
94b0d5a208c1 split up socket.platform
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   155
        if platform.listen(self.fd, backlog) :
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
            raise_errno('listen')
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
    def connect (self, sockaddr addr) :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
            Initiate a connection, connecting this socket to the remote endpoint specified by `addr`. The given sockaddr
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
            should be of the same or a compatible address family.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
            If the socket is in non-blocking mode, this will presumeably return errno.EINPROGRESS.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
            If the socket has not yet been bound (using .bind()), the system will pick an appropriate local address and
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
            ephemeral port.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
                addr        - the remote address to connect to.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   171
        cdef platform.sockaddr *sa
10
94b0d5a208c1 split up socket.platform
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   172
        cdef platform.socklen_t sa_len
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   174
        # XXX: require non-NULL addr?
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   175
        parse_sockaddr(&sa, &sa_len, addr, 1)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
        
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
        # connect()
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   178
        if platform.connect(self.fd, sa, sa_len) :
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
            raise_errno('connect')
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
    def accept (self) :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
            Accept a connection, dequeueing the first pending connection and returning a new sock object for it. This
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
            socket must be a connection-based socket (SOCK_STREAM/SOCK_SEQPACKET) and in the passive listening mode
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
            (.listen()).
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   187
            This returns a (sock, src_addr) tuple:
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
                sock        - the newly created sock, corresponding to the incoming connection
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   189
                src_addr    - the remote address of the incoming connection
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
        
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
        # prep the sockaddr that we will return
10
94b0d5a208c1 split up socket.platform
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   193
        cdef platform.sockaddr_storage ss
94b0d5a208c1 split up socket.platform
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   194
        cdef platform.socklen_t ss_len = sizeof(ss)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
        # accept()
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   197
        cdef socket_t sock_fd = platform.accept(self.fd, <platform.sockaddr *> &ss, &ss_len)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
        if sock_fd < 0 :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
            raise_errno('accept')
13
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   201
        
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   202
        try :
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   203
            # prep the new socket
15
8e7037cc05c7 fix socket.accept, and add simple PyString_Resize code
Tero Marttila <terom@fixme.fi>
parents: 14
diff changeset
   204
            sock_obj = socket(fd=sock_fd)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
13
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   206
        except :
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   207
            # XXX: don't leak the socket fd? How does socket.__init__ handle this?
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   208
            platform.close(sock_fd)
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   209
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   210
            raise
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
        # prep the new addr
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   213
        cdef sockaddr src_addr = build_sockaddr(<platform.sockaddr *> &ss, ss_len)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   215
        return sock_obj, src_addr
18
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   216
    
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   217
    def getsockname (self) :
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   218
        """
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   219
            Get the local address this socket is currently bound to. This can be set using bind(), or automatically.
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   220
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   221
            Returns a sockaddr object.
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   222
        """
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   223
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   224
        # prep the sockaddr that we will return
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   225
        cdef platform.sockaddr_storage ss
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   226
        cdef platform.socklen_t ss_len = sizeof(ss)
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   227
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   228
        # getsockname()
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   229
        if platform.getsockname(self.fd, <platform.sockaddr *> &ss, &ss_len) :
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   230
            raise_errno('getsockname')
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   231
        
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   232
        # build the new sockaddr
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   233
        return build_sockaddr(<platform.sockaddr *> &ss, ss_len)
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   234
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   235
    def getpeername (self) :
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   236
        """
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   237
            Get the remote address this socket is currently connected to.
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   238
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   239
            Returns a sockaddr object.
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   240
        """
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   241
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   242
        # prep the sockaddr that we will return
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   243
        cdef platform.sockaddr_storage ss
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   244
        cdef platform.socklen_t ss_len = sizeof(ss)
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   245
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   246
        # getpeername()
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   247
        if platform.getpeername(self.fd, <platform.sockaddr *> &ss, &ss_len) :
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   248
            raise_errno('getpeername')
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   249
        
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   250
        # build the new sockaddr
43a57943af9f getsockname/getpeername
Tero Marttila <terom@fixme.fi>
parents: 17
diff changeset
   251
        return build_sockaddr(<platform.sockaddr *> &ss, ss_len)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   252
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   253
    def send (self, object buf, int flags = 0) :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   254
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   255
            Transmit a message to the connected remote endpoint.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   256
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   257
                buf         - the data to send
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   258
                flags       - (optional) MSG_* flags to send with
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   259
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   260
            Returns the number of bytes sent, which may be less than the length of buf.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   261
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   262
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   263
        cdef void *buf_ptr
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   264
        cdef size_t buf_len
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   265
        cdef libc.ssize_t ret
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   266
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   267
        parse_buf(&buf_ptr, &buf_len, buf, 0)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   268
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   269
        # send()
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   270
        ret = platform.send(self.fd, buf_ptr, buf_len, flags)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   271
        
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   272
        if ret < 0 :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   273
            raise_errno('send')
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   274
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   275
        else :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   276
            return ret
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   277
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   278
    def sendto (self, object buf, int flags = 0, sockaddr addr = None) :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   279
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   280
            Transmit a message to the given remote endpoint. If this socket is connected, the addr must not be
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   281
            specified, and this acts like send()
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   282
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   283
                buf         - the data to send
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   284
                flags       - (optional) MSG_* flags to send with
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   285
                addr        - (optional) target address
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   286
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   287
            Returns the number of bytes sent, which may be less than the length of buf.
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   288
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   289
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   290
        cdef void *buf_ptr
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   291
        cdef size_t buf_len
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   292
        cdef libc.ssize_t ret
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   293
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   294
        cdef platform.sockaddr *sa
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   295
        cdef platform.socklen_t sa_len
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   296
       
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   297
        parse_sockaddr(&sa, &sa_len, addr, 1)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   298
        parse_buf(&buf_ptr, &buf_len, buf, 0)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   299
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   300
        # send()
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   301
        ret = platform.sendto(self.fd, buf_ptr, buf_len, flags, sa, sa_len)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   302
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   303
        if ret < 0 :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   304
            raise_errno('sendto')
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   305
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   306
        else :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   307
            return ret
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   308
    
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   309
    def sendmsg (self, sockaddr addr = None, iov = None, control = None, int flags = 0) :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   310
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   311
            Transmit an extended message to the given remote endpoint (or default for connected sockets) with the given
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   312
            extra parameters.
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   313
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   314
                addr        - (optional) destination address (struct msghdr::msg_name)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   315
                iov         - (optional) sequence of read-buffers to transmit
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   316
                control     - (optional) control message to transmit
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   317
                flags       - (optional) MSG_* flags to send with
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   318
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   319
            Returns the number of bytes sent, which may be less than the total length of iov.
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   320
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   321
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   322
        cdef libc.ssize_t ret
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   323
        cdef libc.iovec *iovec
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   324
        cdef platform.msghdr msg
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   325
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   326
        libc.memset(&msg, 0, sizeof(msg))
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   327
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   328
        parse_sockaddr(<platform.sockaddr **> &msg.msg_name, &msg.msg_namelen, addr, 1)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   329
        parse_buf(&msg.msg_control, &msg.msg_controllen, control, 1)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   330
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   331
        # iov
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   332
        if iov :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   333
            iov = tuple(iov)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   334
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   335
            # numerb of bufs = number of iovecs
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   336
            msg.msg_iovlen = len(iov)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   337
                
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   338
            # alloca the required number of iovec's
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   339
            msg.msg_iov = <libc.iovec *> libc.alloca(msg.msg_iovlen * sizeof(libc.iovec))
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   340
            
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   341
            # fill in the iovecs
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   342
            for i, buf in enumerate(iov) :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   343
                iovec = &msg.msg_iov[i]
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   344
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   345
                parse_buf(&iovec.iov_base, &iovec.iov_len, buf, 1)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   346
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   347
        # sendmsg()
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   348
        ret = platform.sendmsg(self.fd, &msg, flags)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   349
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   350
        if ret < 0 :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   351
            raise_errno('sendmsg')
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   352
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   353
        else :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   354
            return ret
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   355
       
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   356
    def write (self, object buf) :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   357
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   358
            Write data to socket, mostly equivalent to send() with flags=0.
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   359
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   360
                buf         - the data to send
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   361
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   362
            Returns the number of bytes sent, which may be less than the length of buf.
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   363
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   364
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   365
        cdef void *buf_ptr
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   366
        cdef size_t buf_len
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   367
        cdef libc.ssize_t ret
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   368
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   369
        parse_buf(&buf_ptr, &buf_len, buf, 0)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   370
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   371
        # send()
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   372
        ret = libc.write(self.fd, buf_ptr, buf_len)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   373
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   374
        if ret < 0 :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   375
            raise_errno('write')
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   376
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   377
        else :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   378
            return ret
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   379
    
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   380
    def writev (self, iov) :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   381
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   382
            Write data to a socket from multiple read-buffers.
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   383
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   384
                iov         - sequence of read-buffers to transmit
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   385
            
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   386
            Returns the number of bytes sent, which may be less than the total length of iov.
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   387
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   388
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   389
        # iov
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   390
        cdef libc.iovec *iov_list = NULL
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   391
        cdef size_t iov_count = 0
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   392
        cdef libc.iovec *iovec
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   393
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   394
        iov = tuple(iov)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   395
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   396
        # numerb of bufs = number of iovecs
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   397
        iov_count = len(iov)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   398
            
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   399
        # alloca the required number of iovec's
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   400
        iov_list = <libc.iovec *> libc.alloca(iov_count * sizeof(libc.iovec))
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   401
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   402
        # fill in the iovecs
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   403
        for i, buf in enumerate(iov) :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   404
            iovec = &iov_list[i]
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   405
                
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   406
            parse_buf(&iovec.iov_base, &iovec.iov_len, buf, 1)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   407
            
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   408
        # sendmsg()
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   409
        ret = libc.writev(self.fd, iov_list, iov_count)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   410
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   411
        if ret < 0 :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   412
            raise_errno('writev')
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   413
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   414
        else :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   415
            return ret
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   416
    
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   417
    def recv (self, size_t len, int flags = 0) :
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   418
        """
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   419
            Recieve a message, reading and returning at most `len` bytes.
13
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   420
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   421
                len         - size of buffer to use for recv
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   422
                flags       - (optional) MSG_* flags to use for recv()
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   423
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   424
            Returns the recieved data as a newly allocated string of the correct length.
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   425
        """
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   426
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   427
        cdef sockbuf sb
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   428
        cdef libc.ssize_t ret
15
8e7037cc05c7 fix socket.accept, and add simple PyString_Resize code
Tero Marttila <terom@fixme.fi>
parents: 14
diff changeset
   429
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   430
        # alloc the recv buffer
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   431
        cdef char *buf = sockbuf_init(&sb, len)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   432
        
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   433
        try :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   434
            # recv()
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   435
            ret = platform.recv(self.fd, buf, len, flags)
15
8e7037cc05c7 fix socket.accept, and add simple PyString_Resize code
Tero Marttila <terom@fixme.fi>
parents: 14
diff changeset
   436
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   437
            if ret < 0 :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   438
                raise_errno('recv')
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   439
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   440
            # truncate to correct length
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   441
            return sockbuf_truncate(&sb, ret)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   442
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   443
        finally :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   444
            sockbuf_deinit(&sb)
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   445
    
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   446
    def recvfrom (self, size_t len, int flags = 0) :
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   447
        """
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   448
            Recieve a message, reading at most `len` bytes, also returning the source address.
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   449
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   450
                len         - size of buffer to use for recv
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   451
                flags       - (optional) MSG_* flags to use for recvfrom()
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   452
            
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   453
            Returns the recieved data and the source address as a (buf, src_addr) tuple :
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   454
                buf         - a newly allocated string containing the recieved data, of the correct length
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   455
                src_addr    - the source address the message was recieved from
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   456
        """
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   457
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   458
        cdef sockbuf sb
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   459
        cdef libc.ssize_t ret
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   460
        cdef object str
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   461
        cdef sockaddr src_addr
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   462
            
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   463
        # prep the sockaddr that we will return
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   464
        cdef platform.sockaddr_storage ss
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   465
        cdef platform.socklen_t ss_len = sizeof(ss)
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   466
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   467
        # alloc recv buf
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   468
        cdef char *buf = sockbuf_init(&sb, len)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   469
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   470
        try :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   471
            # recvfrom()
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   472
            ret = platform.recvfrom(self.fd, buf, len, flags, <platform.sockaddr *> &ss, &ss_len)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   473
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   474
            if ret < 0 :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   475
                raise_errno('recv')
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   476
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   477
            # truncate
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   478
            str = sockbuf_truncate(&sb, ret)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   479
            
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   480
            # prep the new addr
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   481
            src_addr = build_sockaddr(<platform.sockaddr *> &ss, ss_len)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   482
            
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   483
            return str, src_addr
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   484
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   485
        finally :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   486
            sockbuf_deinit(&sb)
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   487
    
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   488
    def recvmsg (self, bint recv_addr = True, object iov_lens = None, size_t control_len = 0, int flags = 0) :
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   489
        """
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   490
            Recieve a message along with some extra data.
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   491
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   492
                recv_addr   - ask for and return a sockaddr for the source address of the message?
17
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   493
                iov_lens    - (optional) sequence of buffer sizes to use for the message data iov
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   494
                control_len - (optional) amount of auxiliary data to recieve
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   495
                flags       - (optional) flags to pass to recvmsg()
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   496
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   497
            Returns a (name, iovs, control, flags) tuple :
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   498
                name        - the source address of the message, or None
17
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   499
                iovs        - sequence of strings containing the recieved data corresponding to the iov_lens
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   500
                control     - string containing recieved control message, if any
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   501
                flags       - recieved flags
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   502
        """
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   503
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   504
        cdef platform.msghdr msg
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   505
        cdef sockbuf *sb_list, *sb, cmsg_sb
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   506
        cdef libc.iovec *iovec
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   507
        cdef size_t iov_len, i, msg_len
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   508
        cdef libc.ssize_t ret
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   509
        cdef sockaddr name = None 
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   510
        cdef object iovs = None
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   511
        cdef object control = None
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   512
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   513
        libc.memset(&msg, 0, sizeof(msg))
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   514
        libc.memset(&cmsg_sb, 0, sizeof(cmsg_sb))
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   515
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   516
        # prep the sockaddr that we will return
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   517
        cdef platform.sockaddr_storage ss
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   518
        
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   519
        # ask for a name?
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   520
        if recv_addr :
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   521
            msg.msg_name = <void *> &ss
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   522
            msg.msg_namelen = sizeof(ss)
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   523
        
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   524
        try :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   525
            # build iov?
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   526
            if iov_lens :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   527
                # stabilize
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   528
                iov_lens = tuple(iov_lens)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   529
                
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   530
                msg.msg_iovlen = len(iov_lens)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   531
                
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   532
                # alloc each iov plus a sockbuf for storing the PyString
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   533
                msg.msg_iov = <libc.iovec *> libc.alloca(msg.msg_iovlen * sizeof(libc.iovec))
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   534
                sb_list = <sockbuf *> libc.alloca(msg.msg_iovlen * sizeof(sockbuf))
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   535
                
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   536
                # zero out so we can cleanup
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   537
                libc.memset(sb_list, 0, msg.msg_iovlen * sizeof(sockbuf))
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   538
                
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   539
                # build each
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   540
                for i, iov_len in enumerate(iov_lens) :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   541
                    # the associated iovec/sockbuf
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   542
                    iovec = &msg.msg_iov[i]
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   543
                    sb = &sb_list[i]
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   544
                    
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   545
                    # set up the sockbuf and iovec
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   546
                    iovec.iov_base = sockbuf_init(&sb_list[i], iov_len)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   547
                    iovec.iov_len = iov_len
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   548
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   549
            # build control buffer?
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   550
            if control_len :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   551
                msg.msg_control = sockbuf_init(&cmsg_sb, control_len)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   552
                msg.msg_controllen = control_len
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   553
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   554
            # recvmsg()
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   555
            ret = platform.recvmsg(self.fd, &msg, flags)
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   556
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   557
            if ret < 0 :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   558
                raise_errno('recvmsg')
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   559
            
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   560
            # name?
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   561
            if msg.msg_name and msg.msg_namelen :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   562
                # build a sockaddr for the name
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   563
                name = build_sockaddr(<platform.sockaddr *> msg.msg_name, msg.msg_namelen)
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   564
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   565
            # iov?
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   566
            if ret :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   567
                assert msg.msg_iov and msg.msg_iovlen
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   568
                
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   569
                iovs = []
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   570
                msg_len = ret
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   571
                i = 0
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   572
                
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   573
                # consume iov's until we have all the data we need
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   574
                while msg_len :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   575
                    # sanity-check
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   576
                    assert i < msg.msg_iovlen
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   577
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   578
                    # get the associated iovec/sockbuf
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   579
                    iovec = &msg.msg_iov[i]
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   580
                    sb = &sb_list[i]
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   581
                    
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   582
                    # calc the size of this iov
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   583
                    # XXX: cdef
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   584
                    iov_len = min(msg_len, iovec.iov_len)
14
c44754cc1ffe some recv magic, still no PyString_Resize, though
Tero Marttila <terom@fixme.fi>
parents: 13
diff changeset
   585
16
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   586
                    # add it as a string
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   587
                    iovs.append(sockbuf_truncate(sb, iov_len))
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   588
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   589
                    # advance
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   590
                    msg_len -= iov_len
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   591
                    i += 1
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   592
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   593
            # control?
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   594
            if msg.msg_control and msg.msg_controllen :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   595
                # build the PyString for the control message
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   596
                control = sockbuf_truncate(&cmsg_sb, msg.msg_controllen)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   597
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   598
            return name, iovs, control, msg.msg_flags
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   599
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   600
        finally :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   601
            # cleanup
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   602
            sockbuf_deinit(&cmsg_sb)
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   603
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   604
            for i in range(msg.msg_iovlen) :
24ce1035b338 sockbuf stuff and fully implement recvmsg
Tero Marttila <terom@fixme.fi>
parents: 15
diff changeset
   605
                sockbuf_deinit(&sb_list[i])
13
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   606
17
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   607
    def read (self, size_t len) :
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   608
        """
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   609
            Read data from a socket, mostly equivalent to a recv() with flags=0.
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   610
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   611
                len         - size of buffer to use for recv
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   612
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   613
            Returns the recieved data as a newly allocated string of the correct length.
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   614
        """
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   615
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   616
        cdef sockbuf sb
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   617
        cdef libc.ssize_t ret
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   618
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   619
        # alloc the recv buffer
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   620
        cdef char *buf = sockbuf_init(&sb, len)
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   621
        
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   622
        try :
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   623
            # recv()
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   624
            ret = libc.read(self.fd, buf, len)
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   625
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   626
            if ret < 0 :
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   627
                raise_errno('read')
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   628
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   629
            # truncate to correct length
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   630
            return sockbuf_truncate(&sb, ret)
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   631
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   632
        finally :
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   633
            sockbuf_deinit(&sb)
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   634
    
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   635
    def readv (self, object iov_lens) :
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   636
        """
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   637
            Read data from a socket into multiple buffers.
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   638
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   639
                iov_lens    - sequence of buffer sizes to use as iovs
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   640
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   641
            Returns a sequence of strings containing the recieved data corresponding to the iov_lens.
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   642
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   643
            XXX: implement using real readv instead of faking it with recvmsg...
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   644
        """
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   645
        
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   646
        # fake using recvmsg
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   647
        _, iovs, _, _ = self.recvmsg(recv_addr=False, iov_lens=iov_lens)
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   648
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   649
        return iovs
5f4077a530b0 add repr for sockaddr, and implment read for sockets, plus a recvmsg wrapper called readv...
Tero Marttila <terom@fixme.fi>
parents: 16
diff changeset
   650
13
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   651
    def shutdown (self, how) :
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   652
        """
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   653
            Shutdown part of a full-duplex connection. 
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   654
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   655
                how         - one of SHUT_*
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   656
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   657
            This does not affect this socket's fd.
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   658
        """
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   659
        
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   660
        # shutdown()
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   661
        if platform.shutdown(self.fd, how) :
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   662
            raise_errno('shutdown')
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   663
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   664
    def close (self) :
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   665
        """
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   666
            Close the socket fd if we have one, invalidating it if succesful.
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   667
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   668
            Note that this will raise an error and keep the fd if the system close() returns an error.
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   669
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   670
            Calling this again after a succesfull close() does nothing.
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   671
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   672
            XXX: SO_LINGER/blocking?
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   673
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   674
            >>> s = socket()
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   675
            >>> s.fd >= 0
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   676
            True
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   677
            >>> s.close()
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   678
            >>> s.fd >= 0
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   679
            False
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   680
            >>> s.close()
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   681
        """
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   682
        
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   683
        # ignore if already closed
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   684
        if self.fd < 0 :
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   685
            return
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   686
        
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   687
        # close()
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   688
        if libc.close(self.fd) :
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   689
            raise_errno('close')
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   690
        
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   691
        # invalidate
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   692
        self.fd = -1
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   693
    
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   694
    def __dealloc__ (self) :
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   695
        """
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   696
            Close the socket fd if one is set, ignoring any errors from close
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   697
        """
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   698
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   699
        if self.fd >= 0 :
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   700
            if libc.close(self.fd) :
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   701
                # XXX: at least warn... ?
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   702
                pass
a1091632a8a7 implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   703