@@ -39,10 +39,6 @@
#include "net/slirp.h"
#include "qemu-options.h"
-#ifdef CONFIG_LINUX
-#include <sys/prctl.h>
-#endif
-
#ifdef CONFIG_EVENTFD
#include <sys/eventfd.h>
#endif
@@ -149,20 +145,32 @@ char *os_find_datadir(const char *argv0)
#undef SHARE_SUFFIX
#undef BUILD_SUFFIX
-void os_set_proc_name(const char *s)
+void os_set_proc_name(int argc, char **argv, const char *name)
{
-#if defined(PR_SET_NAME)
- char name[16];
- if (!s)
+#ifdef CONFIG_LINUX
+ char prctl_name[16], *last_argv_byte, *p;
+ int len, i;
+
+ if (!name)
return;
- name[sizeof(name) - 1] = 0;
- strncpy(name, s, sizeof(name));
- /* Could rewrite argv[0] too, but that's a bit more complicated.
- This simple way is enough for `top'. */
- if (prctl(PR_SET_NAME, name)) {
+
+#if defined(PR_SET_NAME)
+ strncpy(prctl_name, name, sizeof(prctl_name));
+ if (prctl(PR_SET_NAME, prctl_name)) {
perror("unable to change process name");
exit(1);
}
+#endif
+
+ last_argv_byte = argv[argc - 1] + strlen(argv[argc - 1]);
+
+ len = snprintf(argv[0], last_argv_byte - argv[0], "%s", name);
+
+ p = &argv[0][len];
+ while (p <= last_argv_byte)
+ *p++ = '\0';
+ for (i = 1; i < argc; ++i)
+ argv[i] = (char *) "";
#else
fprintf(stderr, "Change of process name not supported by your OS\n");
exit(1);
@@ -31,7 +31,7 @@ static inline void os_host_main_loop_wait(int *timeout)
}
void os_set_line_buffering(void);
-void os_set_proc_name(const char *s);
+void os_set_proc_name(int argc, char **argv, const char *name);
void os_setup_signal_handling(void);
void os_daemonize(void);
void os_setup_post(void);
@@ -46,7 +46,8 @@ static inline void os_setup_signal_handling(void) {}
static inline void os_daemonize(void) {}
static inline void os_setup_post(void) {}
void os_set_line_buffering(void);
-static inline void os_set_proc_name(const char *dummy) {}
+static inline void os_set_proc_name(int argc, char **argv,
+ const char *dummy) {}
#if !defined(EPROTONOSUPPORT)
# define EPROTONOSUPPORT EINVAL
@@ -1776,7 +1776,11 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
optarg = NULL;
}
- *poptarg = optarg;
+ if (optarg != NULL) {
+ *poptarg = qemu_strdup(optarg);
+ } else {
+ *poptarg = NULL;
+ }
*poptind = optind;
return popt;
@@ -1804,6 +1808,7 @@ int main(int argc, char **argv, char **envp)
int tb_size;
const char *pid_file = NULL;
const char *incoming = NULL;
+ const char *process_name = NULL;
int show_vnc_port = 0;
int defconfig = 1;
@@ -2497,7 +2502,7 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
p += 8;
- os_set_proc_name(p);
+ process_name = p;
}
}
break;
@@ -2723,6 +2728,8 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
+ os_set_proc_name(argc, argv, process_name);
+
if (kvm_allowed) {
int ret = kvm_init(smp_cpus);
if (ret < 0) {
Linux seems to maintain the length of the original args, even when the new args are shorter and NULL-terminated, so the trailing whitespace in ps(1) output is probably unavoidable. I've seen the same result with other daemons that overwrite argv. Keeps the call to prctl(), since some tools get the process name from /proc/PID/status. Signed-off-by: John Morrissey <jwm@horde.net> --- os-posix.c | 34 +++++++++++++++++++++------------- qemu-os-posix.h | 2 +- qemu-os-win32.h | 3 ++- vl.c | 11 +++++++++-- 4 files changed, 33 insertions(+), 17 deletions(-)