diff options
author | Thomas Haller <thaller@redhat.com> | 2023-08-18 10:38:40 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2023-08-18 11:04:17 (GMT) |
commit | 40578a6299adde3c55e46423e8dbb0e8448c76ad (patch) | |
tree | 4626c6e153a9d9e1b6ea6e563f97b32f0bb2251c /lib | |
parent | 8ee8b05ff59999fd88b8a6faae40e7777ccf8c98 (diff) | |
download | libnl-40578a6299adde3c55e46423e8dbb0e8448c76ad.zip libnl-40578a6299adde3c55e46423e8dbb0e8448c76ad.tar.gz libnl-40578a6299adde3c55e46423e8dbb0e8448c76ad.tar.bz2 |
lib: use getprotobyname_r(), getprotobynumber_r() if available
Avoid non-threadsafe libc API.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/utils.c | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/lib/utils.c b/lib/utils.c index 04bbe81..5281c41 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -128,6 +128,57 @@ struct trans_list { struct nl_list_head list; }; +int nl_getprotobyname(const char *name) +{ + const struct protoent *result; + +#if HAVE_DECL_GETPROTOBYNAME_R + struct protoent result_buf; + char buf[2048]; + int r; + + r = getprotobyname_r(name, &result_buf, buf, sizeof(buf), + (struct protoent **)&result); + if (r != 0 || result != &result_buf) + result = NULL; +#else + result = getprotobyname(name); +#endif + + if (!result) + return -1; + + if (result->p_proto < 0 || result->p_proto > UINT8_MAX) + return -1; + return (uint8_t)result->p_proto; +} + +bool nl_getprotobynumber(int proto, char *out_name, size_t name_len) +{ + const struct protoent *result; + +#if HAVE_DECL_GETPROTOBYNUMBER_R + struct protoent result_buf; + char buf[2048]; + int r; + + r = getprotobynumber_r(proto, &result_buf, buf, sizeof(buf), + (struct protoent **)&result); + if (r != 0 || result != &result_buf) + result = NULL; +#else + result = getprotobynumber(proto); +#endif + + if (!result) + return false; + + if (strlen(result->p_name) >= name_len) + return false; + strcpy(out_name, result->p_name); + return true; +} + const char *nl_strerror_l(int err) { const char *buf; @@ -870,12 +921,8 @@ int nl_str2ether_proto(const char *name) char *nl_ip_proto2str(int proto, char *buf, size_t len) { - struct protoent *p = getprotobynumber(proto); - - if (p) { - snprintf(buf, len, "%s", p->p_name); + if (nl_getprotobynumber(proto, buf, len)) return buf; - } snprintf(buf, len, "0x%x", proto); return buf; @@ -883,12 +930,16 @@ char *nl_ip_proto2str(int proto, char *buf, size_t len) int nl_str2ip_proto(const char *name) { - struct protoent *p = getprotobyname(name); unsigned long l; char *end; + int p; + + if (!name) + return -NLE_INVAL; - if (p) - return p->p_proto; + p = nl_getprotobyname(name); + if (p >= 0) + return p; l = strtoul(name, &end, 0); if (name == end || *end != '\0' || l > (unsigned long)INT_MAX) |