126 """ |
134 """ |
127 Accept a connection, dequeueing the first pending connection and returning a new sock object for it. This |
135 Accept a connection, dequeueing the first pending connection and returning a new sock object for it. This |
128 socket must be a connection-based socket (SOCK_STREAM/SOCK_SEQPACKET) and in the passive listening mode |
136 socket must be a connection-based socket (SOCK_STREAM/SOCK_SEQPACKET) and in the passive listening mode |
129 (.listen()). |
137 (.listen()). |
130 |
138 |
131 This returns a (sock, sockaddr) tuple: |
139 This returns a (sock, src_addr) tuple: |
132 sock - the newly created sock, corresponding to the incoming connection |
140 sock - the newly created sock, corresponding to the incoming connection |
133 sockaddr - the remote address of the incoming connection |
141 src_addr - the remote address of the incoming connection |
134 """ |
142 """ |
135 |
143 |
136 # prep the sockaddr that we will return |
144 # prep the sockaddr that we will return |
137 cdef platform.sockaddr_storage ss |
145 cdef platform.sockaddr_storage ss |
138 cdef platform.socklen_t ss_len = sizeof(ss) |
146 cdef platform.socklen_t ss_len = sizeof(ss) |
139 |
147 |
140 cdef socket_t sock_fd |
|
141 |
|
142 # accept() |
148 # accept() |
143 sock_fd = platform.accept(self.fd, <platform.sockaddr *> &ss, &ss_len) |
149 cdef socket_t sock_fd = platform.accept(self.fd, <platform.sockaddr *> &ss, &ss_len) |
144 |
150 |
145 if sock_fd < 0 : |
151 if sock_fd < 0 : |
146 raise_errno('accept') |
152 raise_errno('accept') |
147 |
153 |
148 try : |
154 try : |
321 if ret < 0 : |
327 if ret < 0 : |
322 raise_errno('writev') |
328 raise_errno('writev') |
323 |
329 |
324 else : |
330 else : |
325 return ret |
331 return ret |
326 |
332 |
|
333 def recv (self, size_t len, int flags = 0) : |
|
334 """ |
|
335 Recieve a message, reading and returning at most `len` bytes. |
|
336 |
|
337 len - size of buffer to use for recv |
|
338 flags - (optional) MSG_* flags to use for recv() |
|
339 |
|
340 Returns the recieved data as a newly allocated string of the correct length. |
|
341 """ |
|
342 |
|
343 # alloc a new return str |
|
344 # XXX: len overflow... |
|
345 cdef object str = py.PyString_FromStringAndSize(NULL, len) |
|
346 cdef char *buf = py.PyString_AS_STRING(str) |
|
347 |
|
348 # recv() |
|
349 cdef libc.ssize_t ret = platform.recv(self.fd, buf, len, flags) |
|
350 |
|
351 if ret < 0 : |
|
352 raise_errno('recv') |
|
353 |
|
354 # XXX: figure out how to call _PyString_Resize |
|
355 return str[:ret] |
|
356 |
|
357 def recvfrom (self, size_t len, int flags = 0) : |
|
358 """ |
|
359 Recieve a message, reading at most `len` bytes, also returning the source address. |
|
360 |
|
361 len - size of buffer to use for recv |
|
362 flags - (optional) MSG_* flags to use for recvfrom() |
|
363 |
|
364 Returns the recieved data and the source address as a (buf, src_addr) tuple : |
|
365 buf - a newly allocated string containing the recieved data, of the correct length |
|
366 src_addr - the source address the message was recieved from |
|
367 """ |
|
368 |
|
369 # alloc a new return str |
|
370 # XXX: len overflow... |
|
371 cdef object str = py.PyString_FromStringAndSize(NULL, len) |
|
372 cdef char *buf = py.PyString_AS_STRING(str) |
|
373 |
|
374 # prep the sockaddr that we will return |
|
375 cdef platform.sockaddr_storage ss |
|
376 cdef platform.socklen_t ss_len = sizeof(ss) |
|
377 |
|
378 # recvfrom() |
|
379 cdef libc.ssize_t ret = platform.recvfrom(self.fd, buf, len, flags, <platform.sockaddr *> &ss, &ss_len) |
|
380 |
|
381 if ret < 0 : |
|
382 raise_errno('recv') |
|
383 |
|
384 # prep the new addr |
|
385 cdef sock_addr = build_sockaddr(<platform.sockaddr *> &ss, ss_len) |
|
386 |
|
387 # XXX: figure out how to call _PyString_Resize |
|
388 return str[:ret], sock_addr |
|
389 |
|
390 def recvmsg (self, bint recv_addr = True, object iov_lens = None, size_t control_len = 0, int flags = 0) : |
|
391 """ |
|
392 Recieve a message along with some extra data. |
|
393 |
|
394 recv_addr - ask for and return a sockaddr for the source address of the message? |
|
395 lenv - (optional) sequence of buffer sizes to use for the message data iov |
|
396 control_len - (optional) amount of auxiliary data to recieve |
|
397 flags - (optional) flags to pass to recvmsg() |
|
398 |
|
399 Returns a (name, iov, control, flags) tuple : |
|
400 name - the source address of the message, or None |
|
401 iov - sequence of strings containing the recieved data, each at most lenv[x] bytes long |
|
402 control - string containing recieved control message, if any |
|
403 flags - recieved flags |
|
404 """ |
|
405 |
|
406 cdef platform.msghdr msg |
|
407 |
|
408 libc.memset(&msg, 0, sizeof(msg)) |
|
409 |
|
410 # prep the sockaddr that we will return |
|
411 cdef platform.sockaddr_storage ss |
|
412 |
|
413 # ask for a name? |
|
414 if recv_addr : |
|
415 msg.msg_name = <void *> &ss |
|
416 msg.msg_namelen = sizeof(ss) |
|
417 |
|
418 # build iov? |
|
419 if iov_lens : |
|
420 # XXX: implement |
|
421 pass |
|
422 |
|
423 # build control buffer? |
|
424 if control_len : |
|
425 # XXX: implement |
|
426 pass |
|
427 |
|
428 # recvmsg() |
|
429 cdef libc.ssize_t ret = platform.recvmsg(self.fd, &msg, flags) |
|
430 |
|
431 if ret < 0 : |
|
432 raise_errno('recvmsg') |
|
433 |
|
434 # name? |
|
435 cdef sockaddr name = None |
|
436 |
|
437 if msg.msg_name and msg.msg_namelen : |
|
438 name = build_sockaddr(<platform.sockaddr *> msg.msg_name, msg.msg_namelen) |
|
439 |
|
440 # iov? |
|
441 cdef object iov = None |
|
442 |
|
443 if ret : |
|
444 assert msg.msg_iov and msg.msg_iovlen |
|
445 |
|
446 # XXX: implement |
|
447 pass |
|
448 |
|
449 # control? |
|
450 cdef object control = None |
|
451 |
|
452 if msg.msg_control and msg.msg_controllen : |
|
453 # XXX: implement |
|
454 pass |
|
455 |
|
456 return name, iov, control, msg.msg_flags |
327 |
457 |
328 def shutdown (self, how) : |
458 def shutdown (self, how) : |
329 """ |
459 """ |
330 Shutdown part of a full-duplex connection. |
460 Shutdown part of a full-duplex connection. |
331 |
461 |