int os_socketpair_cloexec(int domain, int type, int protocol, int *sv) { int ret; #ifdef SOCK_CLOEXEC ret = socketpair(domain, type | SOCK_CLOEXEC, protocol, sv); if (ret == 0 || errno != EINVAL) return ret; #endif ret = socketpair(domain, type, protocol, sv); if (ret < 0) return ret; sv[0] = set_cloexec_or_close(sv[0]); sv[1] = set_cloexec_or_close(sv[1]); if (sv[0] != -1 && sv[1] != -1) return 0; close(sv[0]); close(sv[1]); return -1; }
static ssize_t recvmsg_cloexec_fallback(int sockfd, struct msghdr *msg, int flags) { ssize_t len; struct cmsghdr *cmsg; unsigned char *data; int *fd; int *end; len = recvmsg(sockfd, msg, flags); if (len == -1) return -1; if (!msg->msg_control || msg->msg_controllen == 0) return len; cmsg = CMSG_FIRSTHDR(msg); for (; cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) continue; data = CMSG_DATA(cmsg); end = (int *)(data + cmsg->cmsg_len - CMSG_LEN(0)); for (fd = (int *)data; fd < end; ++fd) *fd = set_cloexec_or_close(*fd); } return len; }
int uwac_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); }
int uwac_os_socket_cloexec(int domain, int type, int protocol) { int fd; fd = socket(domain, type | SOCK_CLOEXEC, protocol); if (fd >= 0) return fd; if (errno != EINVAL) return -1; fd = socket(domain, type, protocol); return set_cloexec_or_close(fd); }
int uwac_os_epoll_create_cloexec(void) { int fd; #ifdef EPOLL_CLOEXEC fd = epoll_create1(EPOLL_CLOEXEC); if (fd >= 0) return fd; if (errno != EINVAL) return -1; #endif fd = epoll_create(1); return set_cloexec_or_close(fd); }
int wl_os_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { int fd; #ifdef HAVE_ACCEPT4 fd = accept4(sockfd, addr, addrlen, SOCK_CLOEXEC); if (fd >= 0) return fd; if (errno != ENOSYS) return -1; #endif fd = accept(sockfd, addr, addrlen); return set_cloexec_or_close(fd); }
static int create_tmpfile_cloexec(char *tmpname) { int fd; #ifdef HAVE_MKOSTEMP fd = mkostemp(tmpname, O_CLOEXEC); if (fd >= 0) unlink(tmpname); #else fd = mkstemp(tmpname); if (fd >= 0) { fd = set_cloexec_or_close(fd); unlink(tmpname); } #endif return fd; }