]> granicus.if.org Git - psmisc/commitdiff
pstree: Remove need for PATH_MAX
authorSvante Signell <svante.signell@gmail.com>
Mon, 12 Jun 2017 00:25:57 +0000 (10:25 +1000)
committerCraig Small <csmall@enc.com.au>
Mon, 12 Jun 2017 00:25:57 +0000 (10:25 +1000)
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 <csmall@enc.com.au>
ChangeLog
src/pstree.c

index 339888330a8696045d496f85e0d6f3e0f4797a8b..e91d6707eb86699fb68008eaf2f9fe6ebec54203 100644 (file)
--- 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.
index 5c54ce3faa1e751cbbf8945c4d1bee87bf871a7e..aaf3df77dcef1c9aad1d9d846bafd91162425414 100644 (file)
 #include "i18n.h"
 #include "comm.h"
 
-#ifndef PATH_MAX
-#define PATH_MAX 4096
-#endif /* PATH_MAX */
-
 #ifdef WITH_SELINUX
 #include <selinux/selinux.h>
 #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);