1 #ifndef __SETUP_ONCE_H
2 #define __SETUP_ONCE_H
3 /***************************************************************************
4  *                                  _   _ ____  _
5  *  Project                     ___| | | |  _ \| |
6  *                             / __| | | | |_) | |
7  *                            | (__| |_| |  _ <| |___
8  *                             \___|\___/|_| \_\_____|
9  *
10  * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
11  *
12  * This software is licensed as described in the file COPYING, which
13  * you should have received as part of this distribution. The terms
14  * are also available at http://curl.haxx.se/docs/copyright.html.
15  *
16  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
17  * copies of the Software, and permit persons to whom the Software is
18  * furnished to do so, under the terms of the COPYING file.
19  *
20  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21  * KIND, either express or implied.
22  *
23  * $Id: setup_once.h,v 1.35 2008-08-27 00:25:03 yangtse Exp $
24  ***************************************************************************/
25 
26 
27 /********************************************************************
28  *                              NOTICE                              *
29  *                             ========                             *
30  *                                                                  *
31  *  Content of header files lib/setup_once.h and ares/setup_once.h  *
32  *  must be kept in sync. Modify the other one if you change this.  *
33  *                                                                  *
34  ********************************************************************/
35 
36 
37 /*
38  * Inclusion of common header files.
39  */
40 
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <stdarg.h>
45 #include <ctype.h>
46 #include <errno.h>
47 
48 #ifdef HAVE_SYS_TYPES_H
49 #include <sys/types.h>
50 #endif
51 
52 #ifdef HAVE_SYS_STAT_H
53 #include <sys/stat.h>
54 #endif
55 
56 #ifdef HAVE_SYS_TIME_H
57 #include <sys/time.h>
58 #ifdef TIME_WITH_SYS_TIME
59 #include <time.h>
60 #endif
61 #else
62 #ifdef HAVE_TIME_H
63 #include <time.h>
64 #endif
65 #endif
66 
67 #ifdef WIN32
68 #include <io.h>
69 #include <fcntl.h>
70 #endif
71 
72 #ifdef HAVE_STDBOOL_H
73 #include <stdbool.h>
74 #endif
75 
76 
77 /*
78  * Definition of timeval struct for platforms that don't have it.
79  */
80 
81 #ifndef HAVE_STRUCT_TIMEVAL
82 struct timeval {
83  long tv_sec;
84  long tv_usec;
85 };
86 #endif
87 
88 
89 /*
90  * If we have the MSG_NOSIGNAL define, make sure we use
91  * it as the fourth argument of function send()
92  */
93 
94 #ifdef HAVE_MSG_NOSIGNAL
95 #define SEND_4TH_ARG MSG_NOSIGNAL
96 #else
97 #define SEND_4TH_ARG 0
98 #endif
99 
100 
101 /*
102  * Windows build targets have socklen_t definition in
103  * ws2tcpip.h but some versions of ws2tcpip.h do not
104  * have the definition. It seems that when the socklen_t
105  * definition is missing from ws2tcpip.h the definition
106  * for INET_ADDRSTRLEN is also missing, and that when one
107  * definition is present the other one also is available.
108  */
109 
110 #if defined(WIN32) && !defined(HAVE_CONFIG_H)
111 #  if ( defined(_MSC_VER) && !defined(INET_ADDRSTRLEN) ) || \
112       (!defined(_MSC_VER) && !defined(HAVE_WS2TCPIP_H) )
113 #    define socklen_t int
114 #  endif
115 #endif
116 
117 
118 #if defined(__minix)
119 /* Minix doesn't support recv on TCP sockets */
120 #define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \
121                                    (RECV_TYPE_ARG2)(y), \
122                                    (RECV_TYPE_ARG3)(z))
123 
124 #elif defined(HAVE_RECV)
125 /*
126  * The definitions for the return type and arguments types
127  * of functions recv() and send() belong and come from the
128  * configuration file. Do not define them in any other place.
129  *
130  * HAVE_RECV is defined if you have a function named recv()
131  * which is used to read incoming data from sockets. If your
132  * function has another name then don't define HAVE_RECV.
133  *
134  * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2,
135  * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also
136  * be defined.
137  *
138  * HAVE_SEND is defined if you have a function named send()
139  * which is used to write outgoing data on a connected socket.
140  * If yours has another name then don't define HAVE_SEND.
141  *
142  * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2,
143  * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and
144  * SEND_TYPE_RETV must also be defined.
145  */
146 
147 #if !defined(RECV_TYPE_ARG1) || \
148     !defined(RECV_TYPE_ARG2) || \
149     !defined(RECV_TYPE_ARG3) || \
150     !defined(RECV_TYPE_ARG4) || \
151     !defined(RECV_TYPE_RETV)
152   /* */
153   Error Missing_definition_of_return_and_arguments_types_of_recv
154   /* */
155 #else
156 #define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
157                                    (RECV_TYPE_ARG2)(y), \
158                                    (RECV_TYPE_ARG3)(z), \
159                                    (RECV_TYPE_ARG4)(0))
160 #endif
161 #else /* HAVE_RECV */
162 #ifndef sread
163   /* */
164   Error Missing_definition_of_macro_sread
165   /* */
166 #endif
167 #endif /* HAVE_RECV */
168 
169 
170 #if defined(__minix)
171 /* Minix doesn't support send on TCP sockets */
172 #define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \
173                                     (SEND_TYPE_ARG2)(y), \
174                                     (SEND_TYPE_ARG3)(z))
175 
176 #elif defined(HAVE_SEND)
177 #if !defined(SEND_TYPE_ARG1) || \
178     !defined(SEND_QUAL_ARG2) || \
179     !defined(SEND_TYPE_ARG2) || \
180     !defined(SEND_TYPE_ARG3) || \
181     !defined(SEND_TYPE_ARG4) || \
182     !defined(SEND_TYPE_RETV)
183   /* */
184   Error Missing_definition_of_return_and_arguments_types_of_send
185   /* */
186 #else
187 #define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
188                                     (SEND_TYPE_ARG2)(y), \
189                                     (SEND_TYPE_ARG3)(z), \
190                                     (SEND_TYPE_ARG4)(SEND_4TH_ARG))
191 #endif
192 #else /* HAVE_SEND */
193 #ifndef swrite
194   /* */
195   Error Missing_definition_of_macro_swrite
196   /* */
197 #endif
198 #endif /* HAVE_SEND */
199 
200 
201 #if 0
202 #if defined(HAVE_RECVFROM)
203 /*
204  * Currently recvfrom is only used on udp sockets.
205  */
206 #if !defined(RECVFROM_TYPE_ARG1) || \
207     !defined(RECVFROM_TYPE_ARG2) || \
208     !defined(RECVFROM_TYPE_ARG3) || \
209     !defined(RECVFROM_TYPE_ARG4) || \
210     !defined(RECVFROM_TYPE_ARG5) || \
211     !defined(RECVFROM_TYPE_ARG6) || \
212     !defined(RECVFROM_TYPE_RETV)
213   /* */
214   Error Missing_definition_of_return_and_arguments_types_of_recvfrom
215   /* */
216 #else
217 #define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1)  (s),  \
218                                                  (RECVFROM_TYPE_ARG2 *)(b),  \
219                                                  (RECVFROM_TYPE_ARG3)  (bl), \
220                                                  (RECVFROM_TYPE_ARG4)  (0),  \
221                                                  (RECVFROM_TYPE_ARG5 *)(f),  \
222                                                  (RECVFROM_TYPE_ARG6 *)(fl))
223 #endif
224 #else /* HAVE_RECVFROM */
225 #ifndef sreadfrom
226   /* */
227   Error Missing_definition_of_macro_sreadfrom
228   /* */
229 #endif
230 #endif /* HAVE_RECVFROM */
231 
232 
233 #ifdef RECVFROM_TYPE_ARG6_IS_VOID
234 #  define RECVFROM_ARG6_T int
235 #else
236 #  define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6
237 #endif
238 #endif /* if 0 */
239 
240 
241 /*
242  * Uppercase macro versions of ANSI/ISO is*() functions/macros which
243  * avoid negative number inputs with argument byte codes > 127.
244  */
245 
246 #define ISSPACE(x)  (isspace((int)  ((unsigned char)x)))
247 #define ISDIGIT(x)  (isdigit((int)  ((unsigned char)x)))
248 #define ISALNUM(x)  (isalnum((int)  ((unsigned char)x)))
249 #define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
250 #define ISGRAPH(x)  (isgraph((int)  ((unsigned char)x)))
251 #define ISALPHA(x)  (isalpha((int)  ((unsigned char)x)))
252 #define ISPRINT(x)  (isprint((int)  ((unsigned char)x)))
253 #define ISUPPER(x)  (isupper((int)  ((unsigned char)x)))
254 #define ISLOWER(x)  (islower((int)  ((unsigned char)x)))
255 
256 #define ISBLANK(x)  (int)((((unsigned char)x) == ' ') || \
257                           (((unsigned char)x) == '\t'))
258 
259 
260 /*
261  * Typedef to 'unsigned char' if bool is not an available 'typedefed' type.
262  */
263 /*
264 #ifndef HAVE_BOOL_T
265 typedef unsigned char bool;
266 #define HAVE_BOOL_T
267 #endif
268 */
269 
270 /*
271  * Default definition of uppercase TRUE and FALSE.
272  */
273 
274 #ifndef TRUE
275 #define TRUE 1
276 #endif
277 #ifndef FALSE
278 #define FALSE 0
279 #endif
280 
281 
282 /*
283  * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
284  */
285 
286 #ifndef HAVE_SIG_ATOMIC_T
287 typedef int sig_atomic_t;
288 #define HAVE_SIG_ATOMIC_T
289 #endif
290 
291 
292 /*
293  * Convenience SIG_ATOMIC_T definition
294  */
295 
296 #ifdef HAVE_SIG_ATOMIC_T_VOLATILE
297 #define SIG_ATOMIC_T static sig_atomic_t
298 #else
299 #define SIG_ATOMIC_T static volatile sig_atomic_t
300 #endif
301 
302 
303 /*
304  * Default return type for signal handlers.
305  */
306 
307 #ifndef RETSIGTYPE
308 #define RETSIGTYPE void
309 #endif
310 
311 
312 /*
313  * Macro used to include code only in debug builds.
314  */
315 
316 #ifdef CURLDEBUG
317 #define DEBUGF(x) x
318 #else
319 #define DEBUGF(x) do { } while (0)
320 #endif
321 
322 
323 /*
324  * Macro used to include assertion code only in debug builds.
325  */
326 
327 #if defined(CURLDEBUG) && defined(HAVE_ASSERT_H)
328 #define DEBUGASSERT(x) assert(x)
329 #else
330 #define DEBUGASSERT(x) do { } while (0)
331 #endif
332 
333 
334 /*
335  * Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno
336  * (or equivalent) on this platform to hide platform details to code using it.
337  */
338 
339 #ifdef USE_WINSOCK
340 #define SOCKERRNO         ((int)WSAGetLastError())
341 #define SET_SOCKERRNO(x)  (WSASetLastError((int)(x)))
342 #else
343 #define SOCKERRNO         (errno)
344 #define SET_SOCKERRNO(x)  (errno = (x))
345 #endif
346 
347 
348 /*
349  * Macro ERRNO / SET_ERRNO() returns / sets the NOT *socket-related* errno
350  * (or equivalent) on this platform to hide platform details to code using it.
351  */
352 
353 #ifdef WIN32
354 #define ERRNO         ((int)GetLastError())
355 #define SET_ERRNO(x)  (SetLastError((DWORD)(x)))
356 #else
357 #define ERRNO         (errno)
358 #define SET_ERRNO(x)  (errno = (x))
359 #endif
360 
361 
362 /*
363  * Portable error number symbolic names defined to Winsock error codes.
364  */
365 
366 #ifdef USE_WINSOCK
367 #undef  EBADF            /* override definition in errno.h */
368 #define EBADF            WSAEBADF
369 #undef  EINTR            /* override definition in errno.h */
370 #define EINTR            WSAEINTR
371 #undef  EINVAL           /* override definition in errno.h */
372 #define EINVAL           WSAEINVAL
373 #define EWOULDBLOCK      WSAEWOULDBLOCK
374 #define EINPROGRESS      WSAEINPROGRESS
375 #define EALREADY         WSAEALREADY
376 #define ENOTSOCK         WSAENOTSOCK
377 #define EDESTADDRREQ     WSAEDESTADDRREQ
378 #define EMSGSIZE         WSAEMSGSIZE
379 #define EPROTOTYPE       WSAEPROTOTYPE
380 #define ENOPROTOOPT      WSAENOPROTOOPT
381 #define EPROTONOSUPPORT  WSAEPROTONOSUPPORT
382 #define ESOCKTNOSUPPORT  WSAESOCKTNOSUPPORT
383 #define EOPNOTSUPP       WSAEOPNOTSUPP
384 #define EPFNOSUPPORT     WSAEPFNOSUPPORT
385 #define EAFNOSUPPORT     WSAEAFNOSUPPORT
386 #define EADDRINUSE       WSAEADDRINUSE
387 #define EADDRNOTAVAIL    WSAEADDRNOTAVAIL
388 #define ENETDOWN         WSAENETDOWN
389 #define ENETUNREACH      WSAENETUNREACH
390 #define ENETRESET        WSAENETRESET
391 #define ECONNABORTED     WSAECONNABORTED
392 #define ECONNRESET       WSAECONNRESET
393 #define ENOBUFS          WSAENOBUFS
394 #define EISCONN          WSAEISCONN
395 #define ENOTCONN         WSAENOTCONN
396 #define ESHUTDOWN        WSAESHUTDOWN
397 #define ETOOMANYREFS     WSAETOOMANYREFS
398 #define ETIMEDOUT        WSAETIMEDOUT
399 #define ECONNREFUSED     WSAECONNREFUSED
400 #define ELOOP            WSAELOOP
401 #ifndef ENAMETOOLONG     /* possible previous definition in errno.h */
402 #define ENAMETOOLONG     WSAENAMETOOLONG
403 #endif
404 #define EHOSTDOWN        WSAEHOSTDOWN
405 #define EHOSTUNREACH     WSAEHOSTUNREACH
406 #ifndef ENOTEMPTY        /* possible previous definition in errno.h */
407 #define ENOTEMPTY        WSAENOTEMPTY
408 #endif
409 #define EPROCLIM         WSAEPROCLIM
410 #define EUSERS           WSAEUSERS
411 #define EDQUOT           WSAEDQUOT
412 #define ESTALE           WSAESTALE
413 #define EREMOTE          WSAEREMOTE
414 #endif
415 
416 
417 /*
418  *  Actually use __32_getpwuid() on 64-bit VMS builds for getpwuid()
419  */
420 
421 #if defined(VMS) && \
422     defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
423 #define getpwuid __32_getpwuid
424 #endif
425 
426 
427 /*
428  * Macro argv_item_t hides platform details to code using it.
429  */
430 
431 #ifdef VMS
432 #define argv_item_t  __char_ptr32
433 #else
434 #define argv_item_t  char *
435 #endif
436 
437 
438 /*
439  * We use this ZERO_NULL to avoid picky compiler warnings,
440  * when assigning a NULL pointer to a function pointer var.
441  */
442 
443 #define ZERO_NULL 0
444 
445 
446 #if defined (__LP64__) && defined(__hpux) && !defined(_XOPEN_SOURCE_EXTENDED)
447 #include <sys/socket.h>
448 /* HP-UX has this oddity where it features a few functions that don't work
449    with socklen_t so we need to convert to ints
450 
451    This is due to socklen_t being a 64bit int under 64bit ABI, but the
452    pre-xopen (default) interfaces require an int, which is 32bits.
453 
454    Therefore, Anytime socklen_t is passed by pointer, the libc function
455    truncates the 64bit socklen_t value by treating it as a 32bit value.
456 
457 
458    Note that some socket calls are allowed to have a NULL pointer for
459    the socklen arg.
460 */
461 
Curl_hp_getsockname(int s,struct sockaddr * name,socklen_t * namelen)462 inline static int Curl_hp_getsockname(int s, struct sockaddr *name,
463                                       socklen_t *namelen)
464 {
465   int rc;
466   if(namelen) {
467      int len = *namelen;
468      rc = getsockname(s, name, &len);
469      *namelen = len;
470    }
471   else
472      rc = getsockname(s, name, 0);
473   return rc;
474 }
475 
Curl_hp_getsockopt(int s,int level,int optname,void * optval,socklen_t * optlen)476 inline static int Curl_hp_getsockopt(int  s, int level, int optname,
477                                      void *optval, socklen_t *optlen)
478 {
479   int rc;
480   if(optlen) {
481     int len = *optlen;
482     rc = getsockopt(s, level, optname, optval, &len);
483     *optlen = len;
484   }
485   else
486     rc = getsockopt(s, level, optname, optval, 0);
487   return rc;
488 }
489 
Curl_hp_accept(int sockfd,struct sockaddr * addr,socklen_t * addrlen)490 inline static int Curl_hp_accept(int sockfd, struct sockaddr *addr,
491                                  socklen_t *addrlen)
492 {
493   int rc;
494   if(addrlen) {
495      int len = *addrlen;
496      rc = accept(sockfd, addr, &len);
497      *addrlen = len;
498   }
499   else
500      rc = accept(sockfd, addr, 0);
501   return rc;
502 }
503 
504 
Curl_hp_recvfrom(int s,void * buf,size_t len,int flags,struct sockaddr * from,socklen_t * fromlen)505 inline static ssize_t Curl_hp_recvfrom(int s, void *buf, size_t len, int flags,
506                                        struct sockaddr *from,
507                                        socklen_t *fromlen)
508 {
509   ssize_t rc;
510   if(fromlen) {
511     int fromlen32 = *fromlen;
512     rc = recvfrom(s, buf, len, flags, from, &fromlen32);
513     *fromlen = fromlen32;
514   }
515   else {
516     rc = recvfrom(s, buf, len, flags, from, 0);
517   }
518   return rc;
519 }
520 
521 #define getsockname(a,b,c) Curl_hp_getsockname((a),(b),(c))
522 #define getsockopt(a,b,c,d,e) Curl_hp_getsockopt((a),(b),(c),(d),(e))
523 #define accept(a,b,c) Curl_hp_accept((a),(b),(c))
524 #define recvfrom(a,b,c,d,e,f) Curl_hp_recvfrom((a),(b),(c),(d),(e),(f))
525 
526 #endif /* HPUX work-around */
527 
528 
529 #endif /* __SETUP_ONCE_H */
530 
531