return 0;
}
-int rename_process(const char name[]) {
+int rename_process_full(const char *comm, const char *invocation) {
bool truncated = false;
- /* This is a like a poor man's setproctitle(). It changes the comm field, argv[0], and also the glibc's
- * internally used name of the process. For the first one a limit of 16 chars applies; to the second one in
- * many cases one of 10 (i.e. length of "/sbin/init") — however if we have CAP_SYS_RESOURCES it is unbounded;
- * to the third one 7 (i.e. the length of "systemd". If you pass a longer string it will likely be
- * truncated.
+ /* This is a like a poor man's setproctitle(). It changes the comm field by the name specified by
+ * 'comm', and changes argv[0] and the glibc's internally used names of the process
+ * (program_invocation_name and program_invocation_short_name) by the name specified by 'invocation'.
+ * For the first one a limit of 16 chars applies; to the second one in many cases one of 10 (i.e.
+ * length of "/sbin/init") — however if we have CAP_SYS_RESOURCES it is unbounded; to the third one
+ * 7 (i.e. the length of "systemd". If you pass a longer string it will likely be truncated.
*
* Returns 0 if a name was set but truncated, > 0 if it was set but not truncated. */
- if (isempty(name))
+ if (isempty(comm))
return -EINVAL; /* let's not confuse users unnecessarily with an empty name */
if (!is_main_thread())
* cache things without locking, and we make assumptions that PR_SET_NAME sets the
* process name that isn't correct on any other threads */
- size_t l = strlen(name);
+ size_t l = strlen(comm);
/* First step, change the comm field. The main thread's comm is identical to the process comm. This means we
* can use PR_SET_NAME, which sets the thread name for the calling thread. */
- if (prctl(PR_SET_NAME, name) < 0)
+ if (prctl(PR_SET_NAME, comm) < 0)
log_debug_errno(errno, "PR_SET_NAME failed: %m");
if (l >= TASK_COMM_LEN) /* Linux userspace process names can be 15 chars at max */
truncated = true;
+ /* If nothing specified, fall back to comm. */
+ if (isempty(invocation))
+ invocation = comm;
+
+ l = strlen(invocation);
+
/* Second step, change glibc's ID of the process name. */
if (program_invocation_name) {
size_t k;
k = strlen(program_invocation_name);
- strncpy(program_invocation_name, name, k);
+ strncpy(program_invocation_name, invocation, k);
if (l > k)
truncated = true;
/* Third step, completely replace the argv[] array the kernel maintains for us. This requires privileges, but
* has the advantage that the argv[] array is exactly what we want it to be, and not filled up with zeros at
* the end. This is the best option for changing /proc/self/cmdline. */
- (void) update_argv(name, l);
+ (void) update_argv(invocation, l);
/* Fourth step: in all cases we'll also update the original argv[], so that our own code gets it right too if
* it still looks here */
size_t k;
k = strlen(saved_argv[0]);
- strncpy(saved_argv[0], name, k);
+ strncpy(saved_argv[0], invocation, k);
if (l > k)
truncated = true;
}
}
static void rename_process_from_path(const char *path) {
- _cleanup_free_ char *buf = NULL;
- const char *p;
+ int r;
assert(path);
- /* This resulting string must fit in 10 chars (i.e. the length of "/sbin/init") to look pretty in
- * /bin/ps */
-
- if (path_extract_filename(path, &buf) < 0) {
- rename_process("(...)");
- return;
+ _cleanup_free_ char *buf = NULL;
+ r = path_extract_filename(path, &buf);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to extract file name from '%s', ignoring: %m", path);
+ return (void) rename_process("(...)");
}
- size_t l = strlen(buf);
- if (l > 8) {
- /* The end of the process name is usually more interesting, since the first bit might just be
- * "systemd-" */
- p = buf + l - 8;
- l = 8;
- } else
- p = buf;
+ size_t len = strlen(buf);
+ char comm[TASK_COMM_LEN], *p = comm;
+ *p++ = '(';
+ p = mempcpy(p, buf + LESS_BY(len, (size_t) (TASK_COMM_LEN - 3)), MIN(len, (size_t) (TASK_COMM_LEN - 3)));
+ *p++ = ')';
+ *p = '\0';
- char process_name[11];
- process_name[0] = '(';
- memcpy(process_name+1, p, l);
- process_name[1+l] = ')';
- process_name[1+l+1] = 0;
+ size_t len_invocation = program_invocation_name ? strlen(program_invocation_name) : SIZE_MAX;
+ _cleanup_free_ char *invocation = strjoin("(", buf + LESS_BY(len, len_invocation - 2), ")");
+ if (!invocation)
+ log_oom_debug();
- (void) rename_process(process_name);
+ (void) rename_process_full(comm, invocation ?: comm);
}
static bool context_has_address_families(const ExecContext *c) {