From 260f524a9e97f15bb26a9704630e2953785c3cbc Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Tue, 4 Feb 2025 17:33:06 +0000 Subject: [PATCH] daemon: Change process title to show status Signed-off-by: Michael Tremer --- Makefile.am | 2 + src/cli/pakfire-daemon.c | 6 +++ src/pakfire/daemon.c | 11 ++++ src/pakfire/job.c | 9 ++++ src/pakfire/proctitle.c | 110 +++++++++++++++++++++++++++++++++++++++ src/pakfire/proctitle.h | 28 ++++++++++ 6 files changed, 166 insertions(+) create mode 100644 src/pakfire/proctitle.c create mode 100644 src/pakfire/proctitle.h diff --git a/Makefile.am b/Makefile.am index c02ca54e..7b4cf9b2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -271,6 +271,8 @@ libpakfire_la_SOURCES = \ src/pakfire/path.h \ src/pakfire/problem.c \ src/pakfire/problem.h \ + src/pakfire/proctitle.c \ + src/pakfire/proctitle.h \ src/pakfire/progress.c \ src/pakfire/progress.h \ src/pakfire/pty.c \ diff --git a/src/cli/pakfire-daemon.c b/src/cli/pakfire-daemon.c index a818a302..c8072b73 100644 --- a/src/cli/pakfire-daemon.c +++ b/src/cli/pakfire-daemon.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "lib/command.h" #include "lib/daemon.h" @@ -64,6 +65,11 @@ int main(int argc, char* argv[]) { struct pakfire_ctx* ctx = NULL; int r; + // Initialize changing the process title + r = pakfire_proctitle_init(argc, argv); + if (r < 0) + goto ERROR; + // Setup the context r = pakfire_ctx_create(&ctx, NULL); if (r) diff --git a/src/pakfire/daemon.c b/src/pakfire/daemon.c index e2e65d08..25c4dbe7 100644 --- a/src/pakfire/daemon.c +++ b/src/pakfire/daemon.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -632,6 +633,11 @@ static int pakfire_daemon_connected(struct pakfire_xfer* xfer, void* data) { DEBUG(daemon->ctx, "Connected!\n"); + // Update the process title + r = pakfire_proctitle_set("pakfire-daemon: Connected\n"); + if (r < 0) + return r; + // Store a reference to the control connection daemon->control = pakfire_xfer_ref(xfer); @@ -666,6 +672,11 @@ static int pakfire_daemon_connect(sd_event_source* s, uint64_t usec, void* data) DEBUG(daemon->ctx, "Connecting...\n"); + // Update the process title + r = pakfire_proctitle_set("pakfire-daemon: Connecting...\n"); + if (r < 0) + return r; + // Fetch the distro const struct pakfire_distro* distro = pakfire_ctx_get_distro(daemon->ctx); diff --git a/src/pakfire/job.c b/src/pakfire/job.c index 170e4ef8..ea7d9225 100644 --- a/src/pakfire/job.c +++ b/src/pakfire/job.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -632,6 +633,14 @@ static int pakfire_job_child(struct pakfire_job* job) { if (r < 0) goto ERROR; + // Set the process title + r = pakfire_proctitle_set("Job: %s (%s)", job->name, job->id); + if (r < 0) { + ERROR(job->ctx, "Failed to set process name: %m\n"); + r = -errno; + goto ERROR; + } + // Replace the context with a new one r = pakfire_ctx_create(&ctx, NULL); if (r < 0) { diff --git a/src/pakfire/proctitle.c b/src/pakfire/proctitle.c new file mode 100644 index 00000000..e68ebf4c --- /dev/null +++ b/src/pakfire/proctitle.c @@ -0,0 +1,110 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2025 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#include +#include +#include + +#include +#include + +extern char** environ; + +static char** argv0 = NULL; +static size_t argv0_length = 0; + +int pakfire_proctitle_init(int argc, char** argv) { + char** e = NULL; + size_t length = 0; + int r; + + // Count the length of the current environment + length = pakfire_strings_length(environ); + + // Allocate a new environment + e = calloc(length + 1, sizeof(*e)); + if (!e) + return -errno; + + // Copy the entire environment + for (unsigned int i = 0; i < length; i++) { + e[i] = strdup(environ[i]); + + // Fail if we could not copy + if (!e[i]) { + r = -errno; + goto ERROR; + } + } + + // Determine how much space we have for a new process title + if (length > 0) { + argv0_length = environ[length - 1] + strlen(environ[length - 1]) + 1 - argv[0]; + } else { + argv0_length = argv[argc - 1] + strlen(argv[argc - 1]) + 1 - argv[0]; + } + + // If there is some space, we remember the start address + if (!argv0_length) { + r = -ENOBUFS; + goto ERROR; + } + + // Replace the environment + environ = e; + + // Store argv + argv0 = argv; + + return 0; + +ERROR: + if (e) + pakfire_strings_free(e); + + return r; +} + +int pakfire_proctitle_set(const char* format, ...) { + char buffer[2048]; + va_list args; + int r; + + // Ensure argv0 is initialized + if (!argv0 || !argv0_length) + return -ENOTSUP; + + va_start(args, format); + r = pakfire_string_vformat(buffer, format, args); + va_end(args); + if (r < 0) + return r; + + // Truncate the buffer + pakfire_string_truncate(buffer, argv0_length - 1); + + // Copy the new content + memcpy(argv0[0], buffer, strlen(buffer) + 1); + + // Reset any other arguments + argv0[1] = NULL; + + return 0; +} diff --git a/src/pakfire/proctitle.h b/src/pakfire/proctitle.h new file mode 100644 index 00000000..43b34ebf --- /dev/null +++ b/src/pakfire/proctitle.h @@ -0,0 +1,28 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2025 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#ifndef PAKFIRE_SETPROCTITLE_H +#define PAKFIRE_SETPROCTITLE_H + +int pakfire_proctitle_init(int argc, char** argv); + +int pakfire_proctitle_set(const char* format, ...) __attribute__((format(printf, 1, 2)));; + +#endif /* PAKFIRE_SETPROCTITLE_H */ -- 2.39.5