OSDN Git Service

* lto.c (get_filename_for_set): Look for cgraph node and if none found, use
[pf3gnuchains/gcc-fork.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-2009, 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 #include "gsocket.h"
35 #ifdef VMS
36 /*
37  * For VMS, gsocket.h can't include sockets-related DEC C header files
38  * when building the runtime (because these files are in a DEC C text library
39  * (DECC$RTLDEF.TLB) not accessable to GCC). So, we generate a separate header
40  * file along with s-oscons.ads and include it here.
41  */
42 # include "s-oscons.h"
43
44 /*
45  * We also need the declaration of struct servent, which s-oscons can't
46  * provide, so we copy it manually here. This needs to be kept in synch
47  * with the definition of that structure in the DEC C headers, which
48  * hopefully won't change frequently.
49  */
50 struct servent {
51   char *s_name;     /* official service name */
52   char **s_aliases; /* alias list */
53   int  s_port;      /* port # */
54   char *s_proto;    /* protocol to use */
55 };
56 #endif
57
58 #if defined(HAVE_SOCKETS)
59
60 /* Include all the necessary system-specific headers and define the
61  * necessary macros (shared with gen-oscons).
62  */
63
64 #if !defined(SO_NOSIGPIPE) && !defined (MSG_NOSIGNAL)
65 #include <signal.h>
66 #endif
67 /* Required if we will be calling signal() in __gnat_disable_all_sigpipes() */
68
69 #include "raise.h"
70 /* Required for __gnat_malloc() */
71
72 #include <string.h>
73 /* Required for memcpy() */
74
75 extern void __gnat_disable_sigpipe (int fd);
76 extern void __gnat_disable_all_sigpipes (void);
77 extern int  __gnat_create_signalling_fds (int *fds);
78 extern int  __gnat_read_signalling_fd (int rsig);
79 extern int  __gnat_write_signalling_fd (int wsig);
80 extern void  __gnat_close_signalling_fd (int sig);
81 extern void __gnat_last_socket_in_set (fd_set *, int *);
82 extern void __gnat_get_socket_from_set (fd_set *, int *, int *);
83 extern void __gnat_insert_socket_in_set (fd_set *, int);
84 extern int __gnat_is_socket_in_set (fd_set *, int);
85 extern fd_set *__gnat_new_socket_set (fd_set *);
86 extern void __gnat_remove_socket_from_set (fd_set *, int);
87 extern void __gnat_reset_socket_set (fd_set *);
88 extern int  __gnat_get_h_errno (void);
89 extern int  __gnat_socket_ioctl (int, int, int *);
90 extern char * __gnat_servent_s_name (struct servent *);
91 extern char ** __gnat_servent_s_aliases (struct servent *);
92 extern int __gnat_servent_s_port (struct servent *);
93 extern char * __gnat_servent_s_proto (struct servent *);
94 extern void __gnat_servent_set_s_name (struct servent *, char *);
95 extern void __gnat_servent_set_s_aliases (struct servent *, char **);
96 extern void __gnat_servent_set_s_port (struct servent *, int);
97 extern void __gnat_servent_set_s_proto (struct servent *, char *);
98 #if defined (__vxworks) || defined (_WIN32)
99 extern int  __gnat_inet_pton (int, const char *, void *);
100 #endif
101 \f
102 /* Disable the sending of SIGPIPE for writes on a broken stream */
103
104 void
105 __gnat_disable_sigpipe (int fd)
106 {
107 #ifdef SO_NOSIGPIPE
108   int val = 1;
109   (void) setsockopt (fd, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof val);
110 #endif
111 }
112
113 void
114 __gnat_disable_all_sigpipes (void)
115 {
116 #if !defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL) && defined(SIGPIPE)
117   (void) signal (SIGPIPE, SIG_IGN);
118 #endif
119 }
120 \f
121 #if defined (_WIN32) || defined (__vxworks) || defined (VMS)
122 /*
123  * Signalling FDs operations are implemented in Ada for these platforms
124  * (see subunit GNAT.Sockets.Thin.Signalling_Fds).
125  */
126 #else
127 /*
128  * Create a pair of connected file descriptors fds[0] and fds[1] used for
129  * signalling by a Selector object. fds[0] is the read end, and fds[1] the
130  * write end.
131  */
132 int
133 __gnat_create_signalling_fds (int *fds) {
134   return pipe (fds);
135 }
136 \f
137 /*
138  * Read one byte of data from rsig, the read end of a pair of signalling fds
139  * created by __gnat_create_signalling_fds.
140  */
141 int
142 __gnat_read_signalling_fd (int rsig) {
143   char c;
144   return read (rsig, &c, 1);
145 }
146 \f
147 /*
148  * Write one byte of data to wsig, the write end of a pair of signalling fds
149  * created by __gnat_create_signalling_fds.
150  */
151 int
152 __gnat_write_signalling_fd (int wsig) {
153   char c = 0;
154   return write (wsig, &c, 1);
155 }
156 \f
157 /*
158  * Close one end of a pair of signalling fds
159  */
160 void
161 __gnat_close_signalling_fd (int sig) {
162   (void) close (sig);
163 }
164 #endif
165 \f
166 /*
167  * GetXXXbyYYY wrappers
168  * These functions are used by the default implementation of g-socthi,
169  * and also by the Windows version.
170  *
171  * They can be used for any platform that either provides an intrinsically
172  * task safe implementation of getXXXbyYYY, or a reentrant variant
173  * getXXXbyYYY_r. Otherwise, a task safe wrapper, including proper mutual
174  * exclusion if appropriate, must be implemented in the target specific
175  * version of g-socthi.
176  */
177
178 #ifdef HAVE_THREAD_SAFE_GETxxxBYyyy
179 int
180 __gnat_safe_gethostbyname (const char *name,
181   struct hostent *ret, char *buf, size_t buflen,
182   int *h_errnop)
183 {
184   struct hostent *rh;
185   rh = gethostbyname (name);
186   if (rh == NULL) {
187     *h_errnop = h_errno;
188     return -1;
189   }
190   *ret = *rh;
191   *h_errnop = 0;
192   return 0;
193 }
194
195 int
196 __gnat_safe_gethostbyaddr (const char *addr, int len, int type,
197   struct hostent *ret, char *buf, size_t buflen,
198   int *h_errnop)
199 {
200   struct hostent *rh;
201   rh = gethostbyaddr (addr, len, type);
202   if (rh == NULL) {
203     *h_errnop = h_errno;
204     return -1;
205   }
206   *ret = *rh;
207   *h_errnop = 0;
208   return 0;
209 }
210
211 int
212 __gnat_safe_getservbyname (const char *name, const char *proto,
213   struct servent *ret, char *buf, size_t buflen)
214 {
215   struct servent *rh;
216   rh = getservbyname (name, proto);
217   if (rh == NULL)
218     return -1;
219   *ret = *rh;
220   return 0;
221 }
222
223 int
224 __gnat_safe_getservbyport (int port, const char *proto,
225   struct servent *ret, char *buf, size_t buflen)
226 {
227   struct servent *rh;
228   rh = getservbyport (port, proto);
229   if (rh == NULL)
230     return -1;
231   *ret = *rh;
232   return 0;
233 }
234 #elif HAVE_GETxxxBYyyy_R
235 int
236 __gnat_safe_gethostbyname (const char *name,
237   struct hostent *ret, char *buf, size_t buflen,
238   int *h_errnop)
239 {
240   struct hostent *rh;
241   int ri;
242
243 #if defined(__linux__) || defined(__GLIBC__)
244   (void) gethostbyname_r (name, ret, buf, buflen, &rh, h_errnop);
245 #else
246   rh = gethostbyname_r (name, ret, buf, buflen, h_errnop);
247 #endif
248   ri = (rh == NULL) ? -1 : 0;
249   return ri;
250 }
251
252 int
253 __gnat_safe_gethostbyaddr (const char *addr, int len, int type,
254   struct hostent *ret, char *buf, size_t buflen,
255   int *h_errnop)
256 {
257   struct hostent *rh;
258   int ri;
259
260 #if defined(__linux__) || defined(__GLIBC__)
261   (void) gethostbyaddr_r (addr, len, type, ret, buf, buflen, &rh, h_errnop);
262 #else
263   rh = gethostbyaddr_r (addr, len, type, ret, buf, buflen, h_errnop);
264 #endif
265   ri = (rh == NULL) ? -1 : 0;
266   return ri;
267 }
268
269 int
270 __gnat_safe_getservbyname (const char *name, const char *proto,
271   struct servent *ret, char *buf, size_t buflen)
272 {
273   struct servent *rh;
274   int ri;
275
276 #if defined(__linux__) || defined(__GLIBC__) || defined(__rtems__)
277   (void) getservbyname_r (name, proto, ret, buf, buflen, &rh);
278 #else
279   rh = getservbyname_r (name, proto, ret, buf, buflen);
280 #endif
281   ri = (rh == NULL) ? -1 : 0;
282   return ri;
283 }
284
285 int
286 __gnat_safe_getservbyport (int port, const char *proto,
287   struct servent *ret, char *buf, size_t buflen)
288 {
289   struct servent *rh;
290   int ri;
291
292 #if defined(__linux__) || defined(__GLIBC__) || defined(__rtems__)
293   (void) getservbyport_r (port, proto, ret, buf, buflen, &rh);
294 #else
295   rh = getservbyport_r (port, proto, ret, buf, buflen);
296 #endif
297   ri = (rh == NULL) ? -1 : 0;
298   return ri;
299 }
300 #endif
301 \f
302 /* Find the largest socket in the socket set SET. This is needed for
303    `select'.  LAST is the maximum value for the largest socket. This hint is
304    used to avoid scanning very large socket sets.  On return, LAST is the
305    actual largest socket in the socket set. */
306
307 void
308 __gnat_last_socket_in_set (fd_set *set, int *last)
309 {
310   int s;
311   int l;
312   l = -1;
313
314 #ifdef _WIN32
315   /* More efficient method for NT. */
316   for (s = 0; s < set->fd_count; s++)
317     if ((int) set->fd_array[s] > l)
318       l = set->fd_array[s];
319
320 #else
321
322   for (s = *last; s != -1; s--)
323     if (FD_ISSET (s, set))
324       {
325         l = s;
326         break;
327       }
328 #endif
329
330   *last = l;
331 }
332
333 /* Get last socket and remove it from the socket set SET.  LAST is the
334    maximum value of the largest socket.  This hint is used to avoid scanning
335    very large socket sets.  On return, LAST is set to the actual largest
336    socket in the socket set. */
337
338 void
339 __gnat_get_socket_from_set (fd_set *set, int *last, int *socket)
340 {
341   *socket = *last;
342   FD_CLR (*socket, set);
343   __gnat_last_socket_in_set (set, last);
344 }
345
346 /* Insert SOCKET in the socket set SET. */
347
348 void
349 __gnat_insert_socket_in_set (fd_set *set, int socket)
350 {
351   FD_SET (socket, set);
352 }
353
354 /* Check whether a given SOCKET is in the socket set SET. */
355
356 int
357 __gnat_is_socket_in_set (fd_set *set, int socket)
358 {
359   return FD_ISSET (socket, set);
360 }
361
362 /* Remove SOCKET from the socket set SET. */
363
364 void
365 __gnat_remove_socket_from_set (fd_set *set, int socket)
366 {
367   FD_CLR (socket, set);
368 }
369
370 /* Reset SET */
371 void
372 __gnat_reset_socket_set (fd_set *set)
373 {
374   FD_ZERO (set);
375 }
376
377 /* Get the value of the last host error */
378
379 int
380 __gnat_get_h_errno (void) {
381 #ifdef __vxworks
382   int vxw_errno = errno;
383
384   switch (vxw_errno) {
385     case 0:
386       return 0;
387
388 #ifdef S_hostLib_HOST_NOT_FOUND
389     case S_hostLib_HOST_NOT_FOUND:
390 #endif
391     case S_hostLib_UNKNOWN_HOST:
392       return HOST_NOT_FOUND;
393
394 #ifdef S_hostLib_TRY_AGAIN
395     case S_hostLib_TRY_AGAIN:
396       return TRY_AGAIN;
397 #endif
398
399 #ifdef S_hostLib_NO_RECOVERY
400     case S_hostLib_NO_RECOVERY:
401 #endif
402 #ifdef S_hostLib_NETDB_INTERNAL
403     case S_hostLib_NETDB_INTERNAL:
404 #endif
405     case S_hostLib_INVALID_PARAMETER:
406       return NO_RECOVERY;
407
408     default:
409       return -1;
410   }
411
412 #elif defined (VMS)
413   /* h_errno is defined as follows in OpenVMS' version of <netdb.h>.
414    * However this header file is not available when building the GNAT
415    * runtime library using GCC, so we are hardcoding the definition
416    * directly. Note that the returned address is thread-specific.
417    */
418   extern int *decc$h_errno_get_addr ();
419   return *decc$h_errno_get_addr ();
420
421 #elif defined (__rtems__)
422   /* At this stage in the tool build, no networking .h files are available.
423    * Newlib does not provide networking .h files and RTEMS is not built yet.
424    * So we need to explicitly extern h_errno to access it.
425    */
426   extern int h_errno;
427   return h_errno;
428
429 #else
430   return h_errno;
431 #endif
432 }
433
434 /* Wrapper for ioctl(2), which is a variadic function */
435
436 int
437 __gnat_socket_ioctl (int fd, int req, int *arg) {
438 #if defined (_WIN32)
439   return ioctlsocket (fd, req, arg);
440 #else
441   return ioctl (fd, req, arg);
442 #endif
443 }
444
445 #ifndef HAVE_INET_PTON
446
447 #ifdef VMS
448 # define in_addr_t int
449 # define inet_addr decc$inet_addr
450 #endif
451
452 int
453 __gnat_inet_pton (int af, const char *src, void *dst) {
454   switch (af) {
455 #if defined (_WIN32) && defined (AF_INET6)
456     case AF_INET6:
457 #endif
458     case AF_INET:
459       break;
460     default:
461       errno = EAFNOSUPPORT;
462       return -1;
463   }
464
465 #if defined (__vxworks)
466   return (inet_aton (src, dst) == OK);
467
468 #elif defined (_WIN32)
469   struct sockaddr_storage ss;
470   int sslen = sizeof ss;
471   int rc;
472
473   ss.ss_family = af;
474   rc = WSAStringToAddressA (src, af, NULL, (struct sockaddr *)&ss, &sslen);
475   if (rc == 0) {
476     switch (af) {
477       case AF_INET:
478         *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
479         break;
480 #ifdef AF_INET6
481       case AF_INET6:
482         *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
483         break;
484 #endif
485     }
486   }
487   return (rc == 0);
488
489 #elif defined (__hpux__) || defined (VMS)
490   in_addr_t addr;
491   int rc = -1;
492
493   if (src == NULL || dst == NULL) {
494     errno = EINVAL;
495
496   } else if (!strcmp (src, "255.255.255.255")) {
497     addr = 0xffffffff;
498     rc = 1;
499
500   } else {
501     addr = inet_addr (src);
502     rc = (addr != 0xffffffff);
503   }
504   if (rc == 1) {
505     *(in_addr_t *)dst = addr;
506   }
507   return rc;
508 #endif
509 }
510 #endif
511
512 /*
513  * Accessor functions for struct servent.
514  *
515  * These are needed because servent has different representations on different
516  * platforms, and we don't want to deal with that on the Ada side. For example,
517  * on Linux, we have (see /usr/include netdb.h):
518  *
519  *   struct servent
520  *   {
521  *     char *s_name;
522  *     char **s_aliases;
523  *     int s_port;
524  *     char *s_proto;
525  *   };
526  *
527  * and on Windows (see mingw's socket.h):
528  *
529  *   struct servent {
530  *     char *s_name;
531  *     char **s_aliases;
532  *   #ifdef _WIN64
533  *     char *s_proto;
534  *     short s_port;
535  *   #else
536  *     short s_port;
537  *     char *s_proto;
538  *   #endif
539  *   };
540  */
541
542 /* Getters */
543
544 char *
545 __gnat_servent_s_name (struct servent * s)
546 {
547   return s->s_name;
548 }
549
550 char **
551 __gnat_servent_s_aliases (struct servent * s)
552 {
553   return s->s_aliases;
554 }
555
556 int
557 __gnat_servent_s_port (struct servent * s)
558 {
559   return s->s_port;
560 }
561
562 char *
563 __gnat_servent_s_proto (struct servent * s)
564 {
565   return s->s_proto;
566 }
567
568 /* Setters */
569
570 void
571 __gnat_servent_set_s_name (struct servent * s, char * s_name)
572 {
573   s->s_name = s_name;
574 }
575
576 void
577 __gnat_servent_set_s_aliases (struct servent * s, char ** s_aliases)
578 {
579   s->s_aliases = s_aliases;
580 }
581
582 void
583 __gnat_servent_set_s_port (struct servent * s, int s_port)
584 {
585   s->s_port = s_port;
586 }
587
588 void
589 __gnat_servent_set_s_proto (struct servent * s, char * s_proto)
590 {
591   s->s_proto = s_proto;
592 }
593
594 #else
595 # warning Sockets are not supported on this platform
596 #endif /* defined(HAVE_SOCKETS) */