[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnunet] branch master updated: service activation: properly use LISTEN_
From: |
Admin |
Subject: |
[gnunet] branch master updated: service activation: properly use LISTEN_FDNAMES as per modern systemd specification |
Date: |
Sun, 15 Jun 2025 14:45:20 +0200 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository gnunet.
The following commit(s) were added to refs/heads/master by this push:
new 17066b4f3 service activation: properly use LISTEN_FDNAMES as per
modern systemd specification
17066b4f3 is described below
commit 17066b4f30196866d7056b60c643e37849c3e958
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Jun 15 14:27:52 2025 +0200
service activation: properly use LISTEN_FDNAMES as per modern systemd
specification
---
src/lib/util/os_priority.c | 96 +++++++++++++++++++++++++++++++++++-----------
src/lib/util/service.c | 86 +++++++++++++++++++++++++++++++----------
2 files changed, 138 insertions(+), 44 deletions(-)
diff --git a/src/lib/util/os_priority.c b/src/lib/util/os_priority.c
index 35b230a6a..0c02feb5a 100644
--- a/src/lib/util/os_priority.c
+++ b/src/lib/util/os_priority.c
@@ -33,10 +33,11 @@
#define LOG(kind, ...) GNUNET_log_from (kind, "util-os-priority", __VA_ARGS__)
#define LOG_STRERROR(kind, syscall) \
- GNUNET_log_from_strerror (kind, "util-os-priority", syscall)
+ GNUNET_log_from_strerror (kind, "util-os-priority", syscall)
#define LOG_STRERROR_FILE(kind, syscall, filename) \
- GNUNET_log_from_strerror_file (kind, "util-os-priority", syscall, filename)
+ GNUNET_log_from_strerror_file (kind, "util-os-priority", syscall, \
+ filename)
#define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE"
@@ -443,8 +444,12 @@ start_process (enum GNUNET_OS_InheritStdioFlags
std_inheritance,
if (-1 == ret)
{
int eno = errno;
- LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
- GNUNET_array_grow (lscp, ls, 0);
+
+ LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
+ "fork");
+ GNUNET_array_grow (lscp,
+ ls,
+ 0);
if (NULL != childpipe_write)
GNUNET_DISK_file_close (childpipe_write);
if (0 <= childpipe_read_fd)
@@ -472,49 +477,65 @@ start_process (enum GNUNET_OS_InheritStdioFlags
std_inheritance,
/* due to vfork, we must NOT free memory on DARWIN! */
GNUNET_DISK_file_close (childpipe_write);
#endif
- snprintf (fdbuf, 100, "%x", childpipe_read_fd);
- setenv (GNUNET_OS_CONTROL_PIPE, fdbuf, 1);
+ snprintf (fdbuf,
+ sizeof (fdbuf),
+ "%x",
+ childpipe_read_fd);
+ setenv (GNUNET_OS_CONTROL_PIPE,
+ fdbuf,
+ 1);
}
else
unsetenv (GNUNET_OS_CONTROL_PIPE);
if (NULL != pipe_stdin)
{
GNUNET_break (0 == close (fd_stdin_write));
- if (-1 == dup2 (fd_stdin_read, 0))
- LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
+ if (-1 == dup2 (fd_stdin_read,
+ 0))
+ LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
+ "dup2");
GNUNET_break (0 == close (fd_stdin_read));
}
else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_IN))
{
GNUNET_break (0 == close (0));
- open_dev_null (0, O_RDONLY);
+ open_dev_null (0,
+ O_RDONLY);
}
if (NULL != pipe_stdout)
{
GNUNET_break (0 == close (fd_stdout_read));
- if (-1 == dup2 (fd_stdout_write, 1))
- LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
- GNUNET_break (0 == close (fd_stdout_write));
+ if (-1 == dup2 (fd_stdout_write,
+ 1))
+ LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
+ "dup2");
+ GNUNET_break (0 ==
+ close (fd_stdout_write));
}
else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_OUT))
{
GNUNET_break (0 == close (1));
- open_dev_null (1, O_WRONLY);
+ open_dev_null (1,
+ O_WRONLY);
}
if (NULL != pipe_stderr)
{
GNUNET_break (0 == close (fd_stderr_read));
- if (-1 == dup2 (fd_stderr_write, 2))
+ if (-1 == dup2 (fd_stderr_write,
+ 2))
LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
GNUNET_break (0 == close (fd_stderr_write));
}
else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_ERR))
{
GNUNET_break (0 == close (2));
- open_dev_null (2, O_WRONLY);
+ open_dev_null (2,
+ O_WRONLY);
}
if (NULL != lscp)
{
+ char *fdnames = GNUNET_strdup ("");
+
/* read systemd documentation... */
i = 0;
tgt = 3;
@@ -539,26 +560,55 @@ start_process (enum GNUNET_OS_InheritStdioFlags
std_inheritance,
/* Bury any existing FD, no matter what; they should all be closed
* on exec anyway and the important ones have been dup'ed away */
GNUNET_break (0 == close (tgt));
- GNUNET_assert (-1 != dup2 (lscp[i], tgt));
+ GNUNET_assert (-1 != dup2 (lscp[i],
+ tgt));
}
/* unset close-on-exec flag */
- flags = fcntl (tgt, F_GETFD);
+ flags = fcntl (tgt,
+ F_GETFD);
GNUNET_assert (flags >= 0);
flags &= ~FD_CLOEXEC;
fflush (stderr);
- (void) fcntl (tgt, F_SETFD, flags);
+ (void) fcntl (tgt,
+ F_SETFD,
+ flags);
+ {
+ char *tmp;
+
+ GNUNET_asprintf (&tmp,
+ "%s:%d",
+ fdnames,
+ tgt);
+ GNUNET_free (fdnames);
+ fdnames = tmp;
+ }
tgt++;
i++;
}
- GNUNET_snprintf (fds, sizeof(fds), "%u", i);
- setenv ("LISTEN_FDS", fds, 1);
+ GNUNET_snprintf (fds,
+ sizeof(fds),
+ "%u",
+ i);
+ setenv ("LISTEN_FDS",
+ fds,
+ 1);
+ if (0 != strlen (fdnames))
+ setenv ("LISTEN_FDNAMES",
+ fdnames + 1, /* skip leading ':' */
+ 1);
+ GNUNET_free (fdnames);
}
#ifndef DARWIN
/* due to vfork, we must NOT free memory on DARWIN! */
- GNUNET_array_grow (lscp, ls, 0);
+ GNUNET_array_grow (lscp,
+ ls,
+ 0);
#endif
- execvp (filename, argv);
- LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
+ execvp (filename,
+ argv);
+ LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR,
+ "execvp",
+ filename);
_exit (1);
}
diff --git a/src/lib/util/service.c b/src/lib/util/service.c
index ebb09584f..ac78e0f48 100644
--- a/src/lib/util/service.c
+++ b/src/lib/util/service.c
@@ -1480,9 +1480,10 @@ setup_service (const struct GNUNET_OS_ProjectData *pd,
struct GNUNET_NETWORK_Handle **csocks = NULL;
struct GNUNET_NETWORK_Handle **lsocks;
const char *nfds;
+ const char *fdns;
unsigned int cnt;
int flags;
- char dummy[2];
+ char dummy;
if (GNUNET_CONFIGURATION_have_value (sh->cfg,
sh->service_name,
@@ -1506,30 +1507,71 @@ setup_service (const struct GNUNET_OS_ProjectData *pd,
lsocks = NULL;
errno = 0;
if ( (NULL != (nfds = getenv ("LISTEN_FDS"))) &&
- (1 == sscanf (nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) &&
- (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE))
- {
- lsocks = GNUNET_new_array (cnt + 1, struct GNUNET_NETWORK_Handle *);
- while (0 < cnt--)
+ (NULL != (fdns = getenv ("LISTEN_FDNAMES"))) &&
+ (1 == sscanf (nfds,
+ "%u%c",
+ &cnt,
+ &dummy)) &&
+ (cnt > 0) &&
+ (cnt < FD_SETSIZE) )
+ {
+ char *fdnames;
+ unsigned int pos;
+
+ lsocks = GNUNET_new_array (cnt + 1,
+ struct GNUNET_NETWORK_Handle *);
+ fdnames = GNUNET_strdup (fdns);
+ pos = 0;
+ for (const char *tok = strtok (fdnames,
+ ":");
+ NULL != tok;
+ tok = strtok (NULL, ":"))
{
- flags = fcntl (3 + cnt, F_GETFD);
- if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
- (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
+ unsigned int fd;
+
+ if (pos == cnt)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "More than LISTEN_FDS sockets given in LISTEN_FDNAMES\n");
+ break;
+ }
+ if (1 != sscanf (tok,
+ "%u%c",
+ &fd,
+ &dummy))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Malformed socket given in LISTEN_FDNAMES than in
LISTEN_FDS\n");
+ break;
+ }
+ if (fd >= FD_SETSIZE)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Socket given in LISTEN_FDNAMES outside of select()able
range\n");
+ break;
+ }
+ flags = fcntl ((int) fd,
+ F_GETFD);
+ if ((flags < 0) ||
+ (0 != (flags & FD_CLOEXEC)) ||
+ (NULL == (lsocks[pos] = GNUNET_NETWORK_socket_box_native ((int)
fd))))
{
LOG (GNUNET_ERROR_TYPE_ERROR,
- _ (
- "Could not access pre-bound socket %u, will try to bind
myself\n"),
- (unsigned int) 3 + cnt);
- cnt++;
- while (NULL != lsocks[cnt])
- GNUNET_break (GNUNET_OK ==
- GNUNET_NETWORK_socket_close (lsocks[cnt++]));
- GNUNET_free (lsocks);
- lsocks = NULL;
+ "Could not access pre-bound socket %u\n",
+ fd);
break;
}
+ pos++;
+ }
+ if (0 == pos)
+ {
+ for (unsigned int i=0; i<cnt; i++)
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_NETWORK_socket_close (lsocks[i]));
+ GNUNET_free (lsocks);
}
unsetenv ("LISTEN_FDS");
+ cnt = pos;
}
if ( (0 != (GNUNET_SERVICE_OPTION_CLOSE_LSOCKS & sh->options)) &&
(NULL != lsocks) )
@@ -1560,7 +1602,10 @@ setup_service (const struct GNUNET_OS_ProjectData *pd,
socklen_t *addrlens;
int num;
- num = get_server_addresses (sh->service_name, sh->cfg, &addrs, &addrlens);
+ num = get_server_addresses (sh->service_name,
+ sh->cfg,
+ &addrs,
+ &addrlens);
if (GNUNET_SYSERR == num)
{
GNUNET_free (csocks);
@@ -1593,8 +1638,7 @@ setup_service (const struct GNUNET_OS_ProjectData *pd,
/* All attempts to bind failed, hard failure */
GNUNET_log (
GNUNET_ERROR_TYPE_ERROR,
- _ (
- "Could not bind to any of the ports I was supposed to, refusing to
run!\n"));
+ "Could not bind to any of the ports I was supposed to, refusing to
run!\n");
GNUNET_free (csocks);
return GNUNET_SYSERR;
}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnunet] branch master updated: service activation: properly use LISTEN_FDNAMES as per modern systemd specification,
Admin <=