Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
linux: improve kernel feature detection
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bnoordhuis committed Nov 17, 2011
1 parent 4ae40b6 commit d5b2615
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/unix/core.c
Expand Up @@ -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;
Expand Down
71 changes: 55 additions & 16 deletions src/unix/internal.h
Expand Up @@ -28,30 +28,69 @@
#include <stddef.h> /* offsetof */

#undef HAVE_FUTIMES
#undef HAVE_PIPE2
#undef HAVE_ACCEPT4
#undef HAVE_KQUEUE
#undef HAVE_PORTS_FS

#if defined(__linux__)

#include <linux/version.h>
#include <features.h>
# 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 <linux/version.h>
# include <sys/syscall.h>
# include <features.h>
# include <unistd.h>

/* 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__ */

Expand Down
4 changes: 2 additions & 2 deletions src/unix/process.c
Expand Up @@ -104,15 +104,15 @@ 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;

if (flags & UV__F_NONBLOCK)
fl |= O_NONBLOCK;

if (pipe2(fds, fl) == 0)
if (sys_pipe2(fds, fl) == 0)
return 0;

if (errno != ENOSYS)
Expand Down

0 comments on commit d5b2615

Please sign in to comment.