2 * Original author : tridge@samba.org, January 2002
4 * Copyright (c) 2005 Christophe Varoqui
5 * Copyright (c) 2005 Alasdair Kergon, Redhat
12 #include <sys/ioctl.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
20 #include <systemd/sd-daemon.h>
28 * connect to a unix domain socket
30 int ux_socket_connect(const char *name)
33 struct sockaddr_un addr;
35 memset(&addr, 0, sizeof(addr));
36 addr.sun_family = AF_LOCAL;
37 addr.sun_path[0] = '\0';
38 len = strlen(name) + 1 + sizeof(sa_family_t);
39 strncpy(&addr.sun_path[1], name, len);
41 fd = socket(AF_LOCAL, SOCK_STREAM, 0);
43 condlog(3, "Couldn't create ux_socket, error %d", errno);
47 if (connect(fd, (struct sockaddr *)&addr, len) == -1) {
48 condlog(3, "Couldn't connect to ux_socket, error %d", errno);
57 * create a unix domain socket and start listening on it
58 * return a file descriptor open on the socket
60 int ux_socket_listen(const char *name)
66 struct sockaddr_un addr;
69 num = sd_listen_fds(0);
71 condlog(3, "sd_listen_fds returned %d fds", num);
73 } else if (num == 1) {
74 fd = SD_LISTEN_FDS_START + 0;
75 condlog(3, "using fd %d from sd_listen_fds", fd);
79 fd = socket(AF_LOCAL, SOCK_STREAM, 0);
81 condlog(3, "Couldn't create ux_socket, error %d", errno);
85 memset(&addr, 0, sizeof(addr));
86 addr.sun_family = AF_LOCAL;
87 addr.sun_path[0] = '\0';
88 len = strlen(name) + 1 + sizeof(sa_family_t);
89 strncpy(&addr.sun_path[1], name, len);
91 if (bind(fd, (struct sockaddr *)&addr, len) == -1) {
92 condlog(3, "Couldn't bind to ux_socket, error %d", errno);
97 if (listen(fd, 10) == -1) {
98 condlog(3, "Couldn't listen to ux_socket, error %d", errno);
106 * keep writing until it's all sent
108 size_t write_all(int fd, const void *buf, size_t len)
113 ssize_t n = write(fd, buf, len);
115 if ((errno == EINTR) || (errno == EAGAIN))
121 buf = n + (char *)buf;
129 * keep reading until its all read
131 ssize_t read_all(int fd, void *buf, size_t len, unsigned int timeout)
141 ret = poll(&pfd, 1, timeout);
144 } else if (ret < 0) {
148 } else if (!pfd.revents & POLLIN)
150 n = read(fd, buf, len);
152 if ((errno == EINTR) || (errno == EAGAIN))
158 buf = n + (char *)buf;
166 * send a packet in length prefix format
168 int send_packet(int fd, const char *buf, size_t len)
175 sigaddset(&set, SIGPIPE);
176 pthread_sigmask(SIG_BLOCK, &set, &old);
178 if (write_all(fd, &len, sizeof(len)) != sizeof(len))
180 if (!ret && write_all(fd, buf, len) != len)
183 /* And unblock it again */
184 pthread_sigmask(SIG_SETMASK, &old, NULL);
190 * receive a packet in length prefix format
192 int recv_packet(int fd, char **buf, size_t *len, unsigned int timeout)
196 ret = read_all(fd, len, sizeof(*len), timeout);
202 if (ret < sizeof(*len)) {
211 (*buf) = MALLOC(*len);
214 ret = read_all(fd, *buf, *len, timeout);
219 return ret < 0 ? ret : -EIO;