#include "smack-util.h"
#include "socket.h"
#include "special.h"
+#include "string-util.h"
#include "strv.h"
#include "unit-name.h"
#include "unit-printf.h"
"%sPassSecurity: %s\n"
"%sTCPCongestion: %s\n"
"%sRemoveOnStop: %s\n"
+ "%sWritable: %s\n"
+ "%sFDName: %s\n"
"%sSELinuxContextFromNet: %s\n",
prefix, socket_state_to_string(s->state),
prefix, socket_result_to_string(s->result),
prefix, yes_no(s->pass_sec),
prefix, strna(s->tcp_congestion),
prefix, yes_no(s->remove_on_stop),
+ prefix, yes_no(s->writable),
+ prefix, socket_fdname(s),
prefix, yes_no(s->selinux_context_from_net));
if (s->control_pid > 0)
int r;
char *k = NULL;
- if ((r = socket_address_print(&p->address, &k)) < 0)
+ r = socket_address_print(&p->address, &k);
+ if (r < 0)
t = strerror(-r);
else
t = k;
fail:
mac_selinux_create_file_clear();
- safe_close(fd);
-
return r;
}
-static int special_address_create(const char *path) {
+static int special_address_create(const char *path, bool writable) {
_cleanup_close_ int fd = -1;
struct stat st;
int r;
assert(path);
- fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW);
+ fd = open(path, (writable ? O_RDWR : O_RDONLY)|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW);
if (fd < 0)
return -errno;
return r;
}
-static int ffs_address_create(const char *path) {
+static int usbffs_address_create(const char *path) {
_cleanup_close_ int fd = -1;
struct stat st;
int r;
return 0;
}
-static int ffs_write_descs(int fd, Service *s) {
+static int usbffs_write_descs(int fd, Service *s) {
int r;
if (!s->usb_function_descriptors || !s->usb_function_strings)
return copy_file_fd(s->usb_function_strings, fd, false);
}
-static int select_ep(const struct dirent *d) {
+static int usbffs_select_ep(const struct dirent *d) {
return d->d_name[0] != '.' && !streq(d->d_name, "ep0");
}
-static int ffs_dispatch_eps(SocketPort *p) {
+static int usbffs_dispatch_eps(SocketPort *p) {
_cleanup_free_ struct dirent **ent = NULL;
- int r, i, n, k;
_cleanup_free_ char *path = NULL;
+ int r, i, n, k;
r = path_get_parent(p->path, &path);
if (r < 0)
return r;
- r = scandir(path, &ent, select_ep, alphasort);
+ r = scandir(path, &ent, usbffs_select_ep, alphasort);
if (r < 0)
return -errno;
path_kill_slashes(ep);
- r = ffs_address_create(ep);
+ r = usbffs_address_create(ep);
if (r < 0)
goto fail;
}
static int socket_open_fds(Socket *s) {
+ _cleanup_(mac_selinux_freep) char *label = NULL;
+ bool know_label = false;
SocketPort *p;
int r;
- char *label = NULL;
- bool know_label = false;
assert(s);
if (p->fd >= 0)
continue;
- if (p->type == SOCKET_SOCKET) {
+ switch (p->type) {
+
+ case SOCKET_SOCKET:
if (!know_label) {
/* Figure out label, if we don't it know
p->fd = r;
socket_apply_socket_options(s, p->fd);
socket_symlink(s);
+ break;
- } else if (p->type == SOCKET_SPECIAL) {
+ case SOCKET_SPECIAL:
- p->fd = special_address_create(p->path);
+ p->fd = special_address_create(p->path, s->writable);
if (p->fd < 0) {
r = p->fd;
goto rollback;
}
+ break;
- } else if (p->type == SOCKET_FIFO) {
+ case SOCKET_FIFO:
p->fd = fifo_address_create(
p->path,
socket_apply_fifo_options(s, p->fd);
socket_symlink(s);
+ break;
- } else if (p->type == SOCKET_MQUEUE) {
+ case SOCKET_MQUEUE:
p->fd = mq_address_create(
p->path,
r = p->fd;
goto rollback;
}
+ break;
- } else if (p->type == SOCKET_USB_FUNCTION) {
+ case SOCKET_USB_FUNCTION:
- p->fd = ffs_address_create(p->path);
+ p->fd = usbffs_address_create(p->path);
if (p->fd < 0) {
r = p->fd;
goto rollback;
}
- r = ffs_write_descs(p->fd, SERVICE(UNIT_DEREF(s->service)));
+ r = usbffs_write_descs(p->fd, SERVICE(UNIT_DEREF(s->service)));
if (r < 0)
goto rollback;
- r = ffs_dispatch_eps(p);
+ r = usbffs_dispatch_eps(p);
if (r < 0)
goto rollback;
- } else
+
+ break;
+
+ default:
assert_not_reached("Unknown port type");
+ }
}
- mac_selinux_free(label);
return 0;
rollback:
socket_close_fds(s);
- mac_selinux_free(label);
-
return r;
}
.apply_chroot = true,
.apply_tty_stdin = true,
.bus_endpoint_fd = -1,
+ .stdin_fd = -1,
+ .stdout_fd = -1,
+ .stderr_fd = -1,
};
assert(s);
return 0;
}
-int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
- int *rfds;
- unsigned rn_fds, k;
- int i;
+int socket_collect_fds(Socket *s, int **fds) {
+ int *rfds, k = 0, n = 0;
SocketPort *p;
assert(s);
assert(fds);
- assert(n_fds);
/* Called from the service code for requesting our fds */
- rn_fds = 0;
LIST_FOREACH(port, p, s->ports) {
if (p->fd >= 0)
- rn_fds++;
- rn_fds += p->n_auxiliary_fds;
+ n++;
+ n += p->n_auxiliary_fds;
}
- if (rn_fds <= 0) {
+ if (n <= 0) {
*fds = NULL;
- *n_fds = 0;
return 0;
}
- rfds = new(int, rn_fds);
+ rfds = new(int, n);
if (!rfds)
return -ENOMEM;
- k = 0;
LIST_FOREACH(port, p, s->ports) {
+ int i;
+
if (p->fd >= 0)
rfds[k++] = p->fd;
for (i = 0; i < p->n_auxiliary_fds; ++i)
rfds[k++] = p->auxiliary_fds[i];
}
- assert(k == rn_fds);
+ assert(k == n);
*fds = rfds;
- *n_fds = rn_fds;
-
- return 0;
+ return n;
}
static void socket_reset_failed(Unit *u) {
return 1;
}
-static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
- [SOCKET_DEAD] = "dead",
- [SOCKET_START_PRE] = "start-pre",
- [SOCKET_START_CHOWN] = "start-chown",
- [SOCKET_START_POST] = "start-post",
- [SOCKET_LISTENING] = "listening",
- [SOCKET_RUNNING] = "running",
- [SOCKET_STOP_PRE] = "stop-pre",
- [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm",
- [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill",
- [SOCKET_STOP_POST] = "stop-post",
- [SOCKET_FINAL_SIGTERM] = "final-sigterm",
- [SOCKET_FINAL_SIGKILL] = "final-sigkill",
- [SOCKET_FAILED] = "failed"
-};
+char *socket_fdname(Socket *s) {
+ assert(s);
-DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState);
+ /* Returns the name to use for $LISTEN_NAMES. If the user
+ * didn't specify anything specifically, use the socket unit's
+ * name as fallback. */
+
+ if (s->fdname)
+ return s->fdname;
+
+ return UNIT(s)->id;
+}
static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
[SOCKET_EXEC_START_PRE] = "StartPre",