qmsk/net/socket/socket.pyx
author Tero Marttila <terom@fixme.fi>
Sun, 16 Aug 2009 21:54:46 +0300
changeset 13 a1091632a8a7
parent 12 314d47bdd4d9
child 14 c44754cc1ffe
permissions -rw-r--r--
implement __cinit__, shutdown, close, __dealloc__ for socket, and also add a try-except to not leak client sock from accept()
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
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    25
        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
    26
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    27
        # XXX: ensure that this is >= 0
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    28
        buf_len[0] = tmp_len
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    29
    
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    30
    elif optional :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    31
        buf_ptr[0] = NULL
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    32
        buf_len[0] = 0
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    33
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    34
    else :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    35
        raise ValueError(buf)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    36
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
# XXX: do some GIL-releasin'
8
b3880dafbab1 phew, things are working
Tero Marttila <terom@fixme.fi>
parents: 7
diff changeset
    38
cdef class socket :
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
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
    40
    def __cinit__ (self) :
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
        """
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
    42
            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
    43
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
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
    45
        self.fd = -1
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
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
    47
    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
    48
        """
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
    49
            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
    50
            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
    51
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
                family      - one of AF_*
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
                socktype    - one of SOCK_*
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
                protocol    - one of IPPROTO_* or zero to select default
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
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
    57
        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
    58
            # 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
    59
            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
    60
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
    61
        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
    62
            # 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
    63
            self.fd = platform.socket(family, socktype, protocol)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
        
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
        # trap
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
        if self.fd < 0 :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
            raise_errno('socket')
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
    def bind (self, sockaddr addr) :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
            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
    72
            compatible address family.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
                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
    75
                              ephemeral port.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    78
        cdef platform.sockaddr *sa
10
94b0d5a208c1 split up socket.platform
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    79
        cdef platform.socklen_t sa_len
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    80
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    81
        # XXX: require non-NULL addr?
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    82
        parse_sockaddr(&sa, &sa_len, addr, 1)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
        # bind()
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    85
        if platform.bind(self.fd, sa, sa_len) :
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
            raise_errno('bind')
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
    def listen (self, int backlog) :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
            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
    91
            requests using sock.accept().
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
            It is customary to call .bind() before .listen().
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
                backlog     - maximum number of pending connections (those not yet .accept()'d).
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
        
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
        # listen()
10
94b0d5a208c1 split up socket.platform
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    99
        if platform.listen(self.fd, backlog) :
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
            raise_errno('listen')
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
    def connect (self, sockaddr addr) :
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
            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
   105
            should be of the same or a compatible address family.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
            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
   108
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
            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
   110
            ephemeral port.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
                addr        - the remote address to connect to.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   115
        cdef platform.sockaddr *sa
10
94b0d5a208c1 split up socket.platform
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   116
        cdef platform.socklen_t sa_len
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   118
        # XXX: require non-NULL addr?
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   119
        parse_sockaddr(&sa, &sa_len, addr, 1)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
        
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
        # connect()
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   122
        if platform.connect(self.fd, sa, sa_len) :
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
            raise_errno('connect')
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
    def accept (self) :
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
            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
   128
            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
   129
            (.listen()).
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
            This returns a (sock, sockaddr) tuple:
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
                sock        - the newly created sock, corresponding to the incoming connection
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
                sockaddr    - the remote address of the incoming connection
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
        
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
        # prep the sockaddr that we will return
10
94b0d5a208c1 split up socket.platform
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   137
        cdef platform.sockaddr_storage ss
94b0d5a208c1 split up socket.platform
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   138
        cdef platform.socklen_t ss_len = sizeof(ss)
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
        cdef socket_t sock_fd
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
        # accept()
10
94b0d5a208c1 split up socket.platform
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   143
        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
   144
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
        if sock_fd < 0 :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
            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
   147
        
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
   148
        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
   149
            # prep the new 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
   150
            sock_obj = socket(sock_fd)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
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
   152
        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
   153
            # 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
   154
            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
   155
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
   156
            raise
6
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
        # prep the new addr
10
94b0d5a208c1 split up socket.platform
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   159
        sock_addr = build_sockaddr(<platform.sockaddr *> &ss, ss_len)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
        return sock_obj, sock_addr
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
    def send (self, object buf, int flags = 0) :
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
            Transmit a message to the connected remote endpoint.
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   167
                buf         - the data to send
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   168
                flags       - (optional) MSG_* flags to send with
6
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
            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
   171
        """
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   173
        cdef void *buf_ptr
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   174
        cdef size_t buf_len
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   175
        cdef libc.ssize_t ret
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   177
        parse_buf(&buf_ptr, &buf_len, buf, 0)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   178
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
        # send()
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   180
        ret = platform.send(self.fd, buf_ptr, buf_len, flags)
6
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
        
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
        if ret < 0 :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
            raise_errno('send')
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
        else :
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
            return ret
10bd48c9b6ce socket type, mass rename
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
12
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   188
    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
   189
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   190
            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
   191
            specified, and this acts like send()
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   192
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   193
                buf         - the data to send
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   194
                flags       - (optional) MSG_* flags to send with
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   195
                addr        - (optional) target address
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   196
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   197
            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
   198
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   199
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   200
        cdef void *buf_ptr
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   201
        cdef size_t buf_len
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   202
        cdef libc.ssize_t ret
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   203
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   204
        cdef platform.sockaddr *sa
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   205
        cdef platform.socklen_t sa_len
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   206
       
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   207
        parse_sockaddr(&sa, &sa_len, addr, 1)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   208
        parse_buf(&buf_ptr, &buf_len, buf, 0)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   209
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   210
        # send()
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   211
        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
   212
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   213
        if ret < 0 :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   214
            raise_errno('sendto')
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   215
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   216
        else :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   217
            return ret
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   218
    
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   219
    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
   220
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   221
            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
   222
            extra parameters.
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   223
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   224
                addr        - (optional) destination address (struct msghdr::msg_name)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   225
                iov         - (optional) sequence of read-buffers to transmit
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   226
                control     - (optional) control message to transmit
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   227
                flags       - (optional) MSG_* flags to send with
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   228
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   229
            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
   230
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   231
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   232
        cdef libc.ssize_t ret
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   233
        cdef libc.iovec *iovec
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   234
        cdef platform.msghdr msg
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   235
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   236
        libc.memset(&msg, 0, sizeof(msg))
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   237
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   238
        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
   239
        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
   240
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   241
        # iov
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   242
        if iov :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   243
            iov = tuple(iov)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   244
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   245
            # numerb of bufs = number of iovecs
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   246
            msg.msg_iovlen = len(iov)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   247
                
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   248
            # alloca the required number of iovec's
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   249
            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
   250
            
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   251
            # fill in the iovecs
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   252
            for i, buf in enumerate(iov) :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   253
                iovec = &msg.msg_iov[i]
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   254
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   255
                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
   256
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   257
        # sendmsg()
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   258
        ret = platform.sendmsg(self.fd, &msg, flags)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   259
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   260
        if ret < 0 :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   261
            raise_errno('sendmsg')
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   262
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   263
        else :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   264
            return ret
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   265
       
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   266
    def write (self, object buf) :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   267
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   268
            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
   269
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   270
                buf         - the data to send
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   271
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   272
            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
   273
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   274
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   275
        cdef void *buf_ptr
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   276
        cdef size_t buf_len
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   277
        cdef libc.ssize_t ret
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   278
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   279
        parse_buf(&buf_ptr, &buf_len, buf, 0)
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   280
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   281
        # send()
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   282
        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
   283
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   284
        if ret < 0 :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   285
            raise_errno('write')
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
        else :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   288
            return ret
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
    def writev (self, iov) :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   291
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   292
            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
   293
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   294
                iov         - sequence of read-buffers to transmit
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   295
            
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   296
            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
   297
        """
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   298
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   299
        # iov
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   300
        cdef libc.iovec *iov_list = NULL
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   301
        cdef size_t iov_count = 0
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   302
        cdef libc.iovec *iovec
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   303
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   304
        iov = tuple(iov)
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
        # numerb of bufs = number of iovecs
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   307
        iov_count = len(iov)
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
        # alloca the required number of iovec's
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   310
        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
   311
        
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   312
        # fill in the iovecs
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   313
        for i, buf in enumerate(iov) :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   314
            iovec = &iov_list[i]
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   315
                
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   316
            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
   317
            
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   318
        # sendmsg()
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   319
        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
   320
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   321
        if ret < 0 :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   322
            raise_errno('writev')
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   323
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   324
        else :
314d47bdd4d9 full range of send/write operations
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   325
            return ret
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
   326
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
   327
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
   328
    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
   329
        """
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
   330
            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
   331
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
   332
                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
   333
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
   334
            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
   335
        """
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
   336
        
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
   337
        # 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
   338
        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
   339
            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
   340
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
   341
    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
   342
        """
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
   343
            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
   344
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
   345
            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
   346
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
   347
            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
   348
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
   349
            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
   350
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
   351
            >>> 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
   352
            >>> 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
   353
            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
   354
            >>> 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
   355
            >>> 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
   356
            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
   357
            >>> 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
   358
        """
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
   359
        
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
   360
        # 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
   361
        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
   362
            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
   363
        
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
   364
        # 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
   365
        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
   366
            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
   367
        
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
   368
        # 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
   369
        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
   370
    
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
   371
    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
   372
        """
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
   373
            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
   374
        """
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
   375
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
   376
        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
   377
            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
   378
                # 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
   379
                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
   380