unix,win: add uv_os_gethostname()
Fixes: https://github.com/libuv/libuv/issues/1315 PR-URL: https://github.com/libuv/libuv/pull/1342 Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
This commit is contained in:
parent
4d0054145d
commit
d8cd08bd98
@ -178,6 +178,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-get-memory.c \
|
||||
test/test-get-passwd.c \
|
||||
test/test-getaddrinfo.c \
|
||||
test/test-gethostname.c \
|
||||
test/test-getnameinfo.c \
|
||||
test/test-getsockname.c \
|
||||
test/test-handle-fileno.c \
|
||||
|
||||
@ -104,6 +104,7 @@ test/test-get-loadavg.c
|
||||
test/test-get-memory.c
|
||||
test/test-get-passwd.c
|
||||
test/test-getaddrinfo.c
|
||||
test/test-gethostname.c
|
||||
test/test-getsockname.c
|
||||
test/test-homedir.c
|
||||
test/test-hrtime.c
|
||||
|
||||
@ -429,3 +429,14 @@ API
|
||||
This function is not thread safe.
|
||||
|
||||
.. versionadded:: 1.12.0
|
||||
|
||||
.. c:function:: int uv_os_gethostname(char* buffer, size_t* size)
|
||||
|
||||
Returns the hostname as a null-terminated string in `buffer`, and sets
|
||||
`size` to the string length of the hostname. When calling this function,
|
||||
`size` must be set to the amount of storage available in `buffer`, including
|
||||
the null terminator. If the hostname exceeds the storage available in
|
||||
`buffer`, `UV_ENOBUFS` is returned, and `size` is set to the amount of
|
||||
storage required to hold the value.
|
||||
|
||||
.. versionadded:: 1.12.0
|
||||
|
||||
@ -1078,6 +1078,8 @@ UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size);
|
||||
UV_EXTERN int uv_os_setenv(const char* name, const char* value);
|
||||
UV_EXTERN int uv_os_unsetenv(const char* name);
|
||||
|
||||
UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size);
|
||||
|
||||
|
||||
typedef enum {
|
||||
UV_FS_UNKNOWN = -1,
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h> /* MAXHOSTNAMELEN on Linux and the BSDs */
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@ -42,6 +43,7 @@
|
||||
#include <pwd.h>
|
||||
|
||||
#ifdef __sun
|
||||
# include <netdb.h> /* MAXHOSTNAMELEN on Solaris */
|
||||
# include <sys/filio.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/wait.h>
|
||||
@ -80,6 +82,11 @@
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
/* Fallback for the maximum hostname length */
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
# define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
static int uv__run_pending(uv_loop_t* loop);
|
||||
|
||||
/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
|
||||
@ -1285,3 +1292,33 @@ int uv_os_unsetenv(const char* name) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_os_gethostname(char* buffer, size_t* size) {
|
||||
/*
|
||||
On some platforms, if the input buffer is not large enough, gethostname()
|
||||
succeeds, but truncates the result. libuv can detect this and return ENOBUFS
|
||||
instead by creating a large enough buffer and comparing the hostname length
|
||||
to the size input.
|
||||
*/
|
||||
char buf[MAXHOSTNAMELEN + 1];
|
||||
size_t len;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (gethostname(buf, sizeof(buf)) != 0)
|
||||
return -errno;
|
||||
|
||||
buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */
|
||||
len = strlen(buf);
|
||||
|
||||
if (len >= *size) {
|
||||
*size = len + 1;
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
memcpy(buffer, buf, len + 1);
|
||||
*size = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -59,6 +59,14 @@
|
||||
# define UNLEN 256
|
||||
#endif
|
||||
|
||||
/*
|
||||
Max hostname length. The Windows gethostname() documentation states that 256
|
||||
bytes will always be large enough to hold the null-terminated hostname.
|
||||
*/
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
# define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
/* Maximum environment variable size, including the terminating null */
|
||||
#define MAX_ENV_VAR_LENGTH 32767
|
||||
|
||||
@ -1540,3 +1548,29 @@ int uv_os_unsetenv(const char* name) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_os_gethostname(char* buffer, size_t* size) {
|
||||
char buf[MAXHOSTNAMELEN + 1];
|
||||
size_t len;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
uv__once_init(); /* Initialize winsock */
|
||||
|
||||
if (gethostname(buf, sizeof(buf)) != 0)
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
|
||||
buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */
|
||||
len = strlen(buf);
|
||||
|
||||
if (len >= *size) {
|
||||
*size = len + 1;
|
||||
return UV_ENOBUFS;
|
||||
}
|
||||
|
||||
memcpy(buffer, buf, len + 1);
|
||||
*size = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
62
test/test-gethostname.c
Normal file
62
test/test-gethostname.c
Normal file
@ -0,0 +1,62 @@
|
||||
/* Copyright libuv contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
# define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
TEST_IMPL(gethostname) {
|
||||
char buf[MAXHOSTNAMELEN + 1];
|
||||
size_t size;
|
||||
size_t enobufs_size;
|
||||
int r;
|
||||
|
||||
/* Reject invalid inputs */
|
||||
size = 1;
|
||||
r = uv_os_gethostname(NULL, &size);
|
||||
ASSERT(r == UV_EINVAL);
|
||||
r = uv_os_gethostname(buf, NULL);
|
||||
ASSERT(r == UV_EINVAL);
|
||||
size = 0;
|
||||
r = uv_os_gethostname(buf, &size);
|
||||
ASSERT(r == UV_EINVAL);
|
||||
|
||||
/* Return UV_ENOBUFS if the buffer cannot hold the hostname */
|
||||
enobufs_size = 1;
|
||||
buf[0] = '\0';
|
||||
r = uv_os_gethostname(buf, &enobufs_size);
|
||||
ASSERT(r == UV_ENOBUFS);
|
||||
ASSERT(buf[0] == '\0');
|
||||
ASSERT(enobufs_size > 1);
|
||||
|
||||
/* Successfully get the hostname */
|
||||
size = MAXHOSTNAMELEN + 1;
|
||||
r = uv_os_gethostname(buf, &size);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(size > 1 && size == strlen(buf));
|
||||
ASSERT(size + 1 == enobufs_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -220,6 +220,7 @@ TEST_DECLARE (getaddrinfo_fail_sync)
|
||||
TEST_DECLARE (getaddrinfo_basic)
|
||||
TEST_DECLARE (getaddrinfo_basic_sync)
|
||||
TEST_DECLARE (getaddrinfo_concurrent)
|
||||
TEST_DECLARE (gethostname)
|
||||
TEST_DECLARE (getnameinfo_basic_ip4)
|
||||
TEST_DECLARE (getnameinfo_basic_ip4_sync)
|
||||
TEST_DECLARE (getnameinfo_basic_ip6)
|
||||
@ -655,6 +656,8 @@ TASK_LIST_START
|
||||
TEST_ENTRY (getaddrinfo_basic_sync)
|
||||
TEST_ENTRY (getaddrinfo_concurrent)
|
||||
|
||||
TEST_ENTRY (gethostname)
|
||||
|
||||
TEST_ENTRY (getnameinfo_basic_ip4)
|
||||
TEST_ENTRY (getnameinfo_basic_ip4_sync)
|
||||
TEST_ENTRY (getnameinfo_basic_ip6)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user