diff options
author | Thomas Haller <thaller@redhat.com> | 2023-08-11 12:08:42 +0200 |
---|---|---|
committer | Philip Withnall <philip@tecnocode.co.uk> | 2023-08-14 09:32:43 +0100 |
commit | f738c7f3db761fc2ca9cf007b101dff516e77732 (patch) | |
tree | 434e1e308ca3db1115a37009f68a1786744de0c0 | |
parent | 8aa889dbf14b59047330951b56220046fc9c1f35 (diff) | |
download | glib-f738c7f3db761fc2ca9cf007b101dff516e77732.tar.gz |
gio: use reentrant getservbyname_r() if available
-rw-r--r-- | gio/gnetworkaddress.c | 7 | ||||
-rw-r--r-- | gio/gnetworking.c | 24 | ||||
-rw-r--r-- | gio/gnetworkingprivate.h | 2 | ||||
-rw-r--r-- | gio/gnetworkservice.c | 10 | ||||
-rw-r--r-- | meson.build | 18 |
5 files changed, 50 insertions, 11 deletions
diff --git a/gio/gnetworkaddress.c b/gio/gnetworkaddress.c index 598917de2..a4ee538af 100644 --- a/gio/gnetworkaddress.c +++ b/gio/gnetworkaddress.c @@ -486,10 +486,7 @@ g_network_address_parse (const gchar *host_and_port, else { - struct servent *entry; - - entry = getservbyname (port, "tcp"); - if (entry == NULL) + if (!g_getservbyname_ntohs (port, "tcp", &portnum)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Unknown service '%s' specified in hostname '%s'", @@ -501,8 +498,6 @@ g_network_address_parse (const gchar *host_and_port, return NULL; } - portnum = g_ntohs (entry->s_port); - #ifdef HAVE_ENDSERVENT endservent (); #endif diff --git a/gio/gnetworking.c b/gio/gnetworking.c index fa16238b3..d0c00c98c 100644 --- a/gio/gnetworking.c +++ b/gio/gnetworking.c @@ -23,6 +23,7 @@ #include "config.h" #include "gnetworking.h" +#include "gnetworkingprivate.h" /** * SECTION:gnetworking @@ -76,3 +77,26 @@ g_networking_init (void) } #endif } + +gboolean +g_getservbyname_ntohs (const char *name, const char *proto, guint16 *out_port) +{ + struct servent *result; + +#ifdef HAVE_GETSERVBYNAME_R + struct servent result_buf; + char buf[2048]; + int r; + + r = getservbyname_r (name, proto, &result_buf, buf, sizeof (buf), &result); + if (r != 0 || result != &result_buf) + result = NULL; +#else + result = getservbyname (name, proto); +#endif + + if (!result) + return FALSE; + *out_port = g_ntohs (result->s_port); + return TRUE; +} diff --git a/gio/gnetworkingprivate.h b/gio/gnetworkingprivate.h index f3bb227ee..88894e037 100644 --- a/gio/gnetworkingprivate.h +++ b/gio/gnetworkingprivate.h @@ -33,6 +33,8 @@ gint g_socket (gint domain, gint protocol, GError **error); +gboolean g_getservbyname_ntohs (const char *name, const char *proto, guint16 *out_port); + G_END_DECLS #endif /* __G_NETWORKINGPRIVATE_H__ */ diff --git a/gio/gnetworkservice.c b/gio/gnetworkservice.c index 8fa74eca3..dac0814d0 100644 --- a/gio/gnetworkservice.c +++ b/gio/gnetworkservice.c @@ -364,17 +364,17 @@ static GList * g_network_service_fallback_targets (GNetworkService *srv) { GSrvTarget *target; - struct servent *entry; + gboolean has_port; guint16 port; - entry = getservbyname (srv->priv->service, "tcp"); - port = entry ? g_ntohs (entry->s_port) : 0; + has_port = g_getservbyname_ntohs (srv->priv->service, "tcp", &port); + #ifdef HAVE_ENDSERVENT endservent (); #endif - if (entry == NULL) - return NULL; + if (!has_port) + return NULL; target = g_srv_target_new (srv->priv->domain, port, 0, 0); return g_list_append (NULL, target); diff --git a/meson.build b/meson.build index 3773ce9bc..bf872b63a 100644 --- a/meson.build +++ b/meson.build @@ -756,6 +756,24 @@ if cc.has_function('memalign', prefix: '#include <stdlib.h>\n#include <malloc.h> glib_conf.set('HAVE_MEMALIGN', 1) endif +# For example on Openbsd, getservbyname_r() has a different signature. +# https://man.openbsd.org/getservbyname.3 +if cc.compiles('''#include <netdb.h> + int main (int argc, char ** argv) { + int (*fcn)(const char *, + const char *, + struct servent *, + char *, + size_t, + struct servent **) = getservbyname_r; + (void) fcn; + return 0; + }''', + name : 'getservbyname_r()', + args: '-Werror=incompatible-pointer-types') + glib_conf.set('HAVE_GETSERVBYNAME_R', 1) +endif + if cc.has_function('_aligned_malloc', prefix: '#include <malloc.h>') glib_conf.set('HAVE__ALIGNED_MALLOC', 1) endif |