From: Svante Signell Date: Mon, 12 Jun 2017 00:25:57 +0000 (+1000) Subject: pstree: Remove need for PATH_MAX X-Git-Tag: v23.0~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5e510d1c9ed8cb61f9c504076a7c4828624b8b07;p=psmisc pstree: Remove need for PATH_MAX This commit removes the need for PATH_MAX in pstree. It uses the fact that calling snprintf() with *str=NULL and size=0 returns the number of bytes needed for the string according to POSIX.1-2001 and later (which is supported by all glibc versions since 2.1, see snprintf(3)). References: https://bugs.debian.org/750405 Signed-off-by: Craig Small --- diff --git a/ChangeLog b/ChangeLog index 3398883..e91d670 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,7 +17,7 @@ Changes in 23.0 * fuser: Fixed typo for -M flag. Debian #740275 * pstree: by default doesn't show threadnames, use -t to show as it disables compaction. SF [#33] Debian #815902 - * pstree: PATH_MAX defined for FreeBSD. Debian #750405 + * pstree: Removed need for PATH_MAX Debian #750405 * pstree: ignores disappeared processes. SF [#34] * killall: -o and -y work with -r flags. SF [#64] * m4/gettext.m4: Upgrade to gettext-0.19.4. diff --git a/src/pstree.c b/src/pstree.c index 5c54ce3..aaf3df7 100644 --- a/src/pstree.c +++ b/src/pstree.c @@ -46,10 +46,6 @@ #include "i18n.h" #include "comm.h" -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif /* PATH_MAX */ - #ifdef WITH_SELINUX #include #else @@ -863,7 +859,9 @@ static char* get_threadname(const pid_t pid, const int tid, const char *comm) { FILE *file; char *thread_comm, *endcomm, *threadname; - char path[PATH_MAX + 1]; + char *path = NULL; + size_t len = 0; + int nbytes; char readbuf[BUFSIZ + 1]; if (! (threadname = malloc(COMM_LEN + 2 + 1))) { @@ -873,8 +871,16 @@ static char* get_threadname(const pid_t pid, const int tid, const char *comm) sprintf(threadname, THREAD_FORMAT, COMM_LEN, comm); return threadname; } - if (snprintf(path, PATH_MAX, "%s/%d/task/%d/stat", PROC_BASE, pid, tid) < 0) - perror("get_threadname: asprintf"); + len = snprintf(NULL, 0, "%s/%d/task/%d/stat", PROC_BASE, pid, tid); + if (len < 0) + exit(2); + len++; + path = malloc(len); + if (path == NULL) + exit(2); + nbytes = snprintf(path, len, "%s/%d/task/%d/stat", PROC_BASE, pid, tid); + if (nbytes < 0 || nbytes >= len) + perror("get_threadname: snprintf"); if ( (file = fopen(path, "r")) != NULL) { if (fgets(readbuf, BUFSIZ, file) != NULL) { if ((thread_comm = strchr(readbuf, '(')) @@ -883,11 +889,13 @@ static char* get_threadname(const pid_t pid, const int tid, const char *comm) *endcomm = '\0'; sprintf(threadname, THREAD_FORMAT, COMM_LEN, thread_comm); (void) fclose(file); + free(path); return threadname; } } fclose(file); } + free(path); /* Fall back to old method */ sprintf(threadname, THREAD_FORMAT, COMM_LEN, comm);