[multiple changes]
[gcc.git] / gcc / ada / socket.c
1 /****************************************************************************
2 * *
3 * GNAT COMPILER COMPONENTS *
4 * *
5 * S O C K E T *
6 * *
7 * C Implementation File *
8 * *
9 * Copyright (C) 2003-2014, Free Software Foundation, Inc. *
10 * *
11 * GNAT is free software; you can redistribute it and/or modify it under *
12 * terms of the GNU General Public License as published by the Free Soft- *
13 * ware Foundation; either version 3, or (at your option) any later ver- *
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
16 * or FITNESS FOR A PARTICULAR PURPOSE. *
17 * *
18 * As a special exception under Section 7 of GPL version 3, you are granted *
19 * additional permissions described in the GCC Runtime Library Exception, *
20 * version 3.1, as published by the Free Software Foundation. *
21 * *
22 * You should have received a copy of the GNU General Public License and *
23 * a copy of the GCC Runtime Library Exception along with this program; *
24 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see *
25 * <http://www.gnu.org/licenses/>. *
26 * *
27 * GNAT was originally developed by the GNAT team at New York University. *
28 * Extensive contributions were provided by Ada Core Technologies Inc. *
29 * *
30 ****************************************************************************/
31
32 /* This file provides a portable binding to the sockets API */
33
34 /* Ensure access to errno is thread safe. */
35 #define _REENTRANT
36 #define _THREAD_SAFE
37
38 #include "gsocket.h"
39
40 #if defined(VMS)
41 /*
42 * For VMS, gsocket.h can't include sockets-related DEC C header files
43 * when building the runtime (because these files are in a DEC C text library
44 * (DECC$RTLDEF.TLB) not accessible to GCC). So, we generate a separate header
45 * file along with s-oscons.ads and include it here.
46 */
47 # include "s-oscons.h"
48
49 /*
50 * We also need the declaration of struct hostent/servent, which s-oscons
51 * can't provide, so we copy it manually here. This needs to be kept in synch
52 * with the definition of that structure in the DEC C headers, which
53 * hopefully won't change frequently.
54 */
55 typedef char *__netdb_char_ptr __attribute__ (( mode (SI) ));
56 typedef __netdb_char_ptr *__netdb_char_ptr_ptr __attribute__ (( mode (SI) ));
57
58 struct hostent {
59 __netdb_char_ptr h_name;
60 __netdb_char_ptr_ptr h_aliases;
61 int h_addrtype;
62 int h_length;
63 __netdb_char_ptr_ptr h_addr_list;
64 };
65
66 struct servent {
67 __netdb_char_ptr s_name;
68 __netdb_char_ptr_ptr s_aliases;
69 int s_port;
70 __netdb_char_ptr s_proto;
71 };
72 #elif defined(__FreeBSD__)
73 typedef unsigned int IOCTL_Req_T;
74 #else
75 typedef int IOCTL_Req_T;
76 #endif
77
78 #if defined(HAVE_SOCKETS)
79
80 /* Include all the necessary system-specific headers and define the
81 * necessary macros (shared with gen-oscons).
82 */
83
84 #if !defined(SO_NOSIGPIPE) && !defined (MSG_NOSIGNAL)
85 #include <signal.h>
86 #endif
87 /* Required if we will be calling signal() in __gnat_disable_all_sigpipes() */
88
89 #include "raise.h"
90 /* Required for __gnat_malloc() */
91
92 #include <string.h>
93 /* Required for memcpy() */
94
95 extern void __gnat_disable_sigpipe (int fd);
96 extern void __gnat_disable_all_sigpipes (void);
97 extern int __gnat_create_signalling_fds (int *fds);
98 extern int __gnat_read_signalling_fd (int rsig);
99 extern int __gnat_write_signalling_fd (int wsig);
100 extern void __gnat_close_signalling_fd (int sig);
101 extern void __gnat_last_socket_in_set (fd_set *, int *);
102 extern void __gnat_get_socket_from_set (fd_set *, int *, int *);
103 extern void __gnat_insert_socket_in_set (fd_set *, int);
104 extern int __gnat_is_socket_in_set (fd_set *, int);
105 extern fd_set *__gnat_new_socket_set (fd_set *);
106 extern void __gnat_remove_socket_from_set (fd_set *, int);
107 extern void __gnat_reset_socket_set (fd_set *);
108 extern int __gnat_get_h_errno (void);
109 extern int __gnat_socket_ioctl (int, IOCTL_Req_T, int *);
110
111 extern char * __gnat_servent_s_name (struct servent *);
112 extern char * __gnat_servent_s_alias (struct servent *, int index);
113 extern unsigned short __gnat_servent_s_port (struct servent *);
114 extern char * __gnat_servent_s_proto (struct servent *);
115
116 extern char * __gnat_hostent_h_name (struct hostent *);
117 extern char * __gnat_hostent_h_alias (struct hostent *, int);
118 extern int __gnat_hostent_h_addrtype (struct hostent *);
119 extern int __gnat_hostent_h_length (struct hostent *);
120 extern char * __gnat_hostent_h_addr (struct hostent *, int);
121
122 #ifndef HAVE_INET_PTON
123 extern int __gnat_inet_pton (int, const char *, void *);
124 #endif
125 \f
126 /* Disable the sending of SIGPIPE for writes on a broken stream */
127
128 void
129 __gnat_disable_sigpipe (int fd)
130 {
131 #ifdef SO_NOSIGPIPE
132 int val = 1;
133 (void) setsockopt (fd, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof val);
134 #endif
135 }
136
137 void
138 __gnat_disable_all_sigpipes (void)
139 {
140 #if !defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL) && defined(SIGPIPE)
141 (void) signal (SIGPIPE, SIG_IGN);
142 #endif
143 }
144 \f
145 #if defined (_WIN32) || defined (__vxworks) || defined (VMS)
146 /*
147 * Signalling FDs operations are implemented in Ada for these platforms
148 * (see subunit GNAT.Sockets.Thin.Signalling_Fds).
149 */
150 #else
151 /*
152 * Create a pair of connected file descriptors fds[0] and fds[1] used for
153 * signalling by a Selector object. fds[0] is the read end, and fds[1] the
154 * write end.
155 */
156 int
157 __gnat_create_signalling_fds (int *fds) {
158 return pipe (fds);
159 }
160 \f
161 /*
162 * Read one byte of data from rsig, the read end of a pair of signalling fds
163 * created by __gnat_create_signalling_fds.
164 */
165 int
166 __gnat_read_signalling_fd (int rsig) {
167 char c;
168 return read (rsig, &c, 1);
169 }
170 \f
171 /*
172 * Write one byte of data to wsig, the write end of a pair of signalling fds
173 * created by __gnat_create_signalling_fds.
174 */
175 int
176 __gnat_write_signalling_fd (int wsig) {
177 char c = 0;
178 return write (wsig, &c, 1);
179 }
180 \f
181 /*
182 * Close one end of a pair of signalling fds
183 */
184 void
185 __gnat_close_signalling_fd (int sig) {
186 (void) close (sig);
187 }
188 #endif
189 \f
190 /*
191 * Handling of gethostbyname, gethostbyaddr, getservbyname and getservbyport
192 * =========================================================================
193 *
194 * This module exposes __gnat_getXXXbyYYY operations with the same signature
195 * as the reentrant variant getXXXbyYYY_r.
196 *
197 * On platforms where getXXXbyYYY is intrinsically reentrant, the provided user
198 * buffer argument is ignored.
199 *
200 * When getXXXbyYYY is not reentrant but getXXXbyYYY_r exists, the latter is
201 * used, and the provided buffer argument must point to a valid, thread-local
202 * buffer (usually on the caller's stack).
203 *
204 * When getXXXbyYYY is not reentrant and no reentrant getXXXbyYYY_r variant
205 * is available, the non-reentrant getXXXbyYYY is called, the provided user
206 * buffer is ignored, and the caller is expected to take care of mutual
207 * exclusion.
208 */
209
210 #ifdef HAVE_GETxxxBYyyy_R
211 int
212 __gnat_gethostbyname (const char *name,
213 struct hostent *ret, char *buf, size_t buflen,
214 int *h_errnop)
215 {
216 struct hostent *rh;
217 int ri;
218
219 #if defined(__linux__) || defined(__GLIBC__)
220 (void) gethostbyname_r (name, ret, buf, buflen, &rh, h_errnop);
221 #else
222 rh = gethostbyname_r (name, ret, buf, buflen, h_errnop);
223 #endif
224 ri = (rh == NULL) ? -1 : 0;
225 return ri;
226 }
227
228 int
229 __gnat_gethostbyaddr (const char *addr, int len, int type,
230 struct hostent *ret, char *buf, size_t buflen,
231 int *h_errnop)
232 {
233 struct hostent *rh;
234 int ri;
235
236 #if defined(__linux__) || defined(__GLIBC__)
237 (void) gethostbyaddr_r (addr, len, type, ret, buf, buflen, &rh, h_errnop);
238 #else
239 rh = gethostbyaddr_r (addr, len, type, ret, buf, buflen, h_errnop);
240 #endif
241 ri = (rh == NULL) ? -1 : 0;
242 return ri;
243 }
244
245 int
246 __gnat_getservbyname (const char *name, const char *proto,
247 struct servent *ret, char *buf, size_t buflen)
248 {
249 struct servent *rh;
250 int ri;
251
252 #if defined(__linux__) || defined(__GLIBC__) || defined(__rtems__)
253 (void) getservbyname_r (name, proto, ret, buf, buflen, &rh);
254 #else
255 rh = getservbyname_r (name, proto, ret, buf, buflen);
256 #endif
257 ri = (rh == NULL) ? -1 : 0;
258 return ri;
259 }
260
261 int
262 __gnat_getservbyport (int port, const char *proto,
263 struct servent *ret, char *buf, size_t buflen)
264 {
265 struct servent *rh;
266 int ri;
267
268 #if defined(__linux__) || defined(__GLIBC__) || defined(__rtems__)
269 (void) getservbyport_r (port, proto, ret, buf, buflen, &rh);
270 #else
271 rh = getservbyport_r (port, proto, ret, buf, buflen);
272 #endif
273 ri = (rh == NULL) ? -1 : 0;
274 return ri;
275 }
276 #elif defined (__vxworks)
277 static char vxw_h_name[MAXHOSTNAMELEN + 1];
278 static char *vxw_h_aliases[1] = { NULL };
279 static int vxw_h_addr;
280 static char *vxw_h_addr_list[2] = { (char*) &vxw_h_addr, NULL };
281
282 int
283 __gnat_gethostbyname (const char *name,
284 struct hostent *ret, char *buf, size_t buflen,
285 int *h_errnop)
286 {
287 vxw_h_addr = hostGetByName (name);
288 if (vxw_h_addr == ERROR) {
289 *h_errnop = __gnat_get_h_errno ();
290 return -1;
291 }
292 ret->h_name = name;
293 ret->h_aliases = &vxw_h_aliases;
294 ret->h_addrtype = AF_INET;
295 ret->h_length = 4;
296 ret->h_addr_list = &vxw_h_addr_list;
297 return 0;
298 }
299
300 int
301 __gnat_gethostbyaddr (const char *addr, int len, int type,
302 struct hostent *ret, char *buf, size_t buflen,
303 int *h_errnop)
304 {
305 if (type != AF_INET) {
306 *h_errnop = EAFNOSUPPORT;
307 return -1;
308 }
309
310 if (addr == NULL || len != 4) {
311 *h_errnop = EINVAL;
312 return -1;
313 }
314
315 if (hostGetByAddr (*(int*)addr, &vxw_h_name) != OK) {
316 *h_errnop = __gnat_get_h_errno ();
317 return -1;
318 }
319
320 vxw_h_addr = addr;
321
322 ret->h_name = &vxw_h_name;
323 ret->h_aliases = &vxw_h_aliases;
324 ret->h_addrtype = AF_INET;
325 ret->h_length = 4;
326 ret->h_addr_list = &vxw_h_addr_list;
327 }
328
329 int
330 __gnat_getservbyname (const char *name, const char *proto,
331 struct servent *ret, char *buf, size_t buflen)
332 {
333 /* Not available under VxWorks */
334 return -1;
335 }
336
337 int
338 __gnat_getservbyport (int port, const char *proto,
339 struct servent *ret, char *buf, size_t buflen)
340 {
341 /* Not available under VxWorks */
342 return -1;
343 }
344 #else
345 int
346 __gnat_gethostbyname (const char *name,
347 struct hostent *ret, char *buf, size_t buflen,
348 int *h_errnop)
349 {
350 struct hostent *rh;
351 rh = gethostbyname (name);
352 if (rh == NULL) {
353 *h_errnop = __gnat_get_h_errno ();
354 return -1;
355 }
356 *ret = *rh;
357 *h_errnop = 0;
358 return 0;
359 }
360
361 int
362 __gnat_gethostbyaddr (const char *addr, int len, int type,
363 struct hostent *ret, char *buf, size_t buflen,
364 int *h_errnop)
365 {
366 struct hostent *rh;
367 rh = gethostbyaddr (addr, len, type);
368 if (rh == NULL) {
369 *h_errnop = __gnat_get_h_errno ();
370 return -1;
371 }
372 *ret = *rh;
373 *h_errnop = 0;
374 return 0;
375 }
376
377 int
378 __gnat_getservbyname (const char *name, const char *proto,
379 struct servent *ret, char *buf, size_t buflen)
380 {
381 struct servent *rh;
382 rh = getservbyname (name, proto);
383 if (rh == NULL)
384 return -1;
385 *ret = *rh;
386 return 0;
387 }
388
389 int
390 __gnat_getservbyport (int port, const char *proto,
391 struct servent *ret, char *buf, size_t buflen)
392 {
393 struct servent *rh;
394 rh = getservbyport (port, proto);
395 if (rh == NULL)
396 return -1;
397 *ret = *rh;
398 return 0;
399 }
400 #endif
401 \f
402 /* Find the largest socket in the socket set SET. This is needed for
403 `select'. LAST is the maximum value for the largest socket. This hint is
404 used to avoid scanning very large socket sets. On return, LAST is the
405 actual largest socket in the socket set. */
406
407 void
408 __gnat_last_socket_in_set (fd_set *set, int *last)
409 {
410 int s;
411 int l;
412 l = -1;
413
414 #ifdef _WIN32
415 /* More efficient method for NT. */
416 for (s = 0; s < set->fd_count; s++)
417 if ((int) set->fd_array[s] > l)
418 l = set->fd_array[s];
419
420 #else
421
422 for (s = *last; s != -1; s--)
423 if (FD_ISSET (s, set))
424 {
425 l = s;
426 break;
427 }
428 #endif
429
430 *last = l;
431 }
432
433 /* Get last socket and remove it from the socket set SET. LAST is the
434 maximum value of the largest socket. This hint is used to avoid scanning
435 very large socket sets. On return, LAST is set to the actual largest
436 socket in the socket set. */
437
438 void
439 __gnat_get_socket_from_set (fd_set *set, int *last, int *socket)
440 {
441 *socket = *last;
442 FD_CLR (*socket, set);
443 __gnat_last_socket_in_set (set, last);
444 }
445
446 /* Insert SOCKET in the socket set SET. */
447
448 void
449 __gnat_insert_socket_in_set (fd_set *set, int socket)
450 {
451 FD_SET (socket, set);
452 }
453
454 /* Check whether a given SOCKET is in the socket set SET. */
455
456 int
457 __gnat_is_socket_in_set (fd_set *set, int socket)
458 {
459 return FD_ISSET (socket, set);
460 }
461
462 /* Remove SOCKET from the socket set SET. */
463
464 void
465 __gnat_remove_socket_from_set (fd_set *set, int socket)
466 {
467 FD_CLR (socket, set);
468 }
469
470 /* Reset SET */
471 void
472 __gnat_reset_socket_set (fd_set *set)
473 {
474 FD_ZERO (set);
475 }
476
477 /* Get the value of the last host error */
478
479 int
480 __gnat_get_h_errno (void) {
481 #ifdef __vxworks
482 int vxw_errno = errno;
483
484 switch (vxw_errno) {
485 case 0:
486 return 0;
487
488 #ifdef S_hostLib_HOST_NOT_FOUND
489 case S_hostLib_HOST_NOT_FOUND:
490 #endif
491 case S_hostLib_UNKNOWN_HOST:
492 return HOST_NOT_FOUND;
493
494 #ifdef S_hostLib_TRY_AGAIN
495 case S_hostLib_TRY_AGAIN:
496 return TRY_AGAIN;
497 #endif
498
499 #ifdef S_hostLib_NO_RECOVERY
500 case S_hostLib_NO_RECOVERY:
501 #endif
502 #ifdef S_hostLib_NETDB_INTERNAL
503 case S_hostLib_NETDB_INTERNAL:
504 #endif
505 case S_hostLib_INVALID_PARAMETER:
506 return NO_RECOVERY;
507
508 default:
509 return -1;
510 }
511
512 #elif defined (VMS)
513 /* h_errno is defined as follows in OpenVMS' version of <netdb.h>.
514 * However this header file is not available when building the GNAT
515 * runtime library using GCC, so we are hardcoding the definition
516 * directly. Note that the returned address is thread-specific.
517 */
518 extern int *decc$h_errno_get_addr ();
519 return *decc$h_errno_get_addr ();
520
521 #elif defined (__rtems__)
522 /* At this stage in the tool build, no networking .h files are available.
523 * Newlib does not provide networking .h files and RTEMS is not built yet.
524 * So we need to explicitly extern h_errno to access it.
525 */
526 extern int h_errno;
527 return h_errno;
528
529 #else
530 return h_errno;
531 #endif
532 }
533
534 /* Wrapper for ioctl(2), which is a variadic function */
535
536 int
537 __gnat_socket_ioctl (int fd, IOCTL_Req_T req, int *arg) {
538 #if defined (_WIN32)
539 return ioctlsocket (fd, req, arg);
540 #elif defined (__APPLE__)
541 /*
542 * On Darwin, req is an unsigned long, and we want to convert without sign
543 * extension to get the proper bit pattern in the case of a 64 bit kernel.
544 */
545 return ioctl (fd, (unsigned int) req, arg);
546 #else
547 return ioctl (fd, req, arg);
548 #endif
549 }
550
551 #ifndef HAVE_INET_PTON
552
553 #ifdef VMS
554 # define in_addr_t int
555 # define inet_addr decc$inet_addr
556 #endif
557
558 int
559 __gnat_inet_pton (int af, const char *src, void *dst) {
560 switch (af) {
561 #if defined (_WIN32) && defined (AF_INET6)
562 case AF_INET6:
563 #endif
564 case AF_INET:
565 break;
566 default:
567 errno = EAFNOSUPPORT;
568 return -1;
569 }
570
571 #if defined (__vxworks)
572 return (inet_aton (src, dst) == OK);
573
574 #elif defined (_WIN32)
575 struct sockaddr_storage ss;
576 int sslen = sizeof ss;
577 int rc;
578
579 ss.ss_family = af;
580 rc = WSAStringToAddressA (src, af, NULL, (struct sockaddr *)&ss, &sslen);
581 if (rc == 0) {
582 switch (af) {
583 case AF_INET:
584 *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
585 break;
586 #ifdef AF_INET6
587 case AF_INET6:
588 *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
589 break;
590 #endif
591 }
592 }
593 return (rc == 0);
594
595 #elif defined (__hpux__) || defined (VMS)
596 in_addr_t addr;
597 int rc = -1;
598
599 if (src == NULL || dst == NULL) {
600 errno = EINVAL;
601
602 } else if (!strcmp (src, "255.255.255.255")) {
603 addr = 0xffffffff;
604 rc = 1;
605
606 } else {
607 addr = inet_addr (src);
608 rc = (addr != 0xffffffff);
609 }
610 if (rc == 1) {
611 *(in_addr_t *)dst = addr;
612 }
613 return rc;
614 #endif
615 }
616 #endif
617
618 /*
619 * Accessor functions for struct hostent.
620 */
621
622 char * __gnat_hostent_h_name (struct hostent * h) {
623 return h->h_name;
624 }
625
626 char * __gnat_hostent_h_alias (struct hostent * h, int index) {
627 return h->h_aliases[index];
628 }
629
630 int __gnat_hostent_h_addrtype (struct hostent * h) {
631 return h->h_addrtype;
632 }
633
634 int __gnat_hostent_h_length (struct hostent * h) {
635 return h->h_length;
636 }
637
638 char * __gnat_hostent_h_addr (struct hostent * h, int index) {
639 return h->h_addr_list[index];
640 }
641
642 /*
643 * Accessor functions for struct servent.
644 *
645 * These are needed because servent has different representations on different
646 * platforms, and we don't want to deal with that on the Ada side. For example,
647 * on Linux, we have (see /usr/include netdb.h):
648 *
649 * struct servent
650 * {
651 * char *s_name;
652 * char **s_aliases;
653 * int s_port;
654 * char *s_proto;
655 * };
656 *
657 * and on Windows (see mingw's socket.h):
658 *
659 * struct servent {
660 * char *s_name;
661 * char **s_aliases;
662 * #ifdef _WIN64
663 * char *s_proto;
664 * short s_port;
665 * #else
666 * short s_port;
667 * char *s_proto;
668 * #endif
669 * };
670 */
671
672 char *
673 __gnat_servent_s_name (struct servent * s)
674 {
675 return s->s_name;
676 }
677
678 char *
679 __gnat_servent_s_alias (struct servent * s, int index)
680 {
681 return s->s_aliases[index];
682 }
683
684 unsigned short
685 __gnat_servent_s_port (struct servent * s)
686 {
687 return s->s_port;
688 }
689
690 char *
691 __gnat_servent_s_proto (struct servent * s)
692 {
693 return s->s_proto;
694 }
695
696 #endif /* defined(HAVE_SOCKETS) */