diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-03-31 19:10:49 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-04-01 03:29:29 +0200 |
commit | e82c950997fd1c8f7eb1cea881cb35387321af3d (patch) | |
tree | 09f796de2e0211490c0f9b0482300a1a2f17dd66 /src/libsystemd-bus/bus-socket.c | |
parent | 7989e1f2d79891ff73dea0ede1c98c47b62547db (diff) |
bus: allow two different fds for input/output in sd_bus_set_fd()
This is useful so that we can speak D-Bus over a FIFO pair such as
stdin+stdout.
Diffstat (limited to 'src/libsystemd-bus/bus-socket.c')
-rw-r--r-- | src/libsystemd-bus/bus-socket.c | 61 |
1 files changed, 35 insertions, 26 deletions
diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index fed1971ec7..9d08674bf7 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -88,7 +88,7 @@ static int bus_socket_write_auth(sd_bus *b) { mh.msg_iov = b->auth_iovec + b->auth_index; mh.msg_iovlen = ELEMENTSOF(b->auth_iovec) - b->auth_index; - k = sendmsg(b->fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL); + k = sendmsg(b->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL); if (k < 0) return errno == EAGAIN ? 0 : -errno; @@ -463,7 +463,7 @@ static int bus_socket_read_auth(sd_bus *b) { mh.msg_control = &control; mh.msg_controllen = sizeof(control); - k = recvmsg(b->fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC); + k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC); if (k < 0) return errno == EAGAIN ? 0 : -errno; if (k == 0) @@ -515,12 +515,12 @@ static int bus_socket_setup(sd_bus *b) { /* Enable SO_PASSCRED + SO_PASSEC. We try this on any * socket, just in case. */ enable = !b->bus_client; - setsockopt(b->fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable)); - setsockopt(b->fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable)); + setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable)); + setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable)); /* Increase the buffers to a MB */ - fd_inc_rcvbuf(b->fd, 1024*1024); - fd_inc_sndbuf(b->fd, 1024*1024); + fd_inc_rcvbuf(b->input_fd, 1024*1024); + fd_inc_sndbuf(b->output_fd, 1024*1024); return 0; } @@ -577,13 +577,17 @@ static int bus_socket_start_auth(sd_bus *b) { b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT; sl = sizeof(domain); - r = getsockopt(b->fd, SOL_SOCKET, SO_DOMAIN, &domain, &sl); - if (r < 0) - return -errno; - - if (domain != AF_UNIX) + r = getsockopt(b->input_fd, SOL_SOCKET, SO_DOMAIN, &domain, &sl); + if (r < 0 || domain != AF_UNIX) b->negotiate_fds = false; + if (b->output_fd != b->input_fd) { + r = getsockopt(b->output_fd, SOL_SOCKET, SO_DOMAIN, &domain, &sl); + if (r < 0 || domain != AF_UNIX) + b->negotiate_fds = false; + } + + if (b->is_server) return bus_socket_read_auth(b); else @@ -594,18 +598,21 @@ int bus_socket_connect(sd_bus *b) { int r; assert(b); - assert(b->fd < 0); + assert(b->input_fd < 0); + assert(b->output_fd < 0); assert(b->sockaddr.sa.sa_family != AF_UNSPEC); - b->fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); - if (b->fd < 0) + b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (b->input_fd < 0) return -errno; + b->output_fd = b->input_fd; + r = bus_socket_setup(b); if (r < 0) return r; - r = connect(b->fd, &b->sockaddr.sa, b->sockaddr_size); + r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size); if (r < 0) { if (errno == EINPROGRESS) return 1; @@ -617,15 +624,16 @@ int bus_socket_connect(sd_bus *b) { } int bus_socket_exec(sd_bus *b) { - int s[2]; + int s[2], r; pid_t pid; assert(b); - assert(b->fd < 0); + assert(b->input_fd < 0); + assert(b->output_fd < 0); assert(b->exec_path); - b->fd = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s); - if (b->fd < 0) + r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s); + if (r < 0) return -errno; pid = fork(); @@ -636,8 +644,9 @@ int bus_socket_exec(sd_bus *b) { if (pid == 0) { /* Child */ - close_all_fds(s, 2); - close_nointr_nofail(s[0]); + reset_all_signal_handlers(); + + close_all_fds(s+1, 1); assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO); assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO); @@ -661,7 +670,7 @@ int bus_socket_exec(sd_bus *b) { } close_nointr_nofail(s[1]); - b->fd = s[0]; + b->output_fd = b->input_fd = s[0]; return bus_socket_start_auth(b); } @@ -714,7 +723,7 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) { mh.msg_iov = iov; mh.msg_iovlen = m->n_iovec; - k = sendmsg(bus->fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL); + k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL); if (k < 0) return errno == EAGAIN ? 0 : -errno; @@ -854,7 +863,7 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) { mh.msg_control = &control; mh.msg_controllen = sizeof(control); - k = recvmsg(bus->fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC); + k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC); if (k < 0) return errno == EAGAIN ? 0 : -errno; if (k == 0) @@ -924,7 +933,7 @@ int bus_socket_process_opening(sd_bus *b) { assert(b->state == BUS_OPENING); zero(p); - p.fd = b->fd; + p.fd = b->output_fd; p.events = POLLOUT; r = poll(&p, 1, 0); @@ -934,7 +943,7 @@ int bus_socket_process_opening(sd_bus *b) { if (!(p.revents & (POLLOUT|POLLERR|POLLHUP))) return 0; - r = getsockopt(b->fd, SOL_SOCKET, SO_ERROR, &error, &slen); + r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen); if (r < 0) b->last_connect_error = errno; else if (error != 0) |