* pstree.c - display process tree
*
* Copyright (C) 1993-2002 Werner Almesberger
- * Copyright (C) 2002-2009 Craig Small
+ * Copyright (C) 2002-2012 Craig Small
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
char **argv; /* only used : argv[0] is 1st arg; undef if argc < 1 */
int argc; /* with -a : number of arguments, -1 if swapped */
pid_t pid;
+ pid_t pgid;
uid_t uid;
#ifdef WITH_SELINUX
security_context_t scontext;
static int *width = NULL;
static int *more = NULL;
-static int print_args = 0, compact = 1, user_change = 0, pids = 0,
+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;
#ifdef WITH_SELINUX
static int show_scontext = 0;
#ifdef WITH_SELINUX
static void
-add_proc(const char *comm, pid_t pid, pid_t ppid, uid_t uid,
+add_proc(const char *comm, pid_t pid, pid_t ppid, pid_t pgid, uid_t uid,
const char *args, int size, char isthread, security_context_t scontext)
#else /*WITH_SELINUX */
static void
-add_proc(const char *comm, pid_t pid, pid_t ppid, uid_t uid,
+add_proc(const char *comm, pid_t pid, pid_t ppid, pid_t pgid, uid_t uid,
const char *args, int size, char isthread)
#endif /*WITH_SELINUX */
{
set_args(this, args, size);
if (pid == ppid)
ppid = 0;
+ this->pgid = pgid;
if (isthread)
this->flags |= PFLAG_THREAD;
if (!(parent = find_proc(ppid))) {
out_char(info++ ? ',' : '(');
(void) out_int(current->pid);
}
+ if (pgids) {
+ out_char(info++ ? ',' : '(');
+ (void) out_int(current->pgid);
+ }
if (user_change && prev_uid != current->uid) {
out_char(info++ ? ',' : '(');
if ((pw = getpwuid(current->uid)))
size_t buffer_size;
char readbuf[BUFSIZ + 1];
char *tmpptr;
- pid_t pid, ppid;
+ pid_t pid, ppid, pgid;
int fd, size;
int empty;
#ifdef WITH_SELINUX
/* We now have readbuf with pid and cmd, and tmpptr+2
* with the rest */
/*printf("tmpptr: %s\n", tmpptr+2); */
- if (sscanf(tmpptr + 2, "%*c %d", &ppid) == 1) {
+ if (sscanf(tmpptr + 2, "%*c %d %d", &ppid, &pgid) == 2) {
DIR *taskdir;
struct dirent *dt;
char *taskpath;
if (thread != pid) {
#ifdef WITH_SELINUX
if (print_args)
- add_proc(threadname, thread, pid, st.st_uid,
+ add_proc(threadname, thread, pid, pgid, st.st_uid,
threadname, strlen (threadname) + 1, 1,scontext);
else
- add_proc(threadname, thread, pid, st.st_uid,
+ add_proc(threadname, thread, pid, pgid, st.st_uid,
NULL, 0, 1, scontext);
#else /*WITH_SELINUX */
if (print_args)
- add_proc(threadname, thread, pid, st.st_uid,
+ add_proc(threadname, thread, pid, pgid, st.st_uid,
threadname, strlen (threadname) + 1, 1);
else
- add_proc(threadname, thread, pid, st.st_uid,
+ add_proc(threadname, thread, pid, pgid, st.st_uid,
NULL, 0, 1);
#endif /*WITH_SELINUX */
}
free(taskpath);
if (!print_args)
#ifdef WITH_SELINUX
- add_proc(comm, pid, ppid, st.st_uid, NULL, 0, 0, scontext);
+ add_proc(comm, pid, ppid, pgid, st.st_uid, NULL, 0, 0, scontext);
#else /*WITH_SELINUX */
- add_proc(comm, pid, ppid, st.st_uid, NULL, 0, 0);
+ add_proc(comm, pid, ppid, pgid, st.st_uid, NULL, 0, 0);
#endif /*WITH_SELINUX */
else {
sprintf(path, "%s/%d/cmdline", PROC_BASE, pid);
if (size)
buffer[size++] = 0;
#ifdef WITH_SELINUX
- add_proc(comm, pid, ppid, st.st_uid,
+ add_proc(comm, pid, ppid, pgid, st.st_uid,
buffer, size, 0, scontext);
#else /*WITH_SELINUX */
- add_proc(comm, pid, ppid, st.st_uid,
+ add_proc(comm, pid, ppid, pgid, st.st_uid,
buffer, size, 0);
#endif /*WITH_SELINUX */
}
{
fprintf(stderr,
_
- ("Usage: pstree [ -a ] [ -c ] [ -h | -H PID ] [ -l ] [ -n ] [ -p ] [ -u ]\n"
+ ("Usage: pstree [ -a ] [ -c ] [ -h | -H PID ] [ -l ] [ -n ] [ -p ] [ -g ] [ -u ]\n"
" [ -A | -G | -U ] [ PID | USER ]\n"
" pstree -V\n" "Display a tree of processes.\n\n"
" -a, --arguments show command line arguments\n"
" -h, --highlight-all highlight current process and its ancestors\n"
" -H PID,\n"
" --highlight-pid=PID highlight this process and its ancestors\n"
+ " -g, --show-pgids show process group ids; implies -c\n"
" -G, --vt100 use VT100 line drawing characters\n"
" -l, --long don't truncate long lines\n"
" -n, --numeric-sort sort output by PID\n"
{"long", 0, NULL, 'l'},
{"numeric-sort", 0, NULL, 'n'},
{"show-pids", 0, NULL, 'p'},
+ {"show-pgids", 0, NULL, 'g'},
{"show-parents", 0, NULL, 's'},
{"uid-changes", 0, NULL, 'u'},
{"unicode", 0, NULL, 'U'},
#ifdef WITH_SELINUX
while ((c =
- getopt_long(argc, argv, "aAcGhH:nplsuUVZ", options,
+ getopt_long(argc, argv, "aAcGhH:npglsuUVZ", options,
NULL)) != -1)
#else /*WITH_SELINUX */
while ((c =
- getopt_long(argc, argv, "aAcGhH:nplsuUV", options, NULL)) != -1)
+ getopt_long(argc, argv, "aAcGhH:npglsuUV", options, NULL)) != -1)
#endif /*WITH_SELINUX */
switch (c) {
case 'a':
pids = 1;
compact = 0;
break;
+ case 'g':
+ pgids = 1;
+ compact = 0;
+ break;
case 's':
show_parents = 1;
break;