1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
/* SPDX-FileCopyrightText: 2014-2023 Greenbone AG
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
/**
* @file
* @brief Implementation of an API to set process title.
*/
#include "proctitle.h"
#include <glib.h> /* for g_free, g_malloc0, g_strdup */
#include <stdio.h>
#include <string.h> /* for strlen, strdup, bzero, strncpy */
#include <sys/param.h>
#include <sys/prctl.h>
#undef G_LOG_DOMAIN
/**
* @brief GLib log domain.
*/
#define G_LOG_DOMAIN "libgvm base"
/**
* @brief Access to the executable's name.
*/
extern const char *__progname;
#ifndef __FreeBSD__
extern const char *__progname_full;
#endif
static char **old_argv;
static int old_argc;
extern char **environ;
void *current_environ = NULL;
static int max_prog_name = 0;
/**
* @brief Initializes the process setting variables.
*
* @param[in] argc Argc argument from main.
* @param[in] argv Argv argument from main.
*/
void
proctitle_init (int argc, char **argv)
{
int i;
char **envp = environ;
#ifndef __FreeBSD__
char *new_progname, *new_progname_full;
#else
char *new_progname;
#endif
old_argc = argc;
if (argv == NULL)
return;
// according to c99 argv is defined as when argc is set it follows program
// parameter. Since we will override on set_proctitle we know that this
// memory is modifiable.
// Everything after that is unsafe and can lead to segmentation faults.
// Therefore we iterate through argv and append strlen to gather the maximum
// safe program name.
for (i = 0; i < argc; i++)
{
max_prog_name += strlen (argv[i]) + 1;
}
i = 0;
new_progname = strdup (__progname);
#ifndef __FreeBSD__
new_progname_full = strdup (__progname_full);
#endif
/* Move environ to new memory, to be able to reuse older one. */
while (envp[i])
i++;
environ = g_malloc0 (sizeof (char *) * (i + 1));
if (current_environ)
g_free (current_environ);
current_environ = environ;
for (i = 0; envp[i]; i++)
environ[i] = g_strdup (envp[i]);
environ[i] = NULL;
old_argv = argv;
/* Seems like these are in the moved environment, so reset them. Idea from
* proctitle.cpp in KDE libs. */
__progname = new_progname;
#ifndef __FreeBSD__
__progname_full = new_progname_full;
#endif
}
/**
* @brief Sets the process' title.
*
* @param[in] new_title Format string for new process title.
* @param[in] args Format string arguments variable list.
*/
static void
proctitle_set_args (const char *new_title, va_list args)
{
char *formatted;
int tmp;
if (old_argv == NULL)
/* Called setproctitle before initproctitle ? */
return;
if (max_prog_name == 0)
// there may no program name set
return;
// omit previous additional parameter
formatted = g_strdup_vprintf (new_title, args);
tmp = strlen (formatted);
if (tmp >= max_prog_name)
{
formatted[max_prog_name] = '\0';
tmp = max_prog_name;
}
// set display name
memset (old_argv[0], 0, max_prog_name);
memcpy (old_argv[0], formatted, tmp);
g_free (formatted);
if (old_argc > 1)
old_argv[1] = NULL;
}
/**
* @brief Sets the process' title.
*
* @param[in] new_title Format string for new process title.
* @param[in] ... Arguments for format string.
*/
void
proctitle_set (const char *new_title, ...)
{
va_list args;
va_start (args, new_title);
proctitle_set_args (new_title, args);
va_end (args);
}
|