summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2007-06-12 21:39:21 +0000
committerDaniel Stenberg <daniel@haxx.se>2007-06-12 21:39:21 +0000
commit375cdf89adaf11a14a7717c39245ac997d0da699 (patch)
treecb3c366a4d93b382775111729c71c6bcaa5ac1f8
parentab7e7144efd9ff195a1f7acbb53afdacb09f22c1 (diff)
downloadcurl-375cdf89adaf11a14a7717c39245ac997d0da699.tar.gz
With lots of help from Rich Rauenza(?) in bug #1733119, we introduce a fairly
complicated work-around for 64bit HPUX compiles. We do the fix using inline static functions to make them follow the header file properly and thus get used fine in the test suite too etc.
-rw-r--r--configure.ac3
-rw-r--r--lib/setup_once.h82
2 files changed, 85 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 01b072625..a3cf7ecea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -204,6 +204,9 @@ dnl The install stuff has already been taken care of by the automake stuff
dnl AC_PROG_INSTALL
AC_PROG_MAKE_SET
+dnl check if there's a way to force code inline
+AC_C_INLINE
+
dnl **********************************************************************
dnl Make sure that our checks for headers windows.h winsock.h winsock2.h
dnl and ws2tcpip.h take precedence over any other further checks which
diff --git a/lib/setup_once.h b/lib/setup_once.h
index 585faed8d..08ead5eb2 100644
--- a/lib/setup_once.h
+++ b/lib/setup_once.h
@@ -365,5 +365,87 @@ typedef int sig_atomic_t;
#endif
+#if defined (__LP64__) && defined(__hpux) && !defined(_XOPEN_SOURCE_EXTENDED)
+#include <sys/socket.h>
+/* HP-UX has this oddity where it features a few functions that don't work
+ with socklen_t so we need to convert to ints
+
+ This is due to socklen_t being a 64bit int under 64bit ABI, but the
+ pre-xopen (default) interfaces require an int, which is 32bits.
+
+ Therefore, Anytime socklen_t is passed by pointer, the libc function
+ truncates the 64bit socklen_t value by treating it as a 32bit value.
+
+
+ Note that some socket calls are allowed to have a NULL pointer for
+ the socklen arg.
+*/
+
+inline static int Curl_hp_getsockname(int s, struct sockaddr *name,
+ socklen_t *namelen)
+{
+ int rc;
+ if(namelen) {
+ int len = *namelen;
+ rc = getsockname(s, name, &len);
+ *namelen = len;
+ }
+ else
+ rc = getsockname(s, name, 0);
+ return rc;
+}
+
+inline static int Curl_hp_getsockopt(int s, int level, int optname,
+ void *optval, socklen_t *optlen)
+{
+ int rc;
+ if(optlen) {
+ int len = *optlen;
+ rc = getsockopt(s, level, optname, optval, &len);
+ *optlen = len;
+ }
+ else
+ rc = getsockopt(s, level, optname, optval, 0);
+ return rc;
+}
+
+inline static int Curl_hp_accept(int sockfd, struct sockaddr *addr,
+ socklen_t *addrlen)
+{
+ int rc;
+ if(addrlen) {
+ int len = *addrlen;
+ rc = accept(sockfd, addr, &len);
+ *addrlen = len;
+ }
+ else
+ rc = accept(sockfd, addr, 0);
+ return rc;
+}
+
+
+inline static ssize_t Curl_hp_recvfrom(int s, void *buf, size_t len, int flags,
+ struct sockaddr *from,
+ socklen_t *fromlen)
+{
+ ssize_t rc;
+ if(fromlen) {
+ int fromlen32 = *fromlen;
+ rc = recvfrom(s, buf, len, flags, from, &fromlen32);
+ *fromlen = fromlen32;
+ }
+ else {
+ rc = recvfrom(s, buf, len, flags, from, 0);
+ }
+ return rc;
+}
+
+#define getsockname(a,b,c) Curl_hp_getsockname((a),(b),(c))
+#define getsockopt(a,b,c,d,e) Curl_hp_getsockopt((a),(b),(c),(d),(e))
+#define accept(a,b,c) Curl_hp_accept((a),(b),(c))
+#define recvfrom(a,b,c,d,e,f) Curl_hp_recvfrom((a),(b),(c),(d),(e),(f))
+
+#endif /* HPUX work-around */
+
#endif /* __SETUP_ONCE_H */