--- /dev/null
+#ifndef _DINIT_SOCKET_H_INCLUDED
+#define _DINIT_SOCKET_H_INCLUDED
+
+#include <sys/socket.h>
+#include <fcntl.h>
+
+namespace {
+#if !defined(SOCK_NONBLOCK) && !defined(SOCK_CLOEXEC)
+ // make our own accept4 on systems that don't have it:
+ constexpr int SOCK_NONBLOCK = 1;
+ constexpr int SOCK_CLOEXEC = 2;
+ inline int dinit_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
+ {
+ int fd = accept(sockfd, addr, addrlen);
+ if (fd == -1) {
+ return -1;
+ }
+
+ if (flags & SOCK_CLOEXEC) fcntl(fd, F_SETFD, FD_CLOEXEC);
+ if (flags & SOCK_NONBLOCK) fcntl(fd, F_SETFL, O_NONBLOCK);
+ return fd;
+ }
+
+ inline int dinit_socket(int domain, int type, int protocol, int flags)
+ {
+ int fd = socket(domain, type, protocol);
+ if (fd == -1) {
+ return -1;
+ }
+
+ if (flags & SOCK_CLOEXEC) fcntl(fd, F_SETFD, FD_CLOEXEC);
+ if (flags & SOCK_NONBLOCK) fcntl(fd, F_SETFL, O_NONBLOCK);
+ return fd;
+ }
+
+ inline int dinit_socketpair(int domain, int type, int protocol, int socket_vector[2], int flags)
+ {
+ int r = socketpair(domain, type, protocol, socket_vector);
+ if (r == -1) {
+ return -1;
+ }
+
+ if (flags & SOCK_CLOEXEC) {
+ fcntl(socket_vector[0], F_SETFD, FD_CLOEXEC);
+ fcntl(socket_vector[1], F_SETFD, FD_CLOEXEC);
+ }
+ if (flags & SOCK_NONBLOCK) {
+ fcntl(socket_vector[0], F_SETFL, O_NONBLOCK);
+ fcntl(socket_vector[1], F_SETFL, O_NONBLOCK);
+ }
+ return 0;
+ }
+
+#else
+ inline int dinit_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
+ {
+ return accept4(sockfd, addr, addrlen, flags);
+ }
+
+ inline int dinit_socket(int domain, int type, int protocol, int flags)
+ {
+ return socket(domain, type | flags, protocol);
+ }
+
+ inline int dinit_socketpair(int domain, int type, int protocol, int socket_vector[2], int flags)
+ {
+ return socketpair(domain, type | flags, protocol, socket_vector);
+ }
+#endif
+}
+
+#endif
#include "service.h"
#include "control.h"
#include "dinit-log.h"
+#include "dinit-socket.h"
#ifdef __linux__
#include <sys/klog.h>
// it once it falls below the maximum.
// Accept a connection
- int newfd = accept4(sockfd, nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC);
+ int newfd = dinit_accept4(sockfd, nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC);
if (newfd != -1) {
try {
// OpenBSD and Linux both allow combining NONBLOCK/CLOEXEC flags with socket type, however
// it's not actually POSIX. (TODO).
- int sockfd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
+ int sockfd = dinit_socket(AF_UNIX, SOCK_STREAM, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
if (sockfd == -1) {
log(LogLevel::ERROR, "Error creating control socket: ", strerror(errno));
free(name);
name->sun_family = AF_UNIX;
memcpy(name->sun_path, saddrname, saddrname_len + 1);
- int sockfd = socket(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
+ int sockfd = dinit_socket(AF_UNIX, SOCK_DGRAM, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
if (sockfd == -1) {
log(LogLevel::ERROR, "Error creating log socket: ", strerror(errno));
free(name);
#include "service.h"
#include "dinit-log.h"
+#include "dinit-socket.h"
/*
* service.cc - Service management.
name->sun_family = AF_UNIX;
strcpy(name->sun_path, saddrname);
- int sockfd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
+ int sockfd = dinit_socket(AF_UNIX, SOCK_STREAM, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
if (sockfd == -1) {
log(LogLevel::ERROR, service_name, ": Error creating activation socket: ", strerror(errno));
free(name);
int control_socket[2] = {-1, -1};
if (onstart_flags.pass_cs_fd) {
- if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, /* protocol */ 0, control_socket)) {
+ if (dinit_socketpair(AF_UNIX, SOCK_STREAM, /* protocol */ 0, control_socket, SOCK_NONBLOCK)) {
log(LogLevel::ERROR, service_name, ": can't create control socket: ", strerror(errno));
goto out_p;
}