aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2018-02-10 12:38:06 -0600
committerRob Landley <rob@landley.net>2018-02-10 12:38:06 -0600
commit9a2c9da7cf72d3ad246f62840dcf9506f5926506 (patch)
tree6aa8ff33bada87dfd8c29873c7752cb3c027b792
parent371dfd41efca697e72832cdf5db61ffd4c7e7a98 (diff)
downloadtoybox-9a2c9da7cf72d3ad246f62840dcf9506f5926506.tar.gz
Fix ps -T again, but this time read files from tid directory, not pid.
(Otherwise updating pid to parents makes threads read thread parent data.)
-rw-r--r--toys/posix/ps.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/toys/posix/ps.c b/toys/posix/ps.c
index e3a2d310..b8542e60 100644
--- a/toys/posix/ps.c
+++ b/toys/posix/ps.c
@@ -678,13 +678,16 @@ static int get_ps(struct dirtree *new)
|(DIRTREE_SAVE*(TT.threadparent||!TT.show_process));
memset(slot, 0, sizeof(tb->slot));
- tb->slot[SLOT_tid] = *slot = atol(new->name);
- if (TT.threadparent && TT.threadparent->extra)
- if (*slot == *(((struct procpid *)TT.threadparent->extra)->slot)) return 0;
+ slot[SLOT_tid] = *slot = atol(new->name);
+ if (TT.threadparent && TT.threadparent->extra) {
+ *slot = *(((struct procpid *)TT.threadparent->extra)->slot);
+ // Parent also shows up as a thread, discard duplicate
+ if (*slot == slot[SLOT_tid]) return 0;
+ }
fd = dirtree_parentfd(new);
len = 2048;
- sprintf(buf, "%lld/stat", *slot);
+ sprintf(buf, "%lld/stat", slot[SLOT_tid]);
if (!readfileat(fd, buf, buf, &len)) return 0;
// parse oddball fields (name and state). Name can have embedded ')' so match
@@ -725,7 +728,7 @@ static int get_ps(struct dirtree *new)
{
off_t temp = len;
- sprintf(buf, "%lld/status", *slot);
+ sprintf(buf, "%lld/status", slot[SLOT_tid]);
if (!readfileat(fd, buf, buf, &temp)) *buf = 0;
s = strafter(buf, "\nUid:");
slot[SLOT_ruid] = s ? atol(s) : new->st.st_uid;
@@ -739,7 +742,7 @@ static int get_ps(struct dirtree *new)
if (TT.bits&(_PS_READ|_PS_WRITE|_PS_DREAD|_PS_DWRITE|_PS_IO|_PS_DIO)) {
off_t temp = len;
- sprintf(buf, "%lld/io", *slot);
+ sprintf(buf, "%lld/io", slot[SLOT_tid]);
if (!readfileat(fd, buf, buf, &temp)) *buf = 0;
if ((s = strafter(buf, "rchar:"))) slot[SLOT_rchar] = atoll(s);
if ((s = strafter(buf, "wchar:"))) slot[SLOT_wchar] = atoll(s);
@@ -762,7 +765,7 @@ static int get_ps(struct dirtree *new)
if (TT.bits&(_PS_VIRT|_PS_RES|_PS_SHR)) {
off_t temp = len;
- sprintf(buf, "%lld/statm", *slot);
+ sprintf(buf, "%lld/statm", slot[SLOT_tid]);
if (!readfileat(fd, buf, buf, &temp)) *buf = 0;
for (s = buf, i=0; i<3; i++)
@@ -774,7 +777,7 @@ static int get_ps(struct dirtree *new)
if (TT.bits&_PS_BIT) {
off_t temp = 6;
- sprintf(buf, "%lld/exe", *slot);
+ sprintf(buf, "%lld/exe", slot[SLOT_tid]);
if (readfileat(fd, buf, buf, &temp) && !memcmp(buf, "\177ELF", 4)) {
if (buf[4] == 1) slot[SLOT_bits] = 32;
else if (buf[4] == 2) slot[SLOT_bits] = 64;
@@ -782,7 +785,8 @@ static int get_ps(struct dirtree *new)
}
// Do we need Android scheduling policy?
- if (TT.bits&_PS_PCY) get_sched_policy(*slot, (void *)&slot[SLOT_pcy]);
+ if (TT.bits&_PS_PCY)
+ get_sched_policy(slot[SLOT_tid], (void *)&slot[SLOT_pcy]);
// Fetch string data while parentfd still available, appending to buf.
// (There's well over 3k of toybuf left. We could dynamically malloc, but
@@ -799,7 +803,7 @@ static int get_ps(struct dirtree *new)
// Determine remaining space, reserving minimum of 256 bytes/field and
// 260 bytes scratch space at the end (for output conversion later).
len = sizeof(toybuf)-(buf-toybuf)-260-256*(ARRAY_LEN(fetch)-j);
- sprintf(buf, "%lld/%s", *slot, fetch[j].name);
+ sprintf(buf, "%lld/%s", slot[SLOT_tid], fetch[j].name);
// For exe we readlink instead of read contents
if (j==3 || j==5) {
@@ -814,7 +818,7 @@ static int get_ps(struct dirtree *new)
else {
if (j==3) i = strlen(s = ptb->str+ptb->offset[3]);
else {
- if (!ptb || tb->slot[SLOT_argv0len]) ptb = tb;
+ if (!ptb || slot[SLOT_argv0len]) ptb = tb;
i = ptb->slot[SLOT_argv0len];
s = ptb->str+ptb->offset[4];
while (-1!=(k = stridx(s, '/')) && k<i) {
@@ -838,7 +842,7 @@ static int get_ps(struct dirtree *new)
if (rdev) {
// Can we readlink() our way to a name?
for (i = 0; i<3; i++) {
- sprintf(buf, "%lld/fd/%i", *slot, i);
+ sprintf(buf, "%lld/fd/%i", slot[SLOT_tid], i);
if (!fstatat(fd, buf, &st, 0) && S_ISCHR(st.st_mode)
&& st.st_rdev == rdev && (len = readlinkat0(fd, buf, buf, len)))
break;