ssize_t len;
struct sockaddr_un addr;
- fd = socket(PF_UNIX, type, 0);
+ fd = socket(PF_UNIX, type | SOCK_CLOEXEC, 0);
if (fd < 0)
return -1;
ssize_t len;
struct sockaddr_un addr;
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (fd < 0)
return -1;
return fd;
}
-int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
- void *data, size_t size)
+int lxc_abstract_unix_send_fds_iov(int fd, int *sendfds, int num_sendfds,
+ struct iovec *iov, size_t iovlen)
{
- __do_free char *cmsgbuf;
+ __do_free char *cmsgbuf = NULL;
+ int ret;
struct msghdr msg;
- struct iovec iov;
struct cmsghdr *cmsg = NULL;
- char buf[1] = {0};
size_t cmsgbufsize = CMSG_SPACE(num_sendfds * sizeof(int));
memset(&msg, 0, sizeof(msg));
- memset(&iov, 0, sizeof(iov));
cmsgbuf = malloc(cmsgbufsize);
if (!cmsgbuf) {
memcpy(CMSG_DATA(cmsg), sendfds, num_sendfds * sizeof(int));
- iov.iov_base = data ? data : buf;
- iov.iov_len = data ? size : sizeof(buf);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = iovlen;
- return sendmsg(fd, &msg, MSG_NOSIGNAL);
+again:
+ ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
+ if (ret < 0)
+ if (errno == EINTR)
+ goto again;
+
+ return ret;
}
-int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
+int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
void *data, size_t size)
{
- __do_free char *cmsgbuf;
+ char buf[1] = {0};
+ struct iovec iov = {
+ .iov_base = data ? data : buf,
+ .iov_len = data ? size : sizeof(buf),
+ };
+ return lxc_abstract_unix_send_fds_iov(fd, sendfds, num_sendfds, &iov,
+ 1);
+}
+
+int lxc_unix_send_fds(int fd, int *sendfds, int num_sendfds, void *data,
+ size_t size)
+{
+ return lxc_abstract_unix_send_fds(fd, sendfds, num_sendfds, data, size);
+}
+
+static int lxc_abstract_unix_recv_fds_iov(int fd, int *recvfds, int num_recvfds,
+ struct iovec *iov, size_t iovlen)
+{
+ __do_free char *cmsgbuf = NULL;
int ret;
struct msghdr msg;
- struct iovec iov;
struct cmsghdr *cmsg = NULL;
char buf[1] = {0};
size_t cmsgbufsize = CMSG_SPACE(sizeof(struct ucred)) +
CMSG_SPACE(num_recvfds * sizeof(int));
memset(&msg, 0, sizeof(msg));
- memset(&iov, 0, sizeof(iov));
cmsgbuf = malloc(cmsgbufsize);
if (!cmsgbuf) {
msg.msg_control = cmsgbuf;
msg.msg_controllen = cmsgbufsize;
- iov.iov_base = data ? data : buf;
- iov.iov_len = data ? size : sizeof(buf);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = iovlen;
+again:
ret = recvmsg(fd, &msg, 0);
- if (ret <= 0)
+ if (ret < 0) {
+ if (errno == EINTR)
+ goto again;
+
+ goto out;
+ }
+ if (ret == 0)
goto out;
/*
return ret;
}
+int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
+ void *data, size_t size)
+{
+ char buf[1] = {0};
+ struct iovec iov = {
+ .iov_base = data ? data : buf,
+ .iov_len = data ? size : sizeof(buf),
+ };
+ return lxc_abstract_unix_recv_fds_iov(fd, recvfds, num_recvfds, &iov, 1);
+}
+
int lxc_abstract_unix_send_credential(int fd, void *data, size_t size)
{
struct msghdr msg = {0};
int ret;
ssize_t len;
- fd = socket(PF_UNIX, SOCK_STREAM, SOCK_CLOEXEC);
- if (fd < 0)
+ fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ if (fd < 0) {
+ SYSERROR("Failed to open new AF_UNIX socket");
return -1;
+ }
if (addr->sun_path[0] == '\0')
len = strlen(&addr->sun_path[1]);
else
len = strlen(&addr->sun_path[0]);
- ret = connect(fd, (struct sockaddr *)&addr,
- offsetof(struct sockaddr_un, sun_path) + len + 1);
- if (ret < 0)
+
+ ret = connect(fd, (struct sockaddr *)addr,
+ offsetof(struct sockaddr_un, sun_path) + len);
+ if (ret < 0) {
+ SYSERROR("Failed to bind new AF_UNIX socket");
return -1;
+ }
return move_fd(fd);
}