.\" the Free Software Foundation; either version 2 of the License, or
.\" (at your option) any later version.
.\"
-.TH PSTREE 1 "2014-01-31" "psmisc" "User Commands"
+.TH PSTREE 1 "2014-03-01" "psmisc" "User Commands"
.SH NAME
pstree \- display a tree of processes
.SH SYNOPSIS
.RB [ \-p , \ \-\-show\-pids ]
.RB [ \-s , \ \-\-show\-parents ]
.RB [ \-S , \ \-\-ns-changes ]
+.RB [ \-t , \ \-\-thread-names ]
.RB [ \-u , \ \-\-uid\-changes ]
.RB [ \-Z , \ \-\-security\-context ]
.RB [ \-A , \ \-\-ascii , \ \-G , \ \-\-vt100 , \ \-U , \ \-\-unicode ]
.IP \fB\-S\fP
Show namespaces transitions. Like \-N, the output is limited when running
as a regular user.
+.IP \fB\-t\fP
+Show full names for threads when available.
.IP \fB\-u\fP
Show uid transitions. Whenever the uid of a process differs from the
uid of its parent, the new uid is shown in parentheses after the
#define NUM_NS 6
+#define THREAD_FORMAT "{%.*s}" /* Format for thread names */
+
typedef struct _proc {
char comm[COMM_LEN + 2 + 1]; /* add another 2 for thread brackets */
char **argv; /* only used : argv[0] is 1st arg; undef if argc < 1 */
static int *more = NULL;
static int print_args = 0, compact = 1, user_change = 0, pids = 0, pgids = 0,
- show_parents = 0, by_pid = 0, trunc = 1, wait_end = 0, ns_change = 0;
+ show_parents = 0, by_pid = 0, trunc = 1, wait_end = 0, ns_change = 0,
+ thread_names = 0;
static int show_scontext = 0;
static int output_width = 132;
static int cur_x = 1;
if (! (threadname = malloc(COMM_LEN + 2 + 1))) {
exit(2);
}
+ if (!thread_names) {
+ 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");
if ( (file = fopen(path, "r")) != NULL) {
&& (endcomm = strrchr(thread_comm, ')'))) {
++thread_comm;
*endcomm = '\0';
- sprintf(threadname, "{%.*s}", COMM_LEN, thread_comm);
+ sprintf(threadname, THREAD_FORMAT, COMM_LEN, thread_comm);
(void) fclose(file);
return threadname;
}
}
+ fclose(file);
}
+
/* Fall back to old method */
- sprintf(threadname, "{%.*s}", COMM_LEN, comm);
- fclose(file);
+ sprintf(threadname, THREAD_FORMAT, COMM_LEN, comm);
return threadname;
}
" -p, --show-pids show PIDs; implies -c\n"
" -s, --show-parents show parents of the selected process\n"
" -S, --ns-changes show namespace transitions\n"
+ " -t, --thread-names show full thread names\n"
" -u, --uid-changes show uid transitions\n"
" -U, --unicode use UTF-8 (Unicode) line drawing characters\n"
" -V, --version display version information\n"));
{"show-pgids", 0, NULL, 'g'},
{"show-parents", 0, NULL, 's'},
{"ns-changes", 0, NULL, 'S' },
+ {"thread-names", 0, NULL, 't'},
{"uid-changes", 0, NULL, 'u'},
{"unicode", 0, NULL, 'U'},
{"version", 0, NULL, 'V'},
#ifdef WITH_SELINUX
while ((c =
- getopt_long(argc, argv, "aAcGhH:nN:pglsSuUVZ", options,
+ getopt_long(argc, argv, "aAcGhH:nN:pglsStuUVZ", options,
NULL)) != -1)
#else /*WITH_SELINUX */
while ((c =
- getopt_long(argc, argv, "aAcGhH:nN:pglsSuUV", options, NULL)) != -1)
+ getopt_long(argc, argv, "aAcGhH:nN:pglsStuUV", options, NULL)) != -1)
#endif /*WITH_SELINUX */
switch (c) {
case 'a':
case 'S':
ns_change = 1;
break;
+ case 't':
+ thread_names = 1;
+ break;
case 'u':
user_change = 1;
break;