diff Modules/socketmodule.c @ 20808:464d213da888 2.1

partial backport of guido's 1.188. Add sendall() method, which loops until all data is written or an error occurs, and doesn't return a count. (This is my second patch from SF patch #474307, with small change to the docstring for send().) the 'partial' is because 1.188 also added a couple of Py_*_ALLOW_THREADS wrappers around SSL_read and SSL_write, and I want to check those separately. This is adding a new method to the socket object, which would normally be a bad thing to do in a bugfix release - however, in this case, it allows fixes for a nasty problem that would otherwise have a filthy filthy fix to Get It Right. Still to-do is to patch the std library modules to use sendall() where appropriate, rather than send().
author Anthony Baxter <anthonybaxter@gmail.com>
date Thu, 01 Nov 2001 14:14:26 +0000
parents 026bf0ab68a5
children 8d4b6642a604
line wrap: on
line diff
--- a/Modules/socketmodule.c	Thu Nov 01 14:05:52 2001 +0000
+++ b/Modules/socketmodule.c	Thu Nov 01 14:14:26 2001 +0000
@@ -59,6 +59,7 @@
 - s.recv(buflen [,flags]) --> string
 - s.recvfrom(buflen [,flags]) --> string, sockaddr
 - s.send(string [,flags]) --> nbytes
+- s.sendall(string [,flags]) # tries to send everything in a loop
 - s.sendto(string, [flags,] sockaddr) --> nbytes
 - s.setblocking(0 | 1) --> None
 - s.setsockopt(level, optname, value) --> None
@@ -1421,10 +1422,45 @@
 }
 
 static char send_doc[] =
-"send(data[, flags])\n\
+"send(data[, flags]) -> count\n\
 \n\
 Send a data string to the socket.  For the optional flags\n\
-argument, see the Unix manual.";
+argument, see the Unix manual.  Return the number of bytes\n\
+sent; this may be less than len(data) if the network is busy.";
+
+
+/* s.sendall(data [,flags]) method */
+
+static PyObject *
+PySocketSock_sendall(PySocketSockObject *s, PyObject *args)
+{
+	char *buf;
+	int len, n, flags = 0, total = 0;
+	if (!PyArg_ParseTuple(args, "s#|i:sendall", &buf, &len, &flags))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	do {
+		n = send(s->sock_fd, buf, len, flags);
+		if (n < 0)
+			break;
+		total += n;
+		buf += n;
+		len -= n;
+	} while (len > 0);
+	Py_END_ALLOW_THREADS
+	if (n < 0)
+		return PySocket_Err();
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char sendall_doc[] =
+"sendall(data[, flags])\n\
+\n\
+Send a data string to the socket.  For the optional flags\n\
+argument, see the Unix manual.  This calls send() repeatedly\n\
+until all data is sent.  If an error occurs, it's impossible\n\
+to tell how much data has been sent.";
 
 
 /* s.sendto(data, [flags,] sockaddr) method */
@@ -1524,6 +1560,8 @@
 			recvfrom_doc},
 	{"send",	(PyCFunction)PySocketSock_send, METH_VARARGS,
 			send_doc},
+	{"sendall",	(PyCFunction)PySocketSock_sendall, METH_VARARGS,
+			sendall_doc},
 	{"sendto",	(PyCFunction)PySocketSock_sendto, METH_VARARGS,
 			sendto_doc},
 	{"setblocking",	(PyCFunction)PySocketSock_setblocking, METH_VARARGS,