Re: Bug#687829: psmisc: pstree hangs on kfreebsd-amd64
Hi Craig,
The attached changes, cherry-picked from upstream Git, applied and
refreshed against psmisc/22.19-1, seem sufficient to fix the RC bug for
me on GNU/kFreeBSD.
Please let me know what you think to a t-p-u upload fixing this in
wheezy. I haven't asked the release team about this yet, but I'm
assuming psmisc/22.20-1 introduced too many changes (including autoconf
stuff) meaning it would not be eligible for unblock.
I notice neither this nor pstree from psmisc/22.20-1 are quite perfect
yet in kFreeBSD jails (or Linux OpenVZ VEs for that matter) but I'll
follow up on that later (it won't be release-critical though).
Regards,
--
Steven Chamberlain
steven@pyro.eu.org
Index: psmisc-22.19/src/pstree.c
===================================================================
--- psmisc-22.19.orig/src/pstree.c 2012-05-20 00:10:36.000000000 +0100
+++ psmisc-22.19/src/pstree.c 2013-01-29 14:05:26.080464900 +0000
@@ -53,6 +53,12 @@
#define PROC_BASE "/proc"
+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
+#define ROOT_PID 0
+#else
+#define ROOT_PID 1
+#endif /* __FreeBSD__ */
+
/* UTF-8 defines by Johan Myreen, updated by Ben Winslow */
#define UTF_V "\342\224\202" /* U+2502, Vertical line drawing char */
#define UTF_VR "\342\224\234" /* U+251C, Vertical and right */
@@ -375,19 +381,21 @@
* then we need fake root pid */
if (!isthread && pid != 1) {
PROC *root;
- if (!(root = find_proc(1))) {
+ if (!(root = find_proc(ROOT_PID))) {
#ifdef WITH_SELINUX
- root = new_proc("?", 1, 0, scontext);
+ root = new_proc("?", ROOT_PID, 0, scontext);
#else /*WITH_SELINUX */
- root = new_proc("?", 1, 0);
+ root = new_proc("?", ROOT_PID, 0);
#endif
}
add_child(root, parent);
parent->parent = root;
}
}
- add_child(parent, this);
- this->parent = parent;
+ if (pid != 0) {
+ add_child(parent, this);
+ this->parent = parent;
+ }
}
@@ -634,7 +642,7 @@
char *buffer;
size_t buffer_size;
char readbuf[BUFSIZ + 1];
- char *tmpptr;
+ char *tmpptr, *endptr;
pid_t pid, ppid, pgid;
int fd, size;
int empty;
@@ -659,8 +667,9 @@
exit(1);
}
empty = 1;
- while ((de = readdir(dir)) != NULL)
- if ((pid = (pid_t) atoi(de->d_name)) != 0) {
+ while ((de = readdir(dir)) != NULL) {
+ pid = (pid_t) strtol(de->d_name, &endptr, 10);
+ if (endptr != de->d_name && endptr[0] == '\0') {
if (! (path = malloc(strlen(PROC_BASE) + strlen(de->d_name) + 10)))
exit(2);
sprintf(path, "%s/%d/stat", PROC_BASE, pid);
@@ -769,6 +778,7 @@
}
free(path);
}
+ }
(void) closedir(dir);
if (print_args)
free(buffer);
@@ -859,8 +869,8 @@
const struct passwd *pw;
pid_t pid, highlight;
char termcap_area[1024];
- char *termname;
- int c;
+ char *termname, *endptr;
+ int c, pid_set;
struct option options[] = {
{"arguments", 0, NULL, 'a'},
@@ -886,7 +896,7 @@
if (ioctl(1, TIOCGWINSZ, &winsz) >= 0)
if (winsz.ws_col)
output_width = winsz.ws_col;
- pid = 1;
+ pid = ROOT_PID;
highlight = 0;
pw = NULL;
@@ -1006,7 +1016,9 @@
}
if (optind == argc - 1) {
if (isdigit(*argv[optind])) {
- if (!(pid = (pid_t) atoi(argv[optind++])))
+ pid = (pid_t) strtol(argv[optind++], &endptr, 10);
+ pid_set = 1;
+ if (endptr[0] != '\0')
usage();
} else if (!(pw = getpwnam(argv[optind++]))) {
fprintf(stderr, _("No such user name: %s\n"),
@@ -1021,16 +1033,16 @@
current = current->parent)
current->flags |= PFLAG_HILIGHT;
- if(show_parents && pid != 0) {
+ if(show_parents && pid_set == 1) {
trim_tree_by_parent(find_proc(pid));
- pid = 1;
+ pid = ROOT_PID;
}
if (!pw)
dump_tree(find_proc(pid), 0, 1, 1, 1, 0, 0);
else {
- dump_by_user(find_proc(1), pw->pw_uid);
+ dump_by_user(find_proc(ROOT_PID), pw->pw_uid);
if (!dumped) {
fprintf(stderr, _("No processes found.\n"));
return 1;
Reply to: