From e97aeb6dea6ed654d599527c1f1d521e576743b4 Mon Sep 17 00:00:00 2001
From: Rob Landley <rob@landley.net>
Date: Tue, 21 Mar 2017 19:25:33 -0500
Subject: dirtree_flagread() returns DIRTREE_ABORTVAL when the initial node
 doesn't exist, which can hit ps when /proc isn't there or /proc/$PID/task
 isn't there (because process exited between the time we checked its contents
 and the time we looked for its threads).

---
 toys/posix/ps.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'toys')

diff --git a/toys/posix/ps.c b/toys/posix/ps.c
index 41ddf6a4..0d79b5cb 100644
--- a/toys/posix/ps.c
+++ b/toys/posix/ps.c
@@ -896,6 +896,7 @@ static int get_threads(struct dirtree *new)
   kcount = TT.kcount;
   sprintf(toybuf, "/proc/%u/task", pid);
   new->child = dirtree_flagread(toybuf, DIRTREE_SHUTUP|DIRTREE_PROC, get_ps);
+  if (new->child == DIRTREE_ABORTVAL) new->child = 0;
   TT.threadparent = 0;
   kcount = TT.kcount-kcount+1;
   tb = (void *)new->extra;
@@ -1236,7 +1237,7 @@ void ps_main(void)
     ((toys.optflags&FLAG_T) || (TT.bits&(_PS_TID|_PS_TCNT)))
       ? get_threads : get_ps);
 
-  if (toys.optflags&(FLAG_k|FLAG_M)) {
+  if ((dt != DIRTREE_ABORTVAL) && toys.optflags&(FLAG_k|FLAG_M)) {
     struct carveup **tbsort = collate(TT.kcount, dt);
 
     if (toys.optflags&FLAG_M) {
@@ -1365,6 +1366,7 @@ static void top_common(
     dt = dirtree_flagread("/proc", DIRTREE_SHUTUP|DIRTREE_PROC,
       ((toys.optflags&FLAG_H) || (TT.bits&(_PS_TID|_PS_TCNT)))
         ? get_threads : get_ps);
+    if (dt == DIRTREE_ABORTVAL) error_exit("no /proc");
     plnew->tb = collate(plnew->count = TT.kcount, dt);
     TT.kcount = 0;
 
-- 
cgit v1.2.3