30 #if defined(__clang__)
31 #pragma clang diagnostic push
32 #pragma clang diagnostic ignored "-Wreserved-id-macro"
37 #if defined(__clang__)
38 #pragma clang diagnostic pop
41 #if defined(__FreeBSD__) || defined(__DragonFly__)
46 #if !defined(O_TMPFILE) && !defined(__FreeBSD__)
47 #define O_TMPFILE (020000000 | O_DIRECTORY)
50 #include <sys/types.h>
51 #include <sys/socket.h>
61 #include <sys/epoll.h>
63 #include <uwac/config.h>
66 #include "uwac-utils.h"
68 static int set_cloexec_or_close(
int fd)
75 flags = fcntl(fd, F_GETFD);
80 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
89 int uwac_os_socket_cloexec(
int domain,
int type,
int protocol)
92 fd = socket(domain, type | SOCK_CLOEXEC, protocol);
100 fd = socket(domain, type, protocol);
101 return set_cloexec_or_close(fd);
104 int uwac_os_dupfd_cloexec(
int fd,
long minfd)
107 newfd = fcntl(fd, F_DUPFD_CLOEXEC, minfd);
115 newfd = fcntl(fd, F_DUPFD, minfd);
116 return set_cloexec_or_close(newfd);
119 static ssize_t recvmsg_cloexec_fallback(
int sockfd,
struct msghdr* msg,
int flags)
122 struct cmsghdr* cmsg = NULL;
123 unsigned char* data = NULL;
125 len = recvmsg(sockfd, msg, flags);
130 if (!msg->msg_control || msg->msg_controllen == 0)
133 cmsg = CMSG_FIRSTHDR(msg);
135 for (; cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg))
137 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS)
140 data = CMSG_DATA(cmsg);
141 end = (
int*)(data + cmsg->cmsg_len - CMSG_LEN(0));
143 for (
int* fd = (
int*)data; fd < end; ++fd)
144 *fd = set_cloexec_or_close(*fd);
150 ssize_t uwac_os_recvmsg_cloexec(
int sockfd,
struct msghdr* msg,
int flags)
153 len = recvmsg(sockfd, msg, flags | MSG_CMSG_CLOEXEC);
161 return recvmsg_cloexec_fallback(sockfd, msg, flags);
164 int uwac_os_epoll_create_cloexec(
void)
168 fd = epoll_create1(EPOLL_CLOEXEC);
177 fd = epoll_create(1);
178 return set_cloexec_or_close(fd);
181 static int create_tmpfile_cloexec(
char* tmpname)
185 fd = shm_open(SHM_ANON, O_CREAT | O_RDWR, 0600);
186 #elif defined(UWAC_HAVE_MKOSTEMP)
187 fd = mkostemp(tmpname, O_CLOEXEC);
193 fd = mkstemp(tmpname);
197 fd = set_cloexec_or_close(fd);
226 int uwac_create_anonymous_file(off_t size)
228 static const char template[] =
"/weston-shared-XXXXXX";
231 const char* path = NULL;
234 path = getenv(
"XDG_RUNTIME_DIR");
243 fd = open(path, O_TMPFILE | O_RDWR | O_EXCL, 0600);
255 length = strlen(path) +
sizeof(
template);
256 name = xmalloc(length);
261 (void)snprintf(name, length,
"%s%s", path,
template);
262 fd = create_tmpfile_cloexec(name);
269 #ifdef UWAC_HAVE_POSIX_FALLOCATE
270 ret = posix_fallocate(fd, 0, size);
280 ret = ftruncate(fd, size);