linux-user: fix /proc/self/stat handling
In the original bug report long files names in Guix caused /proc/self/stat be truncated without the trailing ") " as specified in proc manpage which says: (2) comm %s The filename of the executable, in parentheses. This is visible whether or not the executable is swapped out. In the kernel this is currently done by do_task_stat calling proc_task_name() which uses a structure limited by TASK_COMM_LEN (16). Additionally it should only be reporting the executable name rather than the full path. Fix both these failings while cleaning up the code to use GString to build up the reported values. As the whole function is cleaned up also adjust the white space to the current coding style. Message-ID: <fb4c55fa-d539-67ee-c6c9-de8fb63c8488@inria.fr> Reported-by: Brice Goglin <Brice.Goglin@inria.fr> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20200414200631.12799-10-alex.bennee@linaro.org>
This commit is contained in:
parent
469a788cdd
commit
7ad4d5a43e
|
@ -7295,32 +7295,27 @@ static int open_self_stat(void *cpu_env, int fd)
|
||||||
{
|
{
|
||||||
CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
|
CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
|
||||||
TaskState *ts = cpu->opaque;
|
TaskState *ts = cpu->opaque;
|
||||||
abi_ulong start_stack = ts->info->start_stack;
|
g_autoptr(GString) buf = g_string_new(NULL);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 44; i++) {
|
for (i = 0; i < 44; i++) {
|
||||||
char buf[128];
|
|
||||||
int len;
|
|
||||||
uint64_t val = 0;
|
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
/* pid */
|
/* pid */
|
||||||
val = getpid();
|
g_string_printf(buf, FMT_pid " ", getpid());
|
||||||
snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
|
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
/* app name */
|
/* app name */
|
||||||
snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
|
gchar *bin = g_strrstr(ts->bprm->argv[0], "/");
|
||||||
|
bin = bin ? bin + 1 : ts->bprm->argv[0];
|
||||||
|
g_string_printf(buf, "(%.15s) ", bin);
|
||||||
} else if (i == 27) {
|
} else if (i == 27) {
|
||||||
/* stack bottom */
|
/* stack bottom */
|
||||||
val = start_stack;
|
g_string_printf(buf, TARGET_ABI_FMT_ld " ", ts->info->start_stack);
|
||||||
snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
|
|
||||||
} else {
|
} else {
|
||||||
/* for the rest, there is MasterCard */
|
/* for the rest, there is MasterCard */
|
||||||
snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
|
g_string_printf(buf, "0%c", i == 43 ? '\n' : ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(buf);
|
if (write(fd, buf->str, buf->len) != buf->len) {
|
||||||
if (write(fd, buf, len) != len) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue