hurd: unbreak build on GNU/Hurd (#3450)
The GNU/Hurd platform does not define IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_SOURCE_MEMBERSHIP, MCAST_JOIN_SOURCE_GROUP and MCAST_LEAVE_SOURCE_GROUP. Implement a few functions for the GNU/Hurd. Specifically: * uv_resident_set_memory (from Linux) * uv_get_free_memory (from Linux) * uv_get_total_memory (from Linux) * uv_cpu_info (from cygwin) * uv__process_title_cleanup (void) * uv_get_constrained_memory (stub) * Leave proctitle unimplemented on Hurd for now * Implement hurdish uv_exepath * Enable ifaddrs api * Unbreak udp basics * Unbreak futime and lutime on Hurd
This commit is contained in:
parent
f3e0bffcb1
commit
7ae0c9543d
@ -258,6 +258,17 @@ if(APPLE)
|
||||
src/unix/fsevents.c)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "GNU")
|
||||
list(APPEND uv_libraries dl)
|
||||
list(APPEND uv_sources
|
||||
src/unix/bsd-ifaddrs.c
|
||||
src/unix/no-fsevents.c
|
||||
src/unix/no-proctitle.c
|
||||
src/unix/posix-hrtime.c
|
||||
src/unix/posix-poll.c
|
||||
src/unix/hurd.c)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
list(APPEND uv_defines _GNU_SOURCE _POSIX_C_SOURCE=200112)
|
||||
list(APPEND uv_libraries dl rt)
|
||||
|
||||
@ -455,9 +455,12 @@ endif
|
||||
|
||||
if HURD
|
||||
uvinclude_HEADERS += include/uv/posix.h
|
||||
libuv_la_SOURCES += src/unix/no-fsevents.c \
|
||||
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
||||
src/unix/no-fsevents.c \
|
||||
src/unix/no-proctitle.c \
|
||||
src/unix/posix-hrtime.c \
|
||||
src/unix/posix-poll.c
|
||||
src/unix/posix-poll.c \
|
||||
src/unix/hurd.c
|
||||
endif
|
||||
|
||||
if LINUX
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
*/
|
||||
#include "uv.h"
|
||||
|
||||
/* Copies up to |n-1| bytes from |d| to |s| and always zero-terminates
|
||||
/* Copies up to |n-1| bytes from |s| to |d| and always zero-terminates
|
||||
* the result, except when |n==0|. Returns the number of bytes copied
|
||||
* or UV_E2BIG if |d| is too small.
|
||||
*
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#if !defined(__CYGWIN__) && !defined(__MSYS__)
|
||||
#if !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__GNU__)
|
||||
#include <net/if_dl.h>
|
||||
#endif
|
||||
|
||||
@ -40,7 +40,7 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
|
||||
return 1;
|
||||
if (ent->ifa_addr == NULL)
|
||||
return 1;
|
||||
#if !defined(__CYGWIN__) && !defined(__MSYS__)
|
||||
#if !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__GNU__)
|
||||
/*
|
||||
* If `exclude_type` is `UV__EXCLUDE_IFPHYS`, return whether `sa_family`
|
||||
* equals `AF_LINK`. Otherwise, the result depends on the operating
|
||||
@ -69,7 +69,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
struct ifaddrs* addrs;
|
||||
struct ifaddrs* ent;
|
||||
uv_interface_address_t* address;
|
||||
#if !(defined(__CYGWIN__) || defined(__MSYS__))
|
||||
#if !(defined(__CYGWIN__) || defined(__MSYS__)) && !defined(__GNU__)
|
||||
int i;
|
||||
#endif
|
||||
|
||||
@ -126,7 +126,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
address++;
|
||||
}
|
||||
|
||||
#if !(defined(__CYGWIN__) || defined(__MSYS__))
|
||||
#if !(defined(__CYGWIN__) || defined(__MSYS__)) && !defined(__GNU__)
|
||||
/* Fill in physical addresses for each interface */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS))
|
||||
|
||||
@ -1037,6 +1037,32 @@ int uv__open_cloexec(const char* path, int flags) {
|
||||
}
|
||||
|
||||
|
||||
int uv__slurp(const char* filename, char* buf, size_t len) {
|
||||
ssize_t n;
|
||||
int fd;
|
||||
|
||||
assert(len > 0);
|
||||
|
||||
fd = uv__open_cloexec(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
do
|
||||
n = read(fd, buf, len - 1);
|
||||
while (n == -1 && errno == EINTR);
|
||||
|
||||
if (uv__close_nocheckstdio(fd))
|
||||
abort();
|
||||
|
||||
if (n < 0)
|
||||
return UV__ERR(errno);
|
||||
|
||||
buf[n] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__dup2_cloexec(int oldfd, int newfd) {
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__linux__)
|
||||
int r;
|
||||
|
||||
@ -247,7 +247,8 @@ UV_UNUSED(static struct timeval uv__fs_to_timeval(double time)) {
|
||||
static ssize_t uv__fs_futime(uv_fs_t* req) {
|
||||
#if defined(__linux__) \
|
||||
|| defined(_AIX71) \
|
||||
|| defined(__HAIKU__)
|
||||
|| defined(__HAIKU__) \
|
||||
|| defined(__GNU__)
|
||||
struct timespec ts[2];
|
||||
ts[0] = uv__fs_to_timespec(req->atime);
|
||||
ts[1] = uv__fs_to_timespec(req->mtime);
|
||||
@ -1168,7 +1169,8 @@ static ssize_t uv__fs_lutime(uv_fs_t* req) {
|
||||
#if defined(__linux__) || \
|
||||
defined(_AIX71) || \
|
||||
defined(__sun) || \
|
||||
defined(__HAIKU__)
|
||||
defined(__HAIKU__) || \
|
||||
defined(__GNU__)
|
||||
struct timespec ts[2];
|
||||
ts[0] = uv__fs_to_timespec(req->atime);
|
||||
ts[1] = uv__fs_to_timespec(req->mtime);
|
||||
|
||||
167
src/unix/hurd.c
Normal file
167
src/unix/hurd.c
Normal file
@ -0,0 +1,167 @@
|
||||
/* Copyright libuv project 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.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <hurd.h>
|
||||
#include <hurd/process.h>
|
||||
#include <mach/task_info.h>
|
||||
#include <mach/vm_statistics.h>
|
||||
#include <mach/vm_param.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
int uv_exepath(char* buffer, size_t* size) {
|
||||
kern_return_t err;
|
||||
/* XXX in current Hurd, strings are char arrays of 1024 elements */
|
||||
string_t exepath;
|
||||
ssize_t copied;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (*size - 1 > 0) {
|
||||
/* XXX limited length of buffer in current Hurd, this API will probably
|
||||
* evolve in the future */
|
||||
err = proc_get_exe(getproc(), getpid(), exepath);
|
||||
|
||||
if (err)
|
||||
return UV__ERR(err);
|
||||
}
|
||||
|
||||
copied = uv__strscpy(buffer, exepath, *size);
|
||||
|
||||
/* do not return error on UV_E2BIG failure */
|
||||
*size = copied < 0 ? strlen(buffer) : (size_t) copied;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv_resident_set_memory(size_t* rss) {
|
||||
kern_return_t err;
|
||||
struct task_basic_info bi;
|
||||
mach_msg_type_number_t count;
|
||||
|
||||
count = TASK_BASIC_INFO_COUNT;
|
||||
err = task_info(mach_task_self(), TASK_BASIC_INFO,
|
||||
(task_info_t) &bi, &count);
|
||||
|
||||
if (err)
|
||||
return UV__ERR(err);
|
||||
|
||||
*rss = bi.resident_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t uv_get_free_memory(void) {
|
||||
kern_return_t err;
|
||||
struct vm_statistics vmstats;
|
||||
|
||||
err = vm_statistics(mach_task_self(), &vmstats);
|
||||
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
return vmstats.free_count * vm_page_size;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_total_memory(void) {
|
||||
kern_return_t err;
|
||||
host_basic_info_data_t hbi;
|
||||
mach_msg_type_number_t cnt;
|
||||
|
||||
cnt = HOST_BASIC_INFO_COUNT;
|
||||
err = host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t) &hbi, &cnt);
|
||||
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
return hbi.memory_size;
|
||||
}
|
||||
|
||||
|
||||
int uv_uptime(double* uptime) {
|
||||
char buf[128];
|
||||
|
||||
/* Try /proc/uptime first */
|
||||
if (0 == uv__slurp("/proc/uptime", buf, sizeof(buf)))
|
||||
if (1 == sscanf(buf, "%lf", uptime))
|
||||
return 0;
|
||||
|
||||
/* Reimplement here code from procfs to calculate uptime if not mounted? */
|
||||
|
||||
return UV__ERR(EIO);
|
||||
}
|
||||
|
||||
void uv_loadavg(double avg[3]) {
|
||||
char buf[128]; /* Large enough to hold all of /proc/loadavg. */
|
||||
|
||||
if (0 == uv__slurp("/proc/loadavg", buf, sizeof(buf)))
|
||||
if (3 == sscanf(buf, "%lf %lf %lf", &avg[0], &avg[1], &avg[2]))
|
||||
return;
|
||||
|
||||
/* Reimplement here code from procfs to calculate loadavg if not mounted? */
|
||||
}
|
||||
|
||||
|
||||
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
||||
kern_return_t err;
|
||||
host_basic_info_data_t hbi;
|
||||
mach_msg_type_number_t cnt;
|
||||
|
||||
/* Get count of cpus */
|
||||
cnt = HOST_BASIC_INFO_COUNT;
|
||||
err = host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t) &hbi, &cnt);
|
||||
|
||||
if (err) {
|
||||
err = UV__ERR(err);
|
||||
goto abort;
|
||||
}
|
||||
|
||||
/* XXX not implemented on the Hurd */
|
||||
*cpu_infos = uv__calloc(hbi.avail_cpus, sizeof(**cpu_infos));
|
||||
if (*cpu_infos == NULL) {
|
||||
err = UV_ENOMEM;
|
||||
goto abort;
|
||||
}
|
||||
|
||||
*count = hbi.avail_cpus;
|
||||
|
||||
return 0;
|
||||
|
||||
abort:
|
||||
*cpu_infos = NULL;
|
||||
*count = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
}
|
||||
@ -242,6 +242,7 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
int uv__accept(int sockfd);
|
||||
int uv__dup2_cloexec(int oldfd, int newfd);
|
||||
int uv__open_cloexec(const char* path, int flags);
|
||||
int uv__slurp(const char* filename, char* buf, size_t len);
|
||||
|
||||
/* tcp */
|
||||
int uv__tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
|
||||
|
||||
@ -211,31 +211,6 @@ err:
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
static int uv__slurp(const char* filename, char* buf, size_t len) {
|
||||
ssize_t n;
|
||||
int fd;
|
||||
|
||||
assert(len > 0);
|
||||
|
||||
fd = uv__open_cloexec(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
do
|
||||
n = read(fd, buf, len - 1);
|
||||
while (n == -1 && errno == EINTR);
|
||||
|
||||
if (uv__close_nocheckstdio(fd))
|
||||
abort();
|
||||
|
||||
if (n < 0)
|
||||
return UV__ERR(errno);
|
||||
|
||||
buf[n] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv_uptime(double* uptime) {
|
||||
static volatile int no_clock_boottime;
|
||||
char buf[128];
|
||||
@ -243,7 +218,7 @@ int uv_uptime(double* uptime) {
|
||||
int r;
|
||||
|
||||
/* Try /proc/uptime first, then fallback to clock_gettime(). */
|
||||
|
||||
|
||||
if (0 == uv__slurp("/proc/uptime", buf, sizeof(buf)))
|
||||
if (1 == sscanf(buf, "%lf", uptime))
|
||||
return 0;
|
||||
|
||||
@ -495,7 +495,7 @@ static int uv__set_reuse(int fd) {
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
|
||||
return UV__ERR(errno);
|
||||
}
|
||||
#elif defined(SO_REUSEPORT) && !defined(__linux__)
|
||||
#elif defined(SO_REUSEPORT) && !defined(__linux__) && !defined(__GNU__)
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
|
||||
return UV__ERR(errno);
|
||||
#else
|
||||
@ -928,7 +928,8 @@ static int uv__udp_set_membership6(uv_udp_t* handle,
|
||||
!defined(__NetBSD__) && \
|
||||
!defined(__ANDROID__) && \
|
||||
!defined(__DragonFly__) && \
|
||||
!defined(__QNX__)
|
||||
!defined(__QNX__) && \
|
||||
!defined(__GNU__)
|
||||
static int uv__udp_set_source_membership4(uv_udp_t* handle,
|
||||
const struct sockaddr_in* multicast_addr,
|
||||
const char* interface_addr,
|
||||
@ -1120,7 +1121,8 @@ int uv_udp_set_source_membership(uv_udp_t* handle,
|
||||
!defined(__NetBSD__) && \
|
||||
!defined(__ANDROID__) && \
|
||||
!defined(__DragonFly__) && \
|
||||
!defined(__QNX__)
|
||||
!defined(__QNX__) && \
|
||||
!defined(__GNU__)
|
||||
int err;
|
||||
union uv__sockaddr mcast_addr;
|
||||
union uv__sockaddr src_addr;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user