]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/socket.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / core / socket.c
index d242b10758c294adc4b9b39c191a8a3c8861af83..cfa17b33257bf1cd8bd0ebfd8bce684939ee37f0 100644 (file)
@@ -48,6 +48,7 @@
 #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"
@@ -507,6 +508,8 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
                 "%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),
@@ -523,6 +526,8 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
                 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)
@@ -643,7 +648,8 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
                         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;
@@ -1025,19 +1031,17 @@ static int fifo_address_create(
 
 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;
 
@@ -1279,7 +1283,7 @@ static int socket_open_fds(Socket *s) {
 
                 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;
@@ -1502,6 +1506,9 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
                 .apply_chroot      = true,
                 .apply_tty_stdin   = true,
                 .bus_endpoint_fd   = -1,
+                .stdin_fd          = -1,
+                .stdout_fd         = -1,
+                .stderr_fd         = -1,
         };
 
         assert(s);
@@ -2627,49 +2634,43 @@ static int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *use
         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) {
@@ -2765,6 +2766,19 @@ static int socket_get_timeout(Unit *u, uint64_t *timeout) {
         return 1;
 }
 
+char *socket_fdname(Socket *s) {
+        assert(s);
+
+        /* 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",
         [SOCKET_EXEC_START_CHOWN] = "StartChown",