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.
Signed-off-by: John Morrissey <j...@horde.net> --- os-posix.c | 32 ++++++++++++++++---------------- qemu-os-posix.h | 2 +- qemu-os-win32.h | 3 ++- vl.c | 11 +++++++++-- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/os-posix.c b/os-posix.c index 38c29d1..3ddf7e8 100644 --- a/os-posix.c +++ b/os-posix.c @@ -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,24 @@ 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 *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)) { - perror("unable to change process name"); - exit(1); - } + + 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); diff --git a/qemu-os-posix.h b/qemu-os-posix.h index 353f878..b0cf993 100644 --- a/qemu-os-posix.h +++ b/qemu-os-posix.h @@ -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); diff --git a/qemu-os-win32.h b/qemu-os-win32.h index 1a07e5e..c618362 100644 --- a/qemu-os-win32.h +++ b/qemu-os-win32.h @@ -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 diff --git a/vl.c b/vl.c index c58583d..4b203cf 100644 --- a/vl.c +++ b/vl.c @@ -1772,7 +1772,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; @@ -1800,6 +1804,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; @@ -2493,7 +2498,7 @@ int main(int argc, char **argv, char **envp) exit(1); } p += 8; - os_set_proc_name(p); + process_name = p; } } break; @@ -2719,6 +2724,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) { -- 1.7.0.4