From: Craig Small Date: Fri, 20 Jul 2012 12:32:27 +0000 (+1000) Subject: pstree sorts properly on names X-Git-Tag: v22.20rc1~5^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7afa9fa7eb16cc5f53e38bda80e475985a372b6b;p=psmisc pstree sorts properly on names pstree added temporary parents to processes, so if a child process was lexigraphically before the parents or its "aunties and uncles" then they were sorted with the parent temporary name "?". This patch reorders the children in the parents list when they are renamed. --- diff --git a/ChangeLog b/ChangeLog index dafefa2..1c5d57b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +Changes in 22.20 +================ + * pstree sorts properly on names Debian #682014 Changes in 22.19 ================ * killall with no args exits again SF #3536526 diff --git a/src/pstree.c b/src/pstree.c index dd7045b..9d9e8d5 100644 --- a/src/pstree.c +++ b/src/pstree.c @@ -296,8 +296,8 @@ static void add_child(PROC * parent, PROC * child) if (by_pid) { if ((*walk)->child->pid > child->pid) break; - } else if ((cmp = strcmp((*walk)->child->comm, child->comm)) > 0) - break; + } else if ((cmp = strcmp((*walk)->child->comm, child->comm)) > 0) { + break; } else if (!cmp && (*walk)->child->uid > child->uid) break; new->next = *walk; @@ -335,6 +335,28 @@ static void set_args(PROC * this, const char *args, int size) this->argv[i] = start = strchr(start, 0) + 1; } +static void +rename_proc(PROC *this, const char *comm, uid_t uid) +{ + PROC *tmp_child, *parent; + CHILD **walk; + + strncpy(this->comm, comm, COMM_LEN+2); + this->comm[COMM_LEN+1] = '\0'; + this->uid = uid; + + /* Re-sort children in parent, now we have a name */ + if (!by_pid && this->parent) { + parent = this->parent; + for (walk = &parent->children; *walk; walk = &(*walk)->next) { + if ( ((*walk)->next != NULL) && strcmp((*walk)->child->comm, (*walk)->next->child->comm) > 0 ) { + tmp_child = (*walk)->child; + (*walk)->child = (*walk)->next->child; + (*walk)->next->child = tmp_child; + } + } + } +} #ifdef WITH_SELINUX static void add_proc(const char *comm, pid_t pid, pid_t ppid, pid_t pgid, uid_t uid, @@ -354,9 +376,7 @@ add_proc(const char *comm, pid_t pid, pid_t ppid, pid_t pgid, uid_t uid, this = new_proc(comm, pid, uid); #endif /*WITH_SELINUX */ else { - strncpy(this->comm, comm, COMM_LEN+2); - this->comm[COMM_LEN+1] = '\0'; - this->uid = uid; + rename_proc(this, comm, uid); } if (args) set_args(this, args, size); @@ -778,35 +798,6 @@ static void read_proc(void) } } - -#if 0 - -/* Could use output of ps achlx | awk '{ print $3,$4,$2,$13 }' */ - -static void read_stdin(void) -{ - char comm[PATH_MAX + 1]; - char *cmd; - int pid, ppid, uid; - - while (scanf("%d %d %d %s\n", &pid, &ppid, &uid, comm) == 4) { - if (cmd = strrchr(comm, '/')) - cmd++; - else - cmd = comm; - if (*cmd == '-') - cmd++; -#ifdef WITH_SELINUX - add_proc(cmd, pid, ppid, uid, NULL, 0, NULL); -#else /*WITH_SELINUX */ - add_proc(cmd, pid, ppid, uid, NULL, 0); -#endif /*WITH_SELINUX */ - } -} - -#endif - - static void usage(void) { fprintf(stderr,