From d5b26154f7a99b3a1725b5c68276b0d6750cdc98 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 17 Nov 2011 18:00:51 +0100 Subject: [PATCH] linux: improve kernel feature detection Do not check for minimum kernel and glibc versions, just check that the kernel headers export the syscall number and invoke the syscall directly. Effectively bypasses glibc. --- src/unix/core.c | 4 +-- src/unix/internal.h | 71 +++++++++++++++++++++++++++++++++++---------- src/unix/process.c | 4 +-- 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/unix/core.c b/src/unix/core.c index 4d832413..ac005694 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -727,8 +727,8 @@ int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t slen) { assert(sockfd >= 0); while (1) { -#if HAVE_ACCEPT4 - peerfd = accept4(sockfd, saddr, &slen, SOCK_NONBLOCK | SOCK_CLOEXEC); +#if HAVE_SYS_ACCEPT4 + peerfd = sys_accept4(sockfd, saddr, &slen, SOCK_NONBLOCK | SOCK_CLOEXEC); if (peerfd != -1) break; diff --git a/src/unix/internal.h b/src/unix/internal.h index 12ab6217..4784bcf8 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h @@ -28,30 +28,69 @@ #include /* offsetof */ #undef HAVE_FUTIMES -#undef HAVE_PIPE2 -#undef HAVE_ACCEPT4 #undef HAVE_KQUEUE #undef HAVE_PORTS_FS #if defined(__linux__) -#include -#include +# undef HAVE_SYS_UTIMESAT +# undef HAVE_SYS_PIPE2 +# undef HAVE_SYS_ACCEPT4 -/* futimes() requires linux >= 2.6.22 and glib >= 2.6 */ -#if LINUX_VERSION_CODE >= 0x20616 && __GLIBC_PREREQ(2, 6) -#define HAVE_FUTIMES 1 -#endif +# undef _GNU_SOURCE +# define _GNU_SOURCE -/* pipe2() requires linux >= 2.6.27 and glibc >= 2.9 */ -#if LINUX_VERSION_CODE >= 0x2061B && __GLIBC_PREREQ(2, 9) -#define HAVE_PIPE2 1 -#endif +# include +# include +# include +# include -/* accept4() requires linux >= 2.6.28 and glib >= 2.10 */ -#if LINUX_VERSION_CODE >= 0x2061C && __GLIBC_PREREQ(2, 10) -#define HAVE_ACCEPT4 1 -#endif +# if __NR_utimensat +# define HAVE_SYS_UTIMESAT 1 +# endif +# if __NR_pipe2 +# define HAVE_SYS_PIPE2 1 +# endif +# if __NR_accept4 +# define HAVE_SYS_ACCEPT4 1 +# endif + +# if HAVE_SYS_UTIMESAT +inline static int sys_utimesat(int dirfd, + const char* path, + const struct timespec times[2], + int flags) +{ + return syscall(__NR_utimensat, dirfd, path, times, flags); +} +inline static int sys_futimes(int fd, const struct timeval times[2]) +{ + struct timespec ts[2]; + ts[0].tv_sec = times[0].tv_sec, ts[0].tv_nsec = times[0].tv_usec * 1000; + ts[1].tv_sec = times[1].tv_sec, ts[1].tv_nsec = times[1].tv_usec * 1000; + return sys_utimesat(fd, NULL, ts, 0); +} +# undef HAVE_FUTIMES +# define HAVE_FUTIMES 1 +# define futimes(fd, times) sys_futimes(fd, times) +# endif /* HAVE_SYS_FUTIMESAT */ + +# if HAVE_SYS_PIPE2 +inline static int sys_pipe2(int pipefd[2], int flags) +{ + return syscall(__NR_pipe2, pipefd, flags); +} +# endif /* HAVE_SYS_PIPE2 */ + +# if HAVE_SYS_ACCEPT4 +inline static int sys_accept4(int fd, + struct sockaddr* addr, + socklen_t* addrlen, + int flags) +{ + return syscall(__NR_accept4, fd, addr, addrlen, flags); +} +# endif /* HAVE_SYS_ACCEPT4 */ #endif /* __linux__ */ diff --git a/src/unix/process.c b/src/unix/process.c index c5a45929..5581d8b8 100644 --- a/src/unix/process.c +++ b/src/unix/process.c @@ -104,7 +104,7 @@ static int uv__make_socketpair(int fds[2], int flags) { static int uv__make_pipe(int fds[2], int flags) { -#if HAVE_PIPE2 +#if HAVE_SYS_PIPE2 int fl; fl = O_CLOEXEC; @@ -112,7 +112,7 @@ static int uv__make_pipe(int fds[2], int flags) { if (flags & UV__F_NONBLOCK) fl |= O_NONBLOCK; - if (pipe2(fds, fl) == 0) + if (sys_pipe2(fds, fl) == 0) return 0; if (errno != ENOSYS)