summaryrefslogtreecommitdiff
path: root/gcc/ada/socket.c
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2010-06-14 12:39:55 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2010-06-14 12:39:55 +0000
commit43708347a65411b3b9632daf540c2e23834620c2 (patch)
treea0154a432838c9ab26b6f1434eabfeddc95a92d8 /gcc/ada/socket.c
parent59805910dc260c5cdfca5ae9524a6bced9246d72 (diff)
downloadgcc-43708347a65411b3b9632daf540c2e23834620c2.tar.gz
2010-06-14 Ed Schonberg <schonberg@adacore.com>
* sem_ch8.adb (End_Use_Type): Before indicating that an operator is not use-visible, check whether it is a primitive for more than one type. 2010-06-14 Robert Dewar <dewar@adacore.com> * sem_ch3.adb (Copy_And_Swap): Copy Has_Pragma_Unmodified flag. * sem_ch7.adb (Preserve_Full_Attributes): Preserve Has_Pragma_Unmodified flag. 2010-06-14 Thomas Quinot <quinot@adacore.com> * g-sttsne-locking.adb, g-sttsne-locking.ads, g-sttsne.ads, g-sttsne-vxworks.adb, g-sttsne-dummy.ads: Removed. Mutual exclusion is now done in GNAT.Sockets if necessary. * gsocket.h, g-socket.adb, g-sothco.ads (GNAT.Sockets.Get_XXX_By_YYY): Ensure mutual exclusion for netdb operations if the target platform requires it. (GNAT.Sockets.Thin_Common): New binding for getXXXbyYYY, treating struct hostent as an opaque type to improve portability. * s-oscons-tmplt.c, socket.c: For the case of Vxworks, emulate gethostbyYYY using proprietary VxWorks API so that a uniform interface is available for the Ada side. * gcc-interface/Makefile.in: Remove g-sttsne-* * gcc-interface/Make-lang.in: Update dependencies. 2010-06-14 Vincent Celier <celier@adacore.com> * gnatcmd.adb (Mapping_File): New function. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160731 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/socket.c')
-rw-r--r--gcc/ada/socket.c328
1 files changed, 215 insertions, 113 deletions
diff --git a/gcc/ada/socket.c b/gcc/ada/socket.c
index 76755643161..d03ddea8164 100644
--- a/gcc/ada/socket.c
+++ b/gcc/ada/socket.c
@@ -32,6 +32,7 @@
/* This file provides a portable binding to the sockets API */
#include "gsocket.h"
+
#ifdef VMS
/*
* For VMS, gsocket.h can't include sockets-related DEC C header files
@@ -42,16 +43,41 @@
# include "s-oscons.h"
/*
- * We also need the declaration of struct servent, which s-oscons can't
- * provide, so we copy it manually here. This needs to be kept in synch
+ * We also need the declaration of struct hostent/servent, which s-oscons
+ * can't provide, so we copy it manually here. This needs to be kept in synch
* with the definition of that structure in the DEC C headers, which
* hopefully won't change frequently.
*/
+typedef char *__netdb_char_ptr __attribute__ (( mode (SI) ));
+typedef __netdb_char_ptr *__netdb_char_ptr_ptr __attribute__ (( mode (SI) ));
+# define NEED_STRUCT_xxxENT
+
+#elif defined (__vxworks)
+/*
+ * For VxWorks we emulate getXXXbyYYY using the proprietary VxWorks API.
+ */
+typedef char *__netdb_char_ptr;
+typedef __netdb_char_ptr *__netdb_char_ptr_ptr;
+# define NEED_STRUCT_xxxENT
+
+#else
+# undef NEED_STRUCT_xxxENT
+#endif
+
+#ifdef NEED_STRUCT_xxxENT
+struct hostent {
+ __netdb_char_ptr h_name;
+ __netdb_char_ptr_ptr h_aliases;
+ int h_addrtype;
+ int h_length;
+ __netdb_char_ptr_ptr h_addr_list;
+};
+
struct servent {
- char *s_name; /* official service name */
- char **s_aliases; /* alias list */
- int s_port; /* port # */
- char *s_proto; /* protocol to use */
+ __netdb_char_ptr s_name;
+ __netdb_char_ptr_ptr s_aliases;
+ int s_port;
+ __netdb_char_ptr s_proto;
};
#endif
@@ -87,14 +113,18 @@ extern void __gnat_remove_socket_from_set (fd_set *, int);
extern void __gnat_reset_socket_set (fd_set *);
extern int __gnat_get_h_errno (void);
extern int __gnat_socket_ioctl (int, int, int *);
+
extern char * __gnat_servent_s_name (struct servent *);
-extern char ** __gnat_servent_s_aliases (struct servent *);
-extern int __gnat_servent_s_port (struct servent *);
+extern char * __gnat_servent_s_alias (struct servent *, int index);
+extern unsigned short __gnat_servent_s_port (struct servent *);
extern char * __gnat_servent_s_proto (struct servent *);
-extern void __gnat_servent_set_s_name (struct servent *, char *);
-extern void __gnat_servent_set_s_aliases (struct servent *, char **);
-extern void __gnat_servent_set_s_port (struct servent *, int);
-extern void __gnat_servent_set_s_proto (struct servent *, char *);
+
+extern char * __gnat_hostent_h_name (struct hostent *);
+extern char * __gnat_hostent_h_alias (struct hostent *, int);
+extern int __gnat_hostent_h_addrtype (struct hostent *);
+extern int __gnat_hostent_h_length (struct hostent *);
+extern char * __gnat_hostent_h_addr (struct hostent *, int);
+
#if defined (__vxworks) || defined (_WIN32)
extern int __gnat_inet_pton (int, const char *, void *);
#endif
@@ -164,76 +194,28 @@ __gnat_close_signalling_fd (int sig) {
#endif
/*
- * GetXXXbyYYY wrappers
- * These functions are used by the default implementation of g-socthi,
- * and also by the Windows version.
+ * Handling of gethostbyname, gethostbyaddr, getservbyname and getservbyport
+ * =========================================================================
+ *
+ * This module exposes __gnat_getXXXbyYYY operations with the same signature
+ * as the reentrant variant getXXXbyYYY_r.
+ *
+ * On platforms where getXXXbyYYY is intrinsically reentrant, the provided user
+ * buffer argument is ignored.
*
- * 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.
+ * When getXXXbyYYY is not reentrant but getXXXbyYYY_r exists, the latter is
+ * used, and the provided buffer argument must point to a valid, thread-local
+ * buffer (usually on the caller's stack).
+ *
+ * When getXXXbyYYY is not reentrant and no reentrant getXXXbyYYY_r variant
+ * is available, the non-reentrant getXXXbyYYY is called, the provided user
+ * buffer is ignored, and the caller is expected to take care of mutual
+ * exclusion.
*/
-#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;
-}
-
+#ifdef HAVE_GETxxxBYyyy_R
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,
+__gnat_gethostbyname (const char *name,
struct hostent *ret, char *buf, size_t buflen,
int *h_errnop)
{
@@ -250,7 +232,7 @@ __gnat_safe_gethostbyname (const char *name,
}
int
-__gnat_safe_gethostbyaddr (const char *addr, int len, int type,
+__gnat_gethostbyaddr (const char *addr, int len, int type,
struct hostent *ret, char *buf, size_t buflen,
int *h_errnop)
{
@@ -267,7 +249,7 @@ __gnat_safe_gethostbyaddr (const char *addr, int len, int type,
}
int
-__gnat_safe_getservbyname (const char *name, const char *proto,
+__gnat_getservbyname (const char *name, const char *proto,
struct servent *ret, char *buf, size_t buflen)
{
struct servent *rh;
@@ -283,7 +265,7 @@ __gnat_safe_getservbyname (const char *name, const char *proto,
}
int
-__gnat_safe_getservbyport (int port, const char *proto,
+__gnat_getservbyport (int port, const char *proto,
struct servent *ret, char *buf, size_t buflen)
{
struct servent *rh;
@@ -297,6 +279,130 @@ __gnat_safe_getservbyport (int port, const char *proto,
ri = (rh == NULL) ? -1 : 0;
return ri;
}
+#elif defined (__vxworks)
+static char vxw_h_name[MAXHOSTNAMELEN + 1];
+static char *vxw_h_aliases[1] = { NULL };
+static int vxw_h_addr;
+static char *vxw_h_addr_list[2] = { (char*) &vxw_h_addr, NULL };
+
+int
+__gnat_gethostbyname (const char *name,
+ struct hostent *ret, char *buf, size_t buflen,
+ int *h_errnop)
+{
+ vxw_h_addr = hostGetByName (name);
+ if (vxw_h_addr == ERROR) {
+ *h_errnop = __gnat_get_h_errno ();
+ return -1;
+ }
+ ret->h_name = name;
+ ret->h_aliases = &vxw_h_aliases;
+ ret->h_addrtype = AF_INET;
+ ret->h_length = 4;
+ ret->h_addr_list = &vxw_h_addr_list;
+ return 0;
+}
+
+int
+__gnat_gethostbyaddr (const char *addr, int len, int type,
+ struct hostent *ret, char *buf, size_t buflen,
+ int *h_errnop)
+{
+ if (type != AF_INET) {
+ *h_errnop = EAFNOSUPPORT;
+ return -1;
+ }
+
+ if (addr == NULL || len != 4) {
+ *h_errnop = EINVAL;
+ return -1;
+ }
+
+ if (hostGetByAddr (*(int*)addr, &vxw_h_name) != OK) {
+ *h_errnop = __gnat_get_h_errno ();
+ return -1;
+ }
+
+ vxw_h_addr = addr;
+
+ ret->h_name = &vxw_h_name;
+ ret->h_aliases = &vxw_h_aliases;
+ ret->h_addrtype = AF_INET;
+ ret->h_length = 4;
+ ret->h_addr_list = &vxw_h_addr_list;
+}
+
+int
+__gnat_getservbyname (const char *name, const char *proto,
+ struct servent *ret, char *buf, size_t buflen)
+{
+ /* Not available under VxWorks */
+ return -1;
+}
+
+int
+__gnat_getservbyport (int port, const char *proto,
+ struct servent *ret, char *buf, size_t buflen)
+{
+ /* Not available under VxWorks */
+ return -1;
+}
+#else
+int
+__gnat_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 = __gnat_get_h_errno ();
+ return -1;
+ }
+ *ret = *rh;
+ *h_errnop = 0;
+ return 0;
+}
+
+int
+__gnat_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 = __gnat_get_h_errno ();
+ return -1;
+ }
+ *ret = *rh;
+ *h_errnop = 0;
+ return 0;
+}
+
+int
+__gnat_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_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;
+}
#endif
/* Find the largest socket in the socket set SET. This is needed for
@@ -510,6 +616,30 @@ __gnat_inet_pton (int af, const char *src, void *dst) {
#endif
/*
+ * Accessor functions for struct hostent.
+ */
+
+char * __gnat_hostent_h_name (struct hostent * h) {
+ return h->h_name;
+}
+
+char * __gnat_hostent_h_alias (struct hostent * h, int index) {
+ return h->h_aliases[index];
+}
+
+int __gnat_hostent_h_addrtype (struct hostent * h) {
+ return h->h_addrtype;
+}
+
+int __gnat_hostent_h_length (struct hostent * h) {
+ return h->h_length;
+}
+
+char * __gnat_hostent_h_addr (struct hostent * h, int index) {
+ return h->h_addr_list[index];
+}
+
+/*
* Accessor functions for struct servent.
*
* These are needed because servent has different representations on different
@@ -539,21 +669,19 @@ __gnat_inet_pton (int af, const char *src, void *dst) {
* };
*/
-/* Getters */
-
char *
__gnat_servent_s_name (struct servent * s)
{
return s->s_name;
}
-char **
-__gnat_servent_s_aliases (struct servent * s)
+char *
+__gnat_servent_s_alias (struct servent * s, int index)
{
- return s->s_aliases;
+ return s->s_aliases[index];
}
-int
+unsigned short
__gnat_servent_s_port (struct servent * s)
{
return s->s_port;
@@ -565,32 +693,6 @@ __gnat_servent_s_proto (struct servent * s)
return s->s_proto;
}
-/* Setters */
-
-void
-__gnat_servent_set_s_name (struct servent * s, char * s_name)
-{
- s->s_name = s_name;
-}
-
-void
-__gnat_servent_set_s_aliases (struct servent * s, char ** s_aliases)
-{
- s->s_aliases = s_aliases;
-}
-
-void
-__gnat_servent_set_s_port (struct servent * s, int s_port)
-{
- s->s_port = s_port;
-}
-
-void
-__gnat_servent_set_s_proto (struct servent * s, char * s_proto)
-{
- s->s_proto = s_proto;
-}
-
#else
# warning Sockets are not supported on this platform
#endif /* defined(HAVE_SOCKETS) */