os: wrap F_DUPFD_CLOEXEC

Some system C libraries do not have F_DUPFD_CLOEXEC. Provide a fallback.

Add tests for the new wl_os_dupfd_cloexec() wrapper.

Add per-wrapper call counters in os_wrappers-test.c. Makes it easier to
determine the minimum required number of wrapped calls.

Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
This commit is contained in:
Pekka Paalanen 2012-04-23 13:55:55 +03:00
parent 3b29783dc8
commit 1463a41f89
4 changed files with 91 additions and 4 deletions

View file

@ -37,6 +37,7 @@
#include "wayland-util.h"
#include "wayland-private.h"
#include "wayland-os.h"
#define DIV_ROUNDUP(n, a) ( ((n) + ((a) - 1)) / (a) )
@ -518,7 +519,7 @@ wl_closure_vmarshal(struct wl_closure *closure,
extra += sizeof *fd_ptr;
fd = va_arg(ap, int);
dup_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
dup_fd = wl_os_dupfd_cloexec(fd, 0);
if (dup_fd < 0) {
fprintf(stderr, "dup failed: %m");
abort();

View file

@ -64,3 +64,18 @@ wl_os_socket_cloexec(int domain, int type, int protocol)
fd = socket(domain, type, protocol);
return set_cloexec_or_close(fd);
}
int
wl_os_dupfd_cloexec(int fd, long minfd)
{
int newfd;
newfd = fcntl(fd, F_DUPFD_CLOEXEC, minfd);
if (newfd >= 0)
return newfd;
if (errno != EINVAL)
return -1;
newfd = fcntl(fd, F_DUPFD, minfd);
return set_cloexec_or_close(newfd);
}

View file

@ -26,6 +26,9 @@
int
wl_os_socket_cloexec(int domain, int type, int protocol);
int
wl_os_dupfd_cloexec(int fd, long minfd);
/*
* The following are for wayland-os.c and the unit tests.
* Do not use them elsewhere.
@ -37,6 +40,10 @@ wl_os_socket_cloexec(int domain, int type, int protocol);
#define SOCK_CLOEXEC 02000000
#endif
#ifndef F_DUPFD_CLOEXEC
#define F_DUPFD_CLOEXEC 1030
#endif
#endif /* __linux__ */
#endif