Fixes in struct and socket from merge reviews.
- Following Guido's comments, renamed * pack_to -> pack_into * recv_buf -> recv_into * recvfrom_buf -> recvfrom_into - Made fixes to _struct.c according to Neal Norwitz comments on the checkins list. - Converted some ints into the appropriate -- I hope -- ssize_t and size_t.
This commit is contained in:
parent
63f0db682e
commit
af2ae72cb2
|
@ -141,7 +141,7 @@ class _socketobject(object):
|
||||||
__doc__ = _realsocket.__doc__
|
__doc__ = _realsocket.__doc__
|
||||||
|
|
||||||
__slots__ = ["_sock",
|
__slots__ = ["_sock",
|
||||||
"recv", "recv_buf", "recvfrom_buf",
|
"recv", "recv_into", "recvfrom_into",
|
||||||
"send", "sendto", "recvfrom",
|
"send", "sendto", "recvfrom",
|
||||||
"__weakref__"]
|
"__weakref__"]
|
||||||
|
|
||||||
|
@ -151,10 +151,10 @@ class _socketobject(object):
|
||||||
self._sock = _sock
|
self._sock = _sock
|
||||||
self.send = self._sock.send
|
self.send = self._sock.send
|
||||||
self.recv = self._sock.recv
|
self.recv = self._sock.recv
|
||||||
self.recv_buf = self._sock.recv_buf
|
self.recv_into = self._sock.recv_into
|
||||||
self.sendto = self._sock.sendto
|
self.sendto = self._sock.sendto
|
||||||
self.recvfrom = self._sock.recvfrom
|
self.recvfrom = self._sock.recvfrom
|
||||||
self.recvfrom_buf = self._sock.recvfrom_buf
|
self.recvfrom_into = self._sock.recvfrom_into
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self._sock = _closedsocket()
|
self._sock = _closedsocket()
|
||||||
|
|
|
@ -62,7 +62,7 @@ def pack(fmt, *args):
|
||||||
o = _compile(fmt)
|
o = _compile(fmt)
|
||||||
return o.pack(*args)
|
return o.pack(*args)
|
||||||
|
|
||||||
def pack_to(fmt, buf, offset, *args):
|
def pack_into(fmt, buf, offset, *args):
|
||||||
"""
|
"""
|
||||||
Pack the values v2, v2, ... according to fmt, write
|
Pack the values v2, v2, ... according to fmt, write
|
||||||
the packed bytes into the writable buffer buf starting at offset.
|
the packed bytes into the writable buffer buf starting at offset.
|
||||||
|
@ -72,7 +72,7 @@ def pack_to(fmt, buf, offset, *args):
|
||||||
o = _cache[fmt]
|
o = _cache[fmt]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
o = _compile(fmt)
|
o = _compile(fmt)
|
||||||
return o.pack_to(buf, offset, *args)
|
return o.pack_into(buf, offset, *args)
|
||||||
|
|
||||||
def unpack(fmt, s):
|
def unpack(fmt, s):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -860,25 +860,25 @@ class BufferIOTest(SocketConnectedTest):
|
||||||
def __init__(self, methodName='runTest'):
|
def __init__(self, methodName='runTest'):
|
||||||
SocketConnectedTest.__init__(self, methodName=methodName)
|
SocketConnectedTest.__init__(self, methodName=methodName)
|
||||||
|
|
||||||
def testRecvBuf(self):
|
def testRecvInto(self):
|
||||||
buf = array.array('c', ' '*1024)
|
buf = array.array('c', ' '*1024)
|
||||||
nbytes = self.cli_conn.recv_buf(buf)
|
nbytes = self.cli_conn.recv_into(buf)
|
||||||
self.assertEqual(nbytes, len(MSG))
|
self.assertEqual(nbytes, len(MSG))
|
||||||
msg = buf.tostring()[:len(MSG)]
|
msg = buf.tostring()[:len(MSG)]
|
||||||
self.assertEqual(msg, MSG)
|
self.assertEqual(msg, MSG)
|
||||||
|
|
||||||
def _testRecvBuf(self):
|
def _testRecvInto(self):
|
||||||
buf = buffer(MSG)
|
buf = buffer(MSG)
|
||||||
self.serv_conn.send(buf)
|
self.serv_conn.send(buf)
|
||||||
|
|
||||||
def testRecvFromBuf(self):
|
def testRecvFromInto(self):
|
||||||
buf = array.array('c', ' '*1024)
|
buf = array.array('c', ' '*1024)
|
||||||
nbytes, addr = self.cli_conn.recvfrom_buf(buf)
|
nbytes, addr = self.cli_conn.recvfrom_into(buf)
|
||||||
self.assertEqual(nbytes, len(MSG))
|
self.assertEqual(nbytes, len(MSG))
|
||||||
msg = buf.tostring()[:len(MSG)]
|
msg = buf.tostring()[:len(MSG)]
|
||||||
self.assertEqual(msg, MSG)
|
self.assertEqual(msg, MSG)
|
||||||
|
|
||||||
def _testRecvFromBuf(self):
|
def _testRecvFromInto(self):
|
||||||
buf = buffer(MSG)
|
buf = buffer(MSG)
|
||||||
self.serv_conn.send(buf)
|
self.serv_conn.send(buf)
|
||||||
|
|
||||||
|
|
|
@ -529,50 +529,50 @@ def test_unpack_from():
|
||||||
for i in xrange(6, len(test_string) + 1):
|
for i in xrange(6, len(test_string) + 1):
|
||||||
simple_err(struct.unpack_from, fmt, data, i)
|
simple_err(struct.unpack_from, fmt, data, i)
|
||||||
|
|
||||||
def test_pack_to():
|
def test_pack_into():
|
||||||
test_string = 'Reykjavik rocks, eow!'
|
test_string = 'Reykjavik rocks, eow!'
|
||||||
writable_buf = array.array('c', ' '*100)
|
writable_buf = array.array('c', ' '*100)
|
||||||
fmt = '21s'
|
fmt = '21s'
|
||||||
s = struct.Struct(fmt)
|
s = struct.Struct(fmt)
|
||||||
|
|
||||||
# Test without offset
|
# Test without offset
|
||||||
s.pack_to(writable_buf, 0, test_string)
|
s.pack_into(writable_buf, 0, test_string)
|
||||||
from_buf = writable_buf.tostring()[:len(test_string)]
|
from_buf = writable_buf.tostring()[:len(test_string)]
|
||||||
assert from_buf == test_string
|
assert from_buf == test_string
|
||||||
|
|
||||||
# Test with offset.
|
# Test with offset.
|
||||||
s.pack_to(writable_buf, 10, test_string)
|
s.pack_into(writable_buf, 10, test_string)
|
||||||
from_buf = writable_buf.tostring()[:len(test_string)+10]
|
from_buf = writable_buf.tostring()[:len(test_string)+10]
|
||||||
assert from_buf == (test_string[:10] + test_string)
|
assert from_buf == (test_string[:10] + test_string)
|
||||||
|
|
||||||
# Go beyond boundaries.
|
# Go beyond boundaries.
|
||||||
small_buf = array.array('c', ' '*10)
|
small_buf = array.array('c', ' '*10)
|
||||||
assertRaises(struct.error, s.pack_to, small_buf, 0, test_string)
|
assertRaises(struct.error, s.pack_into, small_buf, 0, test_string)
|
||||||
assertRaises(struct.error, s.pack_to, small_buf, 2, test_string)
|
assertRaises(struct.error, s.pack_into, small_buf, 2, test_string)
|
||||||
|
|
||||||
def test_pack_to_fn():
|
def test_pack_into_fn():
|
||||||
test_string = 'Reykjavik rocks, eow!'
|
test_string = 'Reykjavik rocks, eow!'
|
||||||
writable_buf = array.array('c', ' '*100)
|
writable_buf = array.array('c', ' '*100)
|
||||||
fmt = '21s'
|
fmt = '21s'
|
||||||
pack_to = lambda *args: struct.pack_to(fmt, *args)
|
pack_into = lambda *args: struct.pack_into(fmt, *args)
|
||||||
|
|
||||||
# Test without offset
|
# Test without offset
|
||||||
pack_to(writable_buf, 0, test_string)
|
pack_into(writable_buf, 0, test_string)
|
||||||
from_buf = writable_buf.tostring()[:len(test_string)]
|
from_buf = writable_buf.tostring()[:len(test_string)]
|
||||||
assert from_buf == test_string
|
assert from_buf == test_string
|
||||||
|
|
||||||
# Test with offset.
|
# Test with offset.
|
||||||
pack_to(writable_buf, 10, test_string)
|
pack_into(writable_buf, 10, test_string)
|
||||||
from_buf = writable_buf.tostring()[:len(test_string)+10]
|
from_buf = writable_buf.tostring()[:len(test_string)+10]
|
||||||
assert from_buf == (test_string[:10] + test_string)
|
assert from_buf == (test_string[:10] + test_string)
|
||||||
|
|
||||||
# Go beyond boundaries.
|
# Go beyond boundaries.
|
||||||
small_buf = array.array('c', ' '*10)
|
small_buf = array.array('c', ' '*10)
|
||||||
assertRaises(struct.error, pack_to, small_buf, 0, test_string)
|
assertRaises(struct.error, pack_into, small_buf, 0, test_string)
|
||||||
assertRaises(struct.error, pack_to, small_buf, 2, test_string)
|
assertRaises(struct.error, pack_into, small_buf, 2, test_string)
|
||||||
|
|
||||||
|
|
||||||
# Test methods to pack and unpack from buffers rather than strings.
|
# Test methods to pack and unpack from buffers rather than strings.
|
||||||
test_unpack_from()
|
test_unpack_from()
|
||||||
test_pack_to()
|
test_pack_into()
|
||||||
test_pack_to_fn()
|
test_pack_into_fn()
|
||||||
|
|
|
@ -1572,8 +1572,7 @@ s_pack(PyObject *self, PyObject *args)
|
||||||
soself = (PyStructObject *)self;
|
soself = (PyStructObject *)self;
|
||||||
assert(PyStruct_Check(self));
|
assert(PyStruct_Check(self));
|
||||||
assert(soself->s_codes != NULL);
|
assert(soself->s_codes != NULL);
|
||||||
if (args == NULL || !PyTuple_Check(args) ||
|
if (PyTuple_GET_SIZE(args) != soself->s_len)
|
||||||
PyTuple_GET_SIZE(args) != soself->s_len)
|
|
||||||
{
|
{
|
||||||
PyErr_Format(StructError,
|
PyErr_Format(StructError,
|
||||||
"pack requires exactly %zd arguments", soself->s_len);
|
"pack requires exactly %zd arguments", soself->s_len);
|
||||||
|
@ -1594,16 +1593,16 @@ s_pack(PyObject *self, PyObject *args)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(s_pack_to__doc__,
|
PyDoc_STRVAR(s_pack_into__doc__,
|
||||||
"S.pack_to(buffer, offset, v1, v2, ...)\n\
|
"S.pack_into(buffer, offset, v1, v2, ...)\n\
|
||||||
\n\
|
\n\
|
||||||
Pack the values v2, v2, ... according to this Struct's format, write \n\
|
Pack the values v1, v2, ... according to this Struct's format, write \n\
|
||||||
the packed bytes into the writable buffer buf starting at offset. Note\n\
|
the packed bytes into the writable buffer buf starting at offset. Note\n\
|
||||||
that the offset is not an optional argument. See struct.__doc__ for \n\
|
that the offset is not an optional argument. See struct.__doc__ for \n\
|
||||||
more on format strings.");
|
more on format strings.");
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
s_pack_to(PyObject *self, PyObject *args)
|
s_pack_into(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyStructObject *soself;
|
PyStructObject *soself;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
@ -1613,11 +1612,10 @@ s_pack_to(PyObject *self, PyObject *args)
|
||||||
soself = (PyStructObject *)self;
|
soself = (PyStructObject *)self;
|
||||||
assert(PyStruct_Check(self));
|
assert(PyStruct_Check(self));
|
||||||
assert(soself->s_codes != NULL);
|
assert(soself->s_codes != NULL);
|
||||||
if (args == NULL || !PyTuple_Check(args) ||
|
if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
|
||||||
PyTuple_GET_SIZE(args) != (soself->s_len + 2))
|
|
||||||
{
|
{
|
||||||
PyErr_Format(StructError,
|
PyErr_Format(StructError,
|
||||||
"pack_to requires exactly %zd arguments",
|
"pack_into requires exactly %zd arguments",
|
||||||
(soself->s_len + 2));
|
(soself->s_len + 2));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1630,7 +1628,7 @@ s_pack_to(PyObject *self, PyObject *args)
|
||||||
assert( buffer_len >= 0 );
|
assert( buffer_len >= 0 );
|
||||||
|
|
||||||
/* Extract the offset from the first argument */
|
/* Extract the offset from the first argument */
|
||||||
offset = PyInt_AsLong(PyTuple_GET_ITEM(args, 1));
|
offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
|
||||||
|
|
||||||
/* Support negative offsets. */
|
/* Support negative offsets. */
|
||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
|
@ -1639,7 +1637,7 @@ s_pack_to(PyObject *self, PyObject *args)
|
||||||
/* Check boundaries */
|
/* Check boundaries */
|
||||||
if (offset < 0 || (buffer_len - offset) < soself->s_size) {
|
if (offset < 0 || (buffer_len - offset) < soself->s_size) {
|
||||||
PyErr_Format(StructError,
|
PyErr_Format(StructError,
|
||||||
"pack_to requires a buffer of at least %zd bytes",
|
"pack_into requires a buffer of at least %zd bytes",
|
||||||
soself->s_size);
|
soself->s_size);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1668,10 +1666,10 @@ s_get_size(PyStructObject *self, void *unused)
|
||||||
/* List of functions */
|
/* List of functions */
|
||||||
|
|
||||||
static struct PyMethodDef s_methods[] = {
|
static struct PyMethodDef s_methods[] = {
|
||||||
{"pack", (PyCFunction)s_pack, METH_VARARGS, s_pack__doc__},
|
{"pack", s_pack, METH_VARARGS, s_pack__doc__},
|
||||||
{"pack_to", (PyCFunction)s_pack_to, METH_VARARGS, s_pack_to__doc__},
|
{"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
|
||||||
{"unpack", (PyCFunction)s_unpack, METH_O, s_unpack__doc__},
|
{"unpack", s_unpack, METH_O, s_unpack__doc__},
|
||||||
{"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS, s_unpack_from__doc__},
|
{"unpack_from", s_unpack_from, METH_KEYWORDS, s_unpack_from__doc__},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -104,9 +104,9 @@ gettimeout() -- return timeout or None\n\
|
||||||
listen(n) -- start listening for incoming connections\n\
|
listen(n) -- start listening for incoming connections\n\
|
||||||
makefile([mode, [bufsize]]) -- return a file object for the socket [*]\n\
|
makefile([mode, [bufsize]]) -- return a file object for the socket [*]\n\
|
||||||
recv(buflen[, flags]) -- receive data\n\
|
recv(buflen[, flags]) -- receive data\n\
|
||||||
recv_buf(buffer[, nbytes[, flags]]) -- receive data (into a buffer)\n\
|
recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)\n\
|
||||||
recvfrom(buflen[, flags]) -- receive data and sender\'s address\n\
|
recvfrom(buflen[, flags]) -- receive data and sender\'s address\n\
|
||||||
recvfrom_buf(buffer[, nbytes, [, flags])\n\
|
recvfrom_into(buffer[, nbytes, [, flags])\n\
|
||||||
-- receive data and sender\'s address (into a buffer)\n\
|
-- receive data and sender\'s address (into a buffer)\n\
|
||||||
sendall(data[, flags]) -- send all data\n\
|
sendall(data[, flags]) -- send all data\n\
|
||||||
send(data[, flags]) -- send data, may not send all of it\n\
|
send(data[, flags]) -- send data, may not send all of it\n\
|
||||||
|
@ -2139,17 +2139,18 @@ The mode and buffersize arguments are as for the built-in open() function.");
|
||||||
#endif /* NO_DUP */
|
#endif /* NO_DUP */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the guts of the recv() and recv_buf() methods, which reads into a
|
* This is the guts of the recv() and recv_into() methods, which reads into a
|
||||||
* char buffer. If you have any inc/def ref to do to the objects that contain
|
* char buffer. If you have any inc/def ref to do to the objects that contain
|
||||||
* the buffer, do it in the caller. This function returns the number of bytes
|
* the buffer, do it in the caller. This function returns the number of bytes
|
||||||
* succesfully read. If there was an error, it returns -1. Note that it is
|
* succesfully read. If there was an error, it returns -1. Note that it is
|
||||||
* also possible that we return a number of bytes smaller than the request
|
* also possible that we return a number of bytes smaller than the request
|
||||||
* bytes.
|
* bytes.
|
||||||
*/
|
*/
|
||||||
static int
|
static ssize_t
|
||||||
sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags)
|
sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags)
|
||||||
{
|
{
|
||||||
int timeout, outlen = 0;
|
ssize_t outlen = 0;
|
||||||
|
int timeout;
|
||||||
#ifdef __VMS
|
#ifdef __VMS
|
||||||
int remaining, nread;
|
int remaining, nread;
|
||||||
char *read_buf;
|
char *read_buf;
|
||||||
|
@ -2225,7 +2226,8 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
sock_recv(PySocketSockObject *s, PyObject *args)
|
sock_recv(PySocketSockObject *s, PyObject *args)
|
||||||
{
|
{
|
||||||
int recvlen, flags = 0, outlen;
|
int recvlen, flags = 0;
|
||||||
|
ssize_t outlen;
|
||||||
PyObject *buf;
|
PyObject *buf;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "i|i:recv", &recvlen, &flags))
|
if (!PyArg_ParseTuple(args, "i|i:recv", &recvlen, &flags))
|
||||||
|
@ -2243,7 +2245,7 @@ sock_recv(PySocketSockObject *s, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Call the guts */
|
/* Call the guts */
|
||||||
outlen = sock_recv_guts(s, PyString_AsString(buf), recvlen, flags);
|
outlen = sock_recv_guts(s, PyString_AS_STRING(buf), recvlen, flags);
|
||||||
if (outlen < 0) {
|
if (outlen < 0) {
|
||||||
/* An error occured, release the string and return an
|
/* An error occured, release the string and return an
|
||||||
error. */
|
error. */
|
||||||
|
@ -2270,19 +2272,20 @@ at least one byte is available or until the remote end is closed. When\n\
|
||||||
the remote end is closed and all data is read, return the empty string.");
|
the remote end is closed and all data is read, return the empty string.");
|
||||||
|
|
||||||
|
|
||||||
/* s.recv_buf(buffer, [nbytes [,flags]]) method */
|
/* s.recv_into(buffer, [nbytes [,flags]]) method */
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
sock_recv_buf(PySocketSockObject *s, PyObject *args, PyObject *kwds)
|
sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
|
static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
|
||||||
|
|
||||||
int recvlen = 0, flags = 0, readlen;
|
int recvlen = 0, flags = 0;
|
||||||
|
ssize_t readlen;
|
||||||
char *buf;
|
char *buf;
|
||||||
int buflen;
|
int buflen;
|
||||||
|
|
||||||
/* Get the buffer's memory */
|
/* Get the buffer's memory */
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#|ii:recv", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recv", kwlist,
|
||||||
&buf, &buflen, &recvlen, &flags))
|
&buf, &buflen, &recvlen, &flags))
|
||||||
return NULL;
|
return NULL;
|
||||||
assert(buf != 0 && buflen > 0);
|
assert(buf != 0 && buflen > 0);
|
||||||
|
@ -2313,11 +2316,11 @@ sock_recv_buf(PySocketSockObject *s, PyObject *args, PyObject *kwds)
|
||||||
|
|
||||||
/* Return the number of bytes read. Note that we do not do anything
|
/* Return the number of bytes read. Note that we do not do anything
|
||||||
special here in the case that readlen < recvlen. */
|
special here in the case that readlen < recvlen. */
|
||||||
return PyInt_FromLong(readlen);
|
return PyInt_FromSsize_t(readlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(recv_buf_doc,
|
PyDoc_STRVAR(recv_into_doc,
|
||||||
"recv_buf(buffer, [nbytes[, flags]]) -> nbytes_read\n\
|
"recv_into(buffer, [nbytes[, flags]]) -> nbytes_read\n\
|
||||||
\n\
|
\n\
|
||||||
A version of recv() that stores its data into a buffer rather than creating \n\
|
A version of recv() that stores its data into a buffer rather than creating \n\
|
||||||
a new string. Receive up to buffersize bytes from the socket. If buffersize \n\
|
a new string. Receive up to buffersize bytes from the socket. If buffersize \n\
|
||||||
|
@ -2327,7 +2330,7 @@ See recv() for documentation about the flags.");
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the guts of the recv() and recv_buf() methods, which reads into a
|
* This is the guts of the recv() and recv_into() methods, which reads into a
|
||||||
* char buffer. If you have any inc/def ref to do to the objects that contain
|
* char buffer. If you have any inc/def ref to do to the objects that contain
|
||||||
* the buffer, do it in the caller. This function returns the number of bytes
|
* the buffer, do it in the caller. This function returns the number of bytes
|
||||||
* succesfully read. If there was an error, it returns -1. Note that it is
|
* succesfully read. If there was an error, it returns -1. Note that it is
|
||||||
|
@ -2337,12 +2340,13 @@ See recv() for documentation about the flags.");
|
||||||
* 'addr' is a return value for the address object. Note that you must decref
|
* 'addr' is a return value for the address object. Note that you must decref
|
||||||
* it yourself.
|
* it yourself.
|
||||||
*/
|
*/
|
||||||
static int
|
static ssize_t
|
||||||
sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, int len, int flags,
|
sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, int len, int flags,
|
||||||
PyObject** addr)
|
PyObject** addr)
|
||||||
{
|
{
|
||||||
sock_addr_t addrbuf;
|
sock_addr_t addrbuf;
|
||||||
int n = 0, timeout;
|
int timeout;
|
||||||
|
ssize_t n = 0;
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
|
|
||||||
*addr = NULL;
|
*addr = NULL;
|
||||||
|
@ -2398,7 +2402,8 @@ sock_recvfrom(PySocketSockObject *s, PyObject *args)
|
||||||
PyObject *buf = NULL;
|
PyObject *buf = NULL;
|
||||||
PyObject *addr = NULL;
|
PyObject *addr = NULL;
|
||||||
PyObject *ret = NULL;
|
PyObject *ret = NULL;
|
||||||
int recvlen, outlen, flags = 0;
|
int recvlen, flags = 0;
|
||||||
|
ssize_t outlen;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "i|i:recvfrom", &recvlen, &flags))
|
if (!PyArg_ParseTuple(args, "i|i:recvfrom", &recvlen, &flags))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2435,21 +2440,22 @@ PyDoc_STRVAR(recvfrom_doc,
|
||||||
Like recv(buffersize, flags) but also return the sender's address info.");
|
Like recv(buffersize, flags) but also return the sender's address info.");
|
||||||
|
|
||||||
|
|
||||||
/* s.recvfrom_buf(buffer[, nbytes [,flags]]) method */
|
/* s.recvfrom_into(buffer[, nbytes [,flags]]) method */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
sock_recvfrom_buf(PySocketSockObject *s, PyObject *args, PyObject* kwds)
|
sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds)
|
||||||
{
|
{
|
||||||
static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
|
static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
|
||||||
|
|
||||||
int recvlen = 0, flags = 0, readlen;
|
int recvlen = 0, flags = 0;
|
||||||
|
ssize_t readlen;
|
||||||
char *buf;
|
char *buf;
|
||||||
int buflen;
|
int buflen;
|
||||||
|
|
||||||
PyObject *addr = NULL;
|
PyObject *addr = NULL;
|
||||||
PyObject *ret = NULL;
|
PyObject *ret = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#|ii:recvfrom", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recvfrom", kwlist,
|
||||||
&buf, &buflen, &recvlen, &flags))
|
&buf, &buflen, &recvlen, &flags))
|
||||||
return NULL;
|
return NULL;
|
||||||
assert(buf != 0 && buflen > 0);
|
assert(buf != 0 && buflen > 0);
|
||||||
|
@ -2467,22 +2473,19 @@ sock_recvfrom_buf(PySocketSockObject *s, PyObject *args, PyObject* kwds)
|
||||||
readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr);
|
readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr);
|
||||||
if (readlen < 0) {
|
if (readlen < 0) {
|
||||||
/* Return an error */
|
/* Return an error */
|
||||||
goto finally;
|
Py_XDECREF(addr);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the number of bytes read and the address. Note that we do
|
/* Return the number of bytes read and the address. Note that we do
|
||||||
not do anything special here in the case that readlen < recvlen. */
|
not do anything special here in the case that readlen < recvlen. */
|
||||||
ret = Py_BuildValue("lO", readlen, addr);
|
return Py_BuildValue("lO", readlen, addr);
|
||||||
|
|
||||||
finally:
|
|
||||||
Py_XDECREF(addr);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(recvfrom_buf_doc,
|
PyDoc_STRVAR(recvfrom_into_doc,
|
||||||
"recvfrom_buf(buffer[, nbytes[, flags]]) -> (nbytes, address info)\n\
|
"recvfrom_into(buffer[, nbytes[, flags]]) -> (nbytes, address info)\n\
|
||||||
\n\
|
\n\
|
||||||
Like recv_buf(buffer[, nbytes[, flags]]) but also return the sender's address info.");
|
Like recv_into(buffer[, nbytes[, flags]]) but also return the sender's address info.");
|
||||||
|
|
||||||
|
|
||||||
/* s.send(data [,flags]) method */
|
/* s.send(data [,flags]) method */
|
||||||
|
@ -2711,12 +2714,12 @@ static PyMethodDef sock_methods[] = {
|
||||||
#endif
|
#endif
|
||||||
{"recv", (PyCFunction)sock_recv, METH_VARARGS,
|
{"recv", (PyCFunction)sock_recv, METH_VARARGS,
|
||||||
recv_doc},
|
recv_doc},
|
||||||
{"recv_buf", (PyCFunction)sock_recv_buf, METH_VARARGS | METH_KEYWORDS,
|
{"recv_into", (PyCFunction)sock_recv_into, METH_VARARGS | METH_KEYWORDS,
|
||||||
recv_buf_doc},
|
recv_into_doc},
|
||||||
{"recvfrom", (PyCFunction)sock_recvfrom, METH_VARARGS,
|
{"recvfrom", (PyCFunction)sock_recvfrom, METH_VARARGS,
|
||||||
recvfrom_doc},
|
recvfrom_doc},
|
||||||
{"recvfrom_buf", (PyCFunction)sock_recvfrom_buf, METH_VARARGS | METH_KEYWORDS,
|
{"recvfrom_into", (PyCFunction)sock_recvfrom_into, METH_VARARGS | METH_KEYWORDS,
|
||||||
recvfrom_buf_doc},
|
recvfrom_into_doc},
|
||||||
{"send", (PyCFunction)sock_send, METH_VARARGS,
|
{"send", (PyCFunction)sock_send, METH_VARARGS,
|
||||||
send_doc},
|
send_doc},
|
||||||
{"sendall", (PyCFunction)sock_sendall, METH_VARARGS,
|
{"sendall", (PyCFunction)sock_sendall, METH_VARARGS,
|
||||||
|
|
Loading…
Reference in New Issue