From be0d17e812053bddd99e1d330c429399f17aee44 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 11 Nov 2006 21:34:43 +0000
Subject: [PATCH] cleaned up Curl_write() and the sub functions it uses for
 various protocols. They all now return ssize_t to Curl_write().

Unfortunately, Curl_read() is in a sorrier state but it too would benefit from
a similar cleanup.
---
 lib/gtls.c     |  5 ++--
 lib/gtls.h     |  6 ++--
 lib/krb4.h     |  5 ++--
 lib/security.c |  7 +++++
 lib/sendf.c    | 78 +++++++++++++++++++++++++++-----------------------
 lib/sslgen.c   | 16 +++++------
 lib/sslgen.h   | 18 ++++++------
 lib/ssluse.c   | 10 +++----
 8 files changed, 79 insertions(+), 66 deletions(-)

diff --git a/lib/gtls.c b/lib/gtls.c
index 02680d02b..ee7612028 100644
--- a/lib/gtls.c
+++ b/lib/gtls.c
@@ -452,13 +452,12 @@ Curl_gtls_connect(struct connectdata *conn,
 
 
 /* return number of sent (non-SSL) bytes */
-int Curl_gtls_send(struct connectdata *conn,
+ssize_t Curl_gtls_send(struct connectdata *conn,
                    int sockindex,
                    void *mem,
                    size_t len)
 {
-  int rc;
-  rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
+  ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
 
   if(rc < 0 ) {
     if(rc == GNUTLS_E_AGAIN)
diff --git a/lib/gtls.h b/lib/gtls.h
index 2632b9686..4e7025c89 100644
--- a/lib/gtls.h
+++ b/lib/gtls.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -32,8 +32,8 @@ void Curl_gtls_close_all(struct SessionHandle *data);
 void Curl_gtls_close(struct connectdata *conn); /* close a SSL connection */
 
 /* return number of sent (non-SSL) bytes */
-int Curl_gtls_send(struct connectdata *conn, int sockindex,
-                   void *mem, size_t len);
+ssize_t Curl_gtls_send(struct connectdata *conn, int sockindex,
+                       void *mem, size_t len);
 ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
                        int num,                  /* socketindex */
                        char *buf,                /* store read data here */
diff --git a/lib/krb4.h b/lib/krb4.h
index c45c7c5f4..f46416e62 100644
--- a/lib/krb4.h
+++ b/lib/krb4.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -53,7 +53,8 @@ int Curl_sec_read_msg (struct connectdata *conn, char *, int);
 int Curl_sec_vfprintf(struct connectdata *, FILE *, const char *, va_list);
 int Curl_sec_fprintf2(struct connectdata *conn, FILE *f, const char *fmt, ...);
 int Curl_sec_vfprintf2(struct connectdata *conn, FILE *, const char *, va_list);
-int Curl_sec_write (struct connectdata *conn, int, char *, int);
+ssize_t Curl_sec_send(struct connectdata *conn, int, char *, int);
+int Curl_sec_write(struct connectdata *conn, int, char *, int);
 
 void Curl_sec_end (struct connectdata *);
 int Curl_sec_login (struct connectdata *);
diff --git a/lib/security.c b/lib/security.c
index 865ed23ca..4c9aed812 100644
--- a/lib/security.c
+++ b/lib/security.c
@@ -278,6 +278,13 @@ Curl_sec_write(struct connectdata *conn, int fd, char *buffer, int length)
   return tx;
 }
 
+ssize_t
+Curl_sec_send(struct connectdata *conn, int num, char *buffer, int length)
+{
+  curl_socket_t fd = conn->sock[num];
+  return (ssize_t)Curl_sec_write(conn, fd, buffer, length);
+}
+
 int
 Curl_sec_putc(struct connectdata *conn, int c, FILE *F)
 {
diff --git a/lib/sendf.c b/lib/sendf.c
index 958e852c7..ec2f53da0 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -53,7 +53,7 @@
 #ifdef HAVE_KRB4
 #include "krb4.h"
 #else
-#define Curl_sec_write(a,b,c,d) -1
+#define Curl_sec_send(a,b,c,d) -1
 #define Curl_sec_read(a,b,c,d) -1
 #endif
 
@@ -313,9 +313,40 @@ CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
   return res;
 }
 
+static ssize_t Curl_plain_send(struct connectdata *conn,
+                               int num,
+                               void *mem,
+                               size_t len)
+{
+  curl_socket_t sockfd = conn->sock[num];
+  ssize_t bytes_written = swrite(sockfd, mem, len);
+
+  if(-1 == bytes_written) {
+    int err = Curl_sockerrno();
+
+    if(
+#ifdef WSAEWOULDBLOCK
+      /* This is how Windows does it */
+      (WSAEWOULDBLOCK == err)
+#else
+      /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
+         due to its inability to send off data without blocking. We therefor
+         treat both error codes the same here */
+      (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
+#endif
+      )
+      /* this is just a case of EWOULDBLOCK */
+      bytes_written=0;
+    else
+      failf(conn->data, "Send failure: %s",
+            Curl_strerror(conn, err));
+  }
+  return bytes_written;
+}
+
 /*
- * Curl_write() is an internal write function that sends plain (binary) data
- * to the server. Works with plain sockets, SSL or kerberos.
+ * Curl_write() is an internal write function that sends data to the
+ * server. Works with plain sockets, SCP, SSL or kerberos.
  */
 CURLcode Curl_write(struct connectdata *conn,
                     curl_socket_t sockfd,
@@ -327,44 +358,19 @@ CURLcode Curl_write(struct connectdata *conn,
   CURLcode retcode;
   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
 
-  if (conn->ssl[num].use) {
+  if (conn->ssl[num].use)
     /* only TRUE if SSL enabled */
     bytes_written = Curl_ssl_send(conn, num, mem, len);
-  }
 #ifdef USE_LIBSSH2
-  else if (conn->protocol & PROT_SCP) {
+  else if (conn->protocol & PROT_SCP)
     bytes_written = Curl_scp_send(conn, num, mem, len);
-  }
 #endif /* !USE_LIBSSH2 */
-  else {
-    if(conn->sec_complete)
-      /* only TRUE if krb4 enabled */
-      bytes_written = Curl_sec_write(conn, sockfd, mem, len);
-    else
-      bytes_written = swrite(sockfd, mem, len);
+  else if(conn->sec_complete)
+    /* only TRUE if krb4 enabled */
+    bytes_written = Curl_sec_send(conn, num, mem, len);
+  else
+    bytes_written = Curl_plain_send(conn, num, mem, len);
 
-    if(-1 == bytes_written) {
-      int err = Curl_sockerrno();
-
-      if(
-#ifdef WSAEWOULDBLOCK
-        /* This is how Windows does it */
-        (WSAEWOULDBLOCK == err)
-#else
-        /* As pointed out by Christophe Demory on March 11 2003, errno
-           may be EWOULDBLOCK or on some systems EAGAIN when it returned
-           due to its inability to send off data without blocking. We
-           therefor treat both error codes the same here */
-        (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
-#endif
-        )
-        /* this is just a case of EWOULDBLOCK */
-        bytes_written=0;
-      else
-        failf(conn->data, "Send failure: %s",
-              Curl_strerror(conn, err));
-    }
-  }
   *written = bytes_written;
   retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
 
@@ -513,7 +519,7 @@ int Curl_read(struct connectdata *conn, /* connection data */
 #ifdef USE_LIBSSH2
   else if (conn->protocol & PROT_SCP) {
     nread = Curl_scp_recv(conn, num, conn->master_buffer, bytesfromsocket);
-    /* TODO: return CURLE_OK also for nread <= 0 
+    /* TODO: return CURLE_OK also for nread <= 0
              read failures and timeouts ? */
   }
 #endif /* !USE_LIBSSH2 */
diff --git a/lib/sslgen.c b/lib/sslgen.c
index 7d264b0de..1e0248448 100644
--- a/lib/sslgen.c
+++ b/lib/sslgen.c
@@ -455,10 +455,10 @@ struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data)
 }
 
 /* return number of sent (non-SSL) bytes */
-int Curl_ssl_send(struct connectdata *conn,
-                  int sockindex,
-                  void *mem,
-                  size_t len)
+ssize_t Curl_ssl_send(struct connectdata *conn,
+                      int sockindex,
+                      void *mem,
+                      size_t len)
 {
 #ifdef USE_SSLEAY
   return Curl_ossl_send(conn, sockindex, mem, len);
@@ -481,10 +481,10 @@ int Curl_ssl_send(struct connectdata *conn,
  * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
  * a regular CURLcode value.
  */
-int Curl_ssl_recv(struct connectdata *conn, /* connection data */
-                  int sockindex,            /* socketindex */
-                  char *mem,                /* store read data here */
-                  size_t len)               /* max amount to read */
+ssize_t Curl_ssl_recv(struct connectdata *conn, /* connection data */
+                      int sockindex,            /* socketindex */
+                      char *mem,                /* store read data here */
+                      size_t len)               /* max amount to read */
 {
 #ifdef USE_SSL
   ssize_t nread;
diff --git a/lib/sslgen.h b/lib/sslgen.h
index 03b01b86a..b910ac74b 100644
--- a/lib/sslgen.h
+++ b/lib/sslgen.h
@@ -32,7 +32,7 @@ void Curl_free_ssl_config(struct ssl_config_data* sslc);
 int Curl_ssl_init(void);
 void Curl_ssl_cleanup(void);
 CURLcode Curl_ssl_connect(struct connectdata *conn, int sockindex);
-CURLcode Curl_ssl_connect_nonblocking(struct connectdata *conn, 
+CURLcode Curl_ssl_connect_nonblocking(struct connectdata *conn,
                                       int sockindex,
                                       bool *done);
 void Curl_ssl_close(struct connectdata *conn);
@@ -42,14 +42,14 @@ void Curl_ssl_close_all(struct SessionHandle *data);
 CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine);
 /* Sets engine as default for all SSL operations */
 CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data);
-int Curl_ssl_send(struct connectdata *conn,
-                  int sockindex,
-                  void *mem,
-                  size_t len);
-int Curl_ssl_recv(struct connectdata *conn, /* connection data */
-                  int sockindex,            /* socketindex */
-                  char *mem,                /* store read data here */
-                  size_t len);              /* max amount to read */
+ssize_t Curl_ssl_send(struct connectdata *conn,
+                      int sockindex,
+                      void *mem,
+                      size_t len);
+ssize_t Curl_ssl_recv(struct connectdata *conn, /* connection data */
+                      int sockindex,            /* socketindex */
+                      char *mem,                /* store read data here */
+                      size_t len);              /* max amount to read */
 
 /* init the SSL session ID cache */
 CURLcode Curl_ssl_initsessions(struct SessionHandle *, long);
diff --git a/lib/ssluse.c b/lib/ssluse.c
index 7e9375d51..1c02edc23 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -1702,10 +1702,10 @@ Curl_ossl_connect(struct connectdata *conn,
 }
 
 /* return number of sent (non-SSL) bytes */
-int Curl_ossl_send(struct connectdata *conn,
-                   int sockindex,
-                   void *mem,
-                   size_t len)
+ssize_t Curl_ossl_send(struct connectdata *conn,
+                       int sockindex,
+                       void *mem,
+                       size_t len)
 {
   /* SSL_write() is said to return 'int' while write() and send() returns
      'size_t' */
@@ -1741,7 +1741,7 @@ int Curl_ossl_send(struct connectdata *conn,
     failf(conn->data, "SSL_write() return error %d\n", err);
     return -1;
   }
-  return rc; /* number of bytes */
+  return (ssize_t)rc; /* number of bytes */
 }
 
 /*