From: Thomas Quinot Date: Wed, 6 Jun 2007 10:45:42 +0000 (+0200) Subject: socket.c (__gnat_close_signalling_fd): New function. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1c8e4e2e5556facd565d1e61bb0433b37ff86243;p=gcc.git socket.c (__gnat_close_signalling_fd): New function. 2007-04-20 Thomas Quinot * socket.c (__gnat_close_signalling_fd): New function. (__gnat_safe_gethostbyaddr, __gnat_safe_gethostbyname, __gnat_safe_getservbyname, __gnat_safe_getservbyport): New supporting functions for task safe Netdb operations. From-SVN: r125456 --- diff --git a/gcc/ada/socket.c b/gcc/ada/socket.c index ef8e26581a7..cae30e6619c 100644 --- a/gcc/ada/socket.c +++ b/gcc/ada/socket.c @@ -6,7 +6,7 @@ * * * C Implementation File * * * - * Copyright (C) 2003-2006, Free Software Foundation, Inc. * + * Copyright (C) 2003-2007, Free Software Foundation, Inc. * * * * GNAT is free software; you can redistribute it and/or modify it under * * terms of the GNU General Public License as published by the Free Soft- * @@ -52,6 +52,7 @@ extern void __gnat_disable_all_sigpipes (void); extern int __gnat_create_signalling_fds (int *fds); extern int __gnat_read_signalling_fd (int rsig); extern int __gnat_write_signalling_fd (int wsig); +extern void __gnat_close_signalling_fd (int sig); extern void __gnat_free_socket_set (fd_set *); extern void __gnat_last_socket_in_set (fd_set *, int *); extern void __gnat_get_socket_from_set (fd_set *, int *, int *); @@ -115,6 +116,150 @@ __gnat_write_signalling_fd (int wsig) { char c = 0; return write (wsig, &c, 1); } + +/* + * Close one end of a pair of signalling fds + */ +void +__gnat_close_signalling_fd (int sig) { + (void) close (sig); +} +#endif + +/* + * GetXXXbyYYY wrappers + * These functions are used by the default implementation of g-socthi, + * and also by the Windows version. + * + * They can be used for any platform that either provides an intrinsically + * task safe implementation of getXXXbyYYY, or a reentrant variant + * getXXXbyYYY_r. Otherwise, a task safe wrapper, including proper mutual + * exclusion if appropriate, must be implemented in the target specific + * version of g-socthi. + */ + +#ifdef HAVE_THREAD_SAFE_GETxxxBYyyy +int +__gnat_safe_gethostbyname (const char *name, + struct hostent *ret, char *buf, size_t buflen, + int *h_errnop) +{ + struct hostent *rh; + rh = gethostbyname (name); + if (rh == NULL) { + *h_errnop = h_errno; + return -1; + } + *ret = *rh; + *h_errnop = 0; + return 0; +} + +int +__gnat_safe_gethostbyaddr (const char *addr, int len, int type, + struct hostent *ret, char *buf, size_t buflen, + int *h_errnop) +{ + struct hostent *rh; + rh = gethostbyaddr (addr, len, type); + if (rh == NULL) { + *h_errnop = h_errno; + return -1; + } + *ret = *rh; + *h_errnop = 0; + return 0; +} + +int +__gnat_safe_getservbyname (const char *name, const char *proto, + struct servent *ret, char *buf, size_t buflen) +{ + struct servent *rh; + rh = getservbyname (name, proto); + if (rh == NULL) + return -1; + *ret = *rh; + return 0; +} + +int +__gnat_safe_getservbyport (int port, const char *proto, + struct servent *ret, char *buf, size_t buflen) +{ + struct servent *rh; + rh = getservbyport (port, proto); + if (rh == NULL) + return -1; + *ret = *rh; + return 0; +} +#elif HAVE_GETxxxBYyyy_R +int +__gnat_safe_gethostbyname (const char *name, + struct hostent *ret, char *buf, size_t buflen, + int *h_errnop) +{ + struct hostent *rh; + int ri; + +#ifdef __linux__ + (void) gethostbyname_r (name, ret, buf, buflen, &rh, h_errnop); +#else + rh = gethostbyname_r (name, ret, buf, buflen, h_errnop); +#endif + ri = (rh == NULL) ? -1 : 0; + return ri; +} + +int +__gnat_safe_gethostbyaddr (const char *addr, int len, int type, + struct hostent *ret, char *buf, size_t buflen, + int *h_errnop) +{ + struct hostent *rh; + int ri; + +#ifdef __linux__ + (void) gethostbyaddr_r (addr, len, type, ret, buf, buflen, &rh, h_errnop); +#else + rh = gethostbyaddr_r (addr, len, type, ret, buf, buflen, h_errnop); +#endif + ri = (rh == NULL) ? -1 : 0; + return ri; +} + +int +__gnat_safe_getservbyname (const char *name, const char *proto, + struct servent *ret, char *buf, size_t buflen) +{ + struct servent *rh; + int ri; + +#ifdef __linux__ + (void) getservbyname_r (name, proto, ret, buf, buflen, &rh); +#else + rh = getservbyname_r (name, proto, ret, buf, buflen); +#endif + ri = (rh == NULL) ? -1 : 0; + return ri; +} + +int +__gnat_safe_getservbyport (int port, const char *proto, + struct servent *ret, char *buf, size_t buflen) +{ + struct servent *rh; + int ri; + +#ifdef __linux__ + (void) getservbyport_r (port, proto, ret, buf, buflen, &rh); +#else + rh = getservbyport_r (port, proto, ret, buf, buflen); +#endif + ri = (rh == NULL) ? -1 : 0; + return ri; +} #endif /* Free socket set. */ @@ -241,15 +386,24 @@ __gnat_get_h_errno (void) { default: return -1; } -#elif defined(VMS) - return errno; -#elif defined(__rtems__) + +#elif defined (VMS) + /* h_errno is defined as follows in OpenVMS' version of . + * However this header file is not available when building the GNAT + * runtime library using GCC, so we are hardcoding the definition + * directly. Note that the returned address is thread-specific. + */ + extern int *decc$h_errno_get_addr (); + return *decc$h_errno_get_addr (); + +#elif defined (__rtems__) /* At this stage in the tool build, no networking .h files are available. - Newlib does not provide networking .h files and RTEMS is not built yet. - So we need to explicitly extern h_errno to access it. + * Newlib does not provide networking .h files and RTEMS is not built yet. + * So we need to explicitly extern h_errno to access it. */ extern int h_errno; return h_errno; + #else return h_errno; #endif