cURL / Mailing Lists / curl-library / Single Mail

curl-library

[PATCH 1/2] expose Curl_nonblock as curlx_nonblock

From: Eric Wong <normalperson_at_yhbt.net>
Date: Mon, 29 Jun 2009 02:29:31 -0700

This is to eventually allow curl(1) to use curlx_nonblock
instead of its currently non-portable placeholder.

Based on a previous discussion on the tool list:
<alpine.DEB.2.00.0906152308580.4825_at_yvahk2.pbagnpgbe.fr>

Daniel Stenberg <daniel_at_haxx.se> wrote:
> On Sun, 7 Jun 2009, Eric Wong wrote:
>>> Yeah, if that would be accessible. We could poke the libcurl code to
>>> at least provide a curlx_ version so that we don't have to re-invent
>>> the code for the curl tool, and then we'd get the non-blocking
>>> function fairly portable.
>>
>> Yup, that'd be nice. Should we just replace the old one since with the
>> curlx_nonblock() name since the old one was never public anyways?
>
> Yes, that's exactly what I suggest. To make that as nice as possible, the
> Curl_nonblock() function would need to be moved out from lib/connect.c
> into a separate file so that it can be used independently of all the
> other functions in the connect.c file.

---
 lib/Makefile.inc |    4 +-
 lib/connect.c    |   55 +----------------------------
 lib/connect.h    |    3 +-
 lib/curlx.h      |    3 ++
 lib/ftp.c        |    2 +-
 lib/nonblock.c   |  102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/nonblock.h   |   31 ++++++++++++++++
 lib/socks.c      |   14 ++++----
 8 files changed, 148 insertions(+), 66 deletions(-)
 create mode 100644 lib/nonblock.c
 create mode 100644 lib/nonblock.h
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index 412f5de..99a6a72 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -10,7 +10,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c	\
   hostares.c hostasyn.c hostip4.c hostip6.c hostsyn.c hostthre.c	\
   inet_ntop.c parsedate.c select.c gtls.c sslgen.c tftp.c splay.c	\
   strdup.c socks.c ssh.c nss.c qssl.c rawstr.c curl_addrinfo.c          \
-  socks_gssapi.c socks_sspi.c curl_sspi.c slist.c
+  socks_gssapi.c socks_sspi.c curl_sspi.c slist.c nonblock.c
 
 HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h	\
   progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h	\
@@ -21,4 +21,4 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h	\
   strtoofft.h strerror.h inet_ntop.h curlx.h curl_memory.h setup.h	\
   transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h gtls.h	\
   tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h nssg.h	\
-  curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h slist.h
+  curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h slist.h nonblock.h
diff --git a/lib/connect.c b/lib/connect.c
index 521c91c..2cec74b 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -177,59 +177,6 @@ long Curl_timeleft(struct connectdata *conn,
   return timeout_ms;
 }
 
-
-/*
- * Curl_nonblock() set the given socket to either blocking or non-blocking
- * mode based on the 'nonblock' boolean argument. This function is highly
- * portable.
- */
-int Curl_nonblock(curl_socket_t sockfd,    /* operate on this */
-                  int nonblock   /* TRUE or FALSE */)
-{
-#if defined(USE_BLOCKING_SOCKETS)
-
-  return 0; /* returns success */
-
-#elif defined(HAVE_FCNTL_O_NONBLOCK)
-
-  /* most recent unix versions */
-  int flags;
-  flags = fcntl(sockfd, F_GETFL, 0);
-  if(FALSE != nonblock)
-    return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
-  else
-    return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
-
-#elif defined(HAVE_IOCTL_FIONBIO)
-
-  /* older unix versions */
-  int flags;
-  flags = nonblock;
-  return ioctl(sockfd, FIONBIO, &flags);
-
-#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
-
-  /* Windows */
-  unsigned long flags;
-  flags = nonblock;
-  return ioctlsocket(sockfd, FIONBIO, &flags);
-
-#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
-
-  /* Amiga */
-  return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
-
-#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
-
-  /* BeOS */
-  long b = nonblock ? 1 : 0;
-  return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
-
-#else
-#  error "no non-blocking method was found/used/set"
-#endif
-}
-
 /*
  * waitconnect() waits for a TCP connect on the given socket for the specified
  * number if milliseconds. It returns:
@@ -846,7 +793,7 @@ singleipconnect(struct connectdata *conn,
   }
 
   /* set socket non-blocking */
-  Curl_nonblock(sockfd, TRUE);
+  curlx_nonblock(sockfd, TRUE);
 
   /* Connect TCP sockets, bind UDP */
   if(conn->socktype == SOCK_STREAM)
diff --git a/lib/connect.h b/lib/connect.h
index 12ebe13..c82de24 100644
--- a/lib/connect.h
+++ b/lib/connect.h
@@ -23,8 +23,7 @@
  * $Id: connect.h,v 1.27 2009-05-07 20:00:44 bagder Exp $
  ***************************************************************************/
 
-int Curl_nonblock(curl_socket_t sockfd,    /* operate on this */
-                  int nonblock   /* TRUE or FALSE */);
+#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
 
 CURLcode Curl_is_connected(struct connectdata *conn,
                            int sockindex,
diff --git a/lib/curlx.h b/lib/curlx.h
index 30cbfdb..26f0413 100644
--- a/lib/curlx.h
+++ b/lib/curlx.h
@@ -53,6 +53,9 @@
   curlx_tvdiff_secs()
 */
 
+#include "nonblock.h"
+/* "nonblock.h" provides curlx_nonblock() */
+
 /* Now setup curlx_ * names for the functions that are to become curlx_ and
    be removed from a future libcurl official API:
    curlx_getenv
diff --git a/lib/ftp.c b/lib/ftp.c
index dabfcab..cb65249 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -349,7 +349,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
       infof(data, "Connection accepted from server\n");
 
       conn->sock[SECONDARYSOCKET] = s;
-      Curl_nonblock(s, TRUE); /* enable non-blocking */
+      curlx_nonblock(s, TRUE); /* enable non-blocking */
     }
     break;
   }
diff --git a/lib/nonblock.c b/lib/nonblock.c
new file mode 100644
index 0000000..d5a32a9
--- /dev/null
+++ b/lib/nonblock.c
@@ -0,0 +1,102 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel_at_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
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id$
+ ***************************************************************************/
+
+#include "setup.h"
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE))
+#include <sys/filio.h>
+#endif
+#ifdef VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#include "nonblock.h"
+
+/*
+ * curlx_nonblock() set the given socket to either blocking or non-blocking
+ * mode based on the 'nonblock' boolean argument. This function is highly
+ * portable.
+ */
+int curlx_nonblock(curl_socket_t sockfd,    /* operate on this */
+                   int nonblock   /* TRUE or FALSE */)
+{
+#if defined(USE_BLOCKING_SOCKETS)
+
+  return 0; /* returns success */
+
+#elif defined(HAVE_FCNTL_O_NONBLOCK)
+
+  /* most recent unix versions */
+  int flags;
+  flags = fcntl(sockfd, F_GETFL, 0);
+  if(FALSE != nonblock)
+    return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+  else
+    return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
+
+#elif defined(HAVE_IOCTL_FIONBIO)
+
+  /* older unix versions */
+  int flags;
+  flags = nonblock;
+  return ioctl(sockfd, FIONBIO, &flags);
+
+#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
+
+  /* Windows */
+  unsigned long flags;
+  flags = nonblock;
+  return ioctlsocket(sockfd, FIONBIO, &flags);
+
+#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
+
+  /* Amiga */
+  return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
+
+#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
+
+  /* BeOS */
+  long b = nonblock ? 1 : 0;
+  return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
+
+#else
+#  error "no non-blocking method was found/used/set"
+#endif
+}
diff --git a/lib/nonblock.h b/lib/nonblock.h
new file mode 100644
index 0000000..321588a
--- /dev/null
+++ b/lib/nonblock.h
@@ -0,0 +1,31 @@
+#ifndef __NONBLOCK_H
+#define __NONBLOCK_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel_at_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
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id$
+ ***************************************************************************/
+
+#include <curl/curl.h> /* for curl_socket_t */
+
+int curlx_nonblock(curl_socket_t sockfd,    /* operate on this */
+                   int nonblock   /* TRUE or FALSE */);
+
+#endif
diff --git a/lib/socks.c b/lib/socks.c
index ce6ed80..7754b18 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -144,7 +144,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
     return CURLE_OPERATION_TIMEDOUT;
   }
 
-  Curl_nonblock(sock, FALSE);
+  curlx_nonblock(sock, FALSE);
 
   /*
    * Compose socks4 request
@@ -344,7 +344,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
     }
   }
 
-  Curl_nonblock(sock, TRUE);
+  curlx_nonblock(sock, TRUE);
 
   return CURLE_OK; /* Proxy was successful! */
 }
@@ -406,7 +406,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
     return CURLE_OPERATION_TIMEDOUT;
   }
 
-  Curl_nonblock(sock, TRUE);
+  curlx_nonblock(sock, TRUE);
 
   /* wait until socket gets connected */
   result = Curl_socket_ready(CURL_SOCKET_BAD, sock, (int)timeout);
@@ -437,7 +437,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
   socksreq[3] = 2; /* username/password */
 #endif
 
-  Curl_nonblock(sock, FALSE);
+  curlx_nonblock(sock, FALSE);
 
   code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
                           &written);
@@ -446,7 +446,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
     return CURLE_COULDNT_CONNECT;
   }
 
-  Curl_nonblock(sock, TRUE);
+  curlx_nonblock(sock, TRUE);
 
   result = Curl_socket_ready(sock, CURL_SOCKET_BAD, (int)timeout);
 
@@ -464,7 +464,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
     return CURLE_RECV_ERROR;
   }
 
-  Curl_nonblock(sock, FALSE);
+  curlx_nonblock(sock, FALSE);
 
   result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread,
                             timeout);
@@ -719,7 +719,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
   }
 #endif
 
-  Curl_nonblock(sock, TRUE);
+  curlx_nonblock(sock, TRUE);
   return CURLE_OK; /* Proxy was successful! */
 }
 
-- 
Eric Wong
Received on 2009-06-29