Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

external-toybox: Commit

external/toybox


Commit MetaInfo

Revision88097b68fc299c17bfe69148fc8924b574146faa (tree)
Time2018-02-14 17:22:25
Authorandroid-build-team Robot <android-build-team-robot@goog...>
Commiterandroid-build-team Robot

Log Message

Snap for 4603395 from a62c5f6d669cf2d15f54ce58fa4ca025613632e4 to pi-release

Change-Id: I6dff7c00ca9a518ea5e068cb330d85286ee13e02

Change Summary

Incremental Difference

--- a/toys/posix/ps.c
+++ b/toys/posix/ps.c
@@ -286,21 +286,20 @@ GLOBALS(
286286 void (*show_process)(void *tb);
287287 )
288288
289-/* Linked list of fields selected for display, in order, with :len and =title */
289+// Linked list of -o fields selected for display, in order, with :len and =title
290290
291-struct strawberry {
292- struct strawberry *next, *prev;
291+struct ofields {
292+ struct ofields *next, *prev;
293293 short which, len, reverse;
294294 char *title;
295- char forever[];
296295 };
297296
298297 /* The function get_ps() reads all the data about one process, saving it in
299- * toybox as a struct carveup. Simple ps calls then pass toybuf directly to
300- * show_ps(), but features like sorting instead append a copy to a linked list
298+ * toybox as a struct procpid. Simple ps calls then pass toybuf directly to
299+ * show_ps(), but features like sorting append a copy to a linked list
301300 * for further processing once all processes have been read.
302301 *
303- * struct carveup contains a slot[] array of 64 bit values, with the following
302+ * struct procpid contains a slot[] array of 64 bit values, with the following
304303 * data at each position in the array. Most is read from /proc/$PID/stat (see
305304 * https://kernel.org/doc/Documentation/filesystems/proc.txt table 1-4) but
306305 * we we replace several fields with don't use with other data. */
@@ -346,7 +345,7 @@ enum {
346345 starting position of each string after the first (which is always 0). */
347346
348347 // Data layout in toybuf
349-struct carveup {
348+struct procpid {
350349 long long slot[SLOT_count]; // data (see enum above)
351350 unsigned short offset[6]; // offset of fields in str[] (skip CMD, always 0)
352351 char state;
@@ -364,7 +363,7 @@ struct carveup {
364363 * the display code reclaims unused padding from later fields to try to
365364 * get the overflow back).
366365 *
367- * slot: which slot[] out of carveup. Negative means it's a string field.
366+ * slot: which slot[] out of procpid. Negative means it's a string field.
368367 * Setting bit |64 requests extra display/sort processing.
369368 *
370369 * The TAGGED_ARRAY plumbing produces an enum of indexes, the "tag" is the
@@ -391,7 +390,7 @@ struct typography {
391390 {"RTPRIO", 6, SLOT_rtprio}, {"SCH", 3, SLOT_policy}, {"CPU", 3, SLOT_taskcpu},
392391 {"TID", 5, SLOT_tid}, {"TCNT", 4, SLOT_tcount}, {"BIT", 3, SLOT_bits},
393392
394- // String fields (-1 is carveup->str, rest are str+offset[1-slot])
393+ // String fields (-1 is procpid->str, rest are str+offset[1-slot])
395394 {"TTY", -8, -2}, {"WCHAN", -6, -3}, {"LABEL", -30, -4}, {"COMM", -27, -5},
396395 {"NAME", -27, -7}, {"COMMAND", -27, -5}, {"CMDLINE", -27, -6},
397396 {"ARGS", -27, -6}, {"CMD", -15, -1},
@@ -464,7 +463,7 @@ static int ps_match_process(long long *slot)
464463 }
465464
466465 // Convert field to string representation
467-static char *string_field(struct carveup *tb, struct strawberry *field)
466+static char *string_field(struct procpid *tb, struct ofields *field)
468467 {
469468 char *buf = toybuf+sizeof(toybuf)-260, *out = buf, *s;
470469 int which = field->which, sl = typos[which].slot;
@@ -593,8 +592,8 @@ static char *string_field(struct carveup *tb, struct strawberry *field)
593592 // Display process data that get_ps() read from /proc, formatting with TT.fields
594593 static void show_ps(void *p)
595594 {
596- struct carveup *tb = p;
597- struct strawberry *field;
595+ struct procpid *tb = p;
596+ struct ofields *field;
598597 int pad, len, width = TT.width, abslen, sign, olen, extra = 0;
599598
600599 // Loop through fields to display
@@ -654,7 +653,7 @@ static void show_ps(void *p)
654653 }
655654
656655 // dirtree callback: read data about process to display, store, or discard it.
657-// Fills toybuf with struct carveup and either DIRTREE_SAVEs a copy to ->extra
656+// Fills toybuf with struct procpid and either DIRTREE_SAVEs a copy to ->extra
658657 // (in -k mode) or calls show_ps on toybuf (no malloc/copy/free there).
659658 static int get_ps(struct dirtree *new)
660659 {
@@ -662,12 +661,12 @@ static int get_ps(struct dirtree *new)
662661 char *name; // Path under /proc/$PID directory
663662 long long bits; // Only fetch extra data if an -o field is displaying it
664663 } fetch[] = {
665- // sources for carveup->offset[] data
664+ // sources for procpid->offset[] data
666665 {"fd/", _PS_TTY}, {"wchan", _PS_WCHAN}, {"attr/current", _PS_LABEL},
667666 {"exe", _PS_COMMAND|_PS_COMM}, {"cmdline", _PS_CMDLINE|_PS_ARGS|_PS_NAME},
668667 {"", _PS_NAME}
669668 };
670- struct carveup *tb = (void *)toybuf;
669+ struct procpid *tb = (void *)toybuf;
671670 long long *slot = tb->slot;
672671 char *name, *s, *buf = tb->str, *end = 0;
673672 int i, j, fd;
@@ -679,13 +678,16 @@ static int get_ps(struct dirtree *new)
679678 |(DIRTREE_SAVE*(TT.threadparent||!TT.show_process));
680679
681680 memset(slot, 0, sizeof(tb->slot));
682- tb->slot[SLOT_tid] = *slot = atol(new->name);
683- if (TT.threadparent && TT.threadparent->extra)
684- if (*slot == *(((struct carveup *)TT.threadparent->extra)->slot)) return 0;
681+ slot[SLOT_tid] = *slot = atol(new->name);
682+ if (TT.threadparent && TT.threadparent->extra) {
683+ *slot = *(((struct procpid *)TT.threadparent->extra)->slot);
684+ // Parent also shows up as a thread, discard duplicate
685+ if (*slot == slot[SLOT_tid]) return 0;
686+ }
685687 fd = dirtree_parentfd(new);
686688
687689 len = 2048;
688- sprintf(buf, "%lld/stat", *slot);
690+ sprintf(buf, "%lld/stat", slot[SLOT_tid]);
689691 if (!readfileat(fd, buf, buf, &len)) return 0;
690692
691693 // parse oddball fields (name and state). Name can have embedded ')' so match
@@ -726,7 +728,7 @@ static int get_ps(struct dirtree *new)
726728 {
727729 off_t temp = len;
728730
729- sprintf(buf, "%lld/status", *slot);
731+ sprintf(buf, "%lld/status", slot[SLOT_tid]);
730732 if (!readfileat(fd, buf, buf, &temp)) *buf = 0;
731733 s = strafter(buf, "\nUid:");
732734 slot[SLOT_ruid] = s ? atol(s) : new->st.st_uid;
@@ -740,7 +742,7 @@ static int get_ps(struct dirtree *new)
740742 if (TT.bits&(_PS_READ|_PS_WRITE|_PS_DREAD|_PS_DWRITE|_PS_IO|_PS_DIO)) {
741743 off_t temp = len;
742744
743- sprintf(buf, "%lld/io", *slot);
745+ sprintf(buf, "%lld/io", slot[SLOT_tid]);
744746 if (!readfileat(fd, buf, buf, &temp)) *buf = 0;
745747 if ((s = strafter(buf, "rchar:"))) slot[SLOT_rchar] = atoll(s);
746748 if ((s = strafter(buf, "wchar:"))) slot[SLOT_wchar] = atoll(s);
@@ -763,7 +765,7 @@ static int get_ps(struct dirtree *new)
763765 if (TT.bits&(_PS_VIRT|_PS_RES|_PS_SHR)) {
764766 off_t temp = len;
765767
766- sprintf(buf, "%lld/statm", *slot);
768+ sprintf(buf, "%lld/statm", slot[SLOT_tid]);
767769 if (!readfileat(fd, buf, buf, &temp)) *buf = 0;
768770
769771 for (s = buf, i=0; i<3; i++)
@@ -775,7 +777,7 @@ static int get_ps(struct dirtree *new)
775777 if (TT.bits&_PS_BIT) {
776778 off_t temp = 6;
777779
778- sprintf(buf, "%lld/exe", *slot);
780+ sprintf(buf, "%lld/exe", slot[SLOT_tid]);
779781 if (readfileat(fd, buf, buf, &temp) && !memcmp(buf, "\177ELF", 4)) {
780782 if (buf[4] == 1) slot[SLOT_bits] = 32;
781783 else if (buf[4] == 2) slot[SLOT_bits] = 64;
@@ -783,7 +785,8 @@ static int get_ps(struct dirtree *new)
783785 }
784786
785787 // Do we need Android scheduling policy?
786- if (TT.bits&_PS_PCY) get_sched_policy(*slot, (void *)&slot[SLOT_pcy]);
788+ if (TT.bits&_PS_PCY)
789+ get_sched_policy(slot[SLOT_tid], (void *)&slot[SLOT_pcy]);
787790
788791 // Fetch string data while parentfd still available, appending to buf.
789792 // (There's well over 3k of toybuf left. We could dynamically malloc, but
@@ -800,11 +803,11 @@ static int get_ps(struct dirtree *new)
800803 // Determine remaining space, reserving minimum of 256 bytes/field and
801804 // 260 bytes scratch space at the end (for output conversion later).
802805 len = sizeof(toybuf)-(buf-toybuf)-260-256*(ARRAY_LEN(fetch)-j);
803- sprintf(buf, "%lld/%s", *slot, fetch[j].name);
806+ sprintf(buf, "%lld/%s", slot[SLOT_tid], fetch[j].name);
804807
805808 // For exe we readlink instead of read contents
806809 if (j==3 || j==5) {
807- struct carveup *ptb = 0;
810+ struct procpid *ptb = 0;
808811 int k;
809812
810813 // Thread doesn't have exe or argv[0], so use parent's
@@ -815,7 +818,7 @@ static int get_ps(struct dirtree *new)
815818 else {
816819 if (j==3) i = strlen(s = ptb->str+ptb->offset[3]);
817820 else {
818- if (!ptb || tb->slot[SLOT_argv0len]) ptb = tb;
821+ if (!ptb || slot[SLOT_argv0len]) ptb = tb;
819822 i = ptb->slot[SLOT_argv0len];
820823 s = ptb->str+ptb->offset[4];
821824 while (-1!=(k = stridx(s, '/')) && k<i) {
@@ -839,7 +842,7 @@ static int get_ps(struct dirtree *new)
839842 if (rdev) {
840843 // Can we readlink() our way to a name?
841844 for (i = 0; i<3; i++) {
842- sprintf(buf, "%lld/fd/%i", *slot, i);
845+ sprintf(buf, "%lld/fd/%i", slot[SLOT_tid], i);
843846 if (!fstatat(fd, buf, &st, 0) && S_ISCHR(st.st_mode)
844847 && st.st_rdev == rdev && (len = readlinkat0(fd, buf, buf, len)))
845848 break;
@@ -925,7 +928,7 @@ static int get_ps(struct dirtree *new)
925928 static int get_threads(struct dirtree *new)
926929 {
927930 struct dirtree *dt;
928- struct carveup *tb;
931+ struct procpid *tb;
929932 unsigned pid, kcount;
930933
931934 if (!new->parent) return get_ps(new);
@@ -975,7 +978,7 @@ static int get_threads(struct dirtree *new)
975978
976979 static char *parse_ko(void *data, char *type, int length)
977980 {
978- struct strawberry *field;
981+ struct ofields *field;
979982 char *width, *title, *end, *s;
980983 int i, j, k;
981984
@@ -995,10 +998,11 @@ static char *parse_ko(void *data, char *type, int length)
995998 if (!title) length = width-type;
996999 } else width = 0;
9971000
998- // Allocate structure, copy title
999- field = xzalloc(sizeof(struct strawberry)+(length+1)*!!title);
1001+ // Allocate structure plus extra space to append a copy of title data
1002+ // (this way it's same lifetime, freeing struct automatically frees title)
1003+ field = xzalloc(sizeof(struct ofields)+(length+1)*!!title);
10001004 if (title) {
1001- memcpy(field->title = field->forever, title, length);
1005+ memcpy(field->title = (char *)(field+1), title, length);
10021006 field->title[field->len = length] = 0;
10031007 }
10041008
@@ -1036,15 +1040,15 @@ static char *parse_ko(void *data, char *type, int length)
10361040 return 0;
10371041 }
10381042
1039-static long long get_headers(struct strawberry *fields, char *buf, int blen)
1043+static long long get_headers(struct ofields *field, char *buf, int blen)
10401044 {
10411045 long long bits = 0;
10421046 int len = 0;
10431047
1044- for (; fields; fields = fields->next) {
1045- len += snprintf(buf+len, blen-len, " %*s"+!bits, fields->len,
1046- fields->title);
1047- bits |= 1LL<<fields->which;
1048+ for (; field; field = field->next) {
1049+ len += snprintf(buf+len, blen-len, " %*s"+!bits, field->len,
1050+ field->title);
1051+ bits |= 1LL<<field->which;
10481052 }
10491053
10501054 return bits;
@@ -1131,8 +1135,8 @@ static char *parse_rest(void *data, char *str, int len)
11311135 // sort for -k
11321136 static int ksort(void *aa, void *bb)
11331137 {
1134- struct strawberry *field;
1135- struct carveup *ta = *(struct carveup **)aa, *tb = *(struct carveup **)bb;
1138+ struct ofields *field;
1139+ struct procpid *ta = *(struct procpid **)aa, *tb = *(struct procpid **)bb;
11361140 int ret = 0, slot;
11371141
11381142 for (field = TT.kfields; field && !ret; field = field->next) {
@@ -1156,7 +1160,7 @@ static int ksort(void *aa, void *bb)
11561160 return ret;
11571161 }
11581162
1159-static struct carveup **collate_leaves(struct carveup **tb, struct dirtree *dt)
1163+static struct procpid **collate_leaves(struct procpid **tb, struct dirtree *dt)
11601164 {
11611165 while (dt) {
11621166 struct dirtree *next = dt->next;
@@ -1170,9 +1174,9 @@ static struct carveup **collate_leaves(struct carveup **tb, struct dirtree *dt)
11701174 return tb;
11711175 }
11721176
1173-static struct carveup **collate(int count, struct dirtree *dt)
1177+static struct procpid **collate(int count, struct dirtree *dt)
11741178 {
1175- struct carveup **tbsort = xmalloc(count*sizeof(struct carveup *));
1179+ struct procpid **tbsort = xmalloc(count*sizeof(struct procpid *));
11761180
11771181 collate_leaves(tbsort, dt);
11781182
@@ -1244,20 +1248,20 @@ void ps_main(void)
12441248 default_ko(toybuf, &TT.fields, "bad -o", TT.ps.o);
12451249
12461250 if (TT.ps.O) {
1247- if (TT.fields) TT.fields = ((struct strawberry *)TT.fields)->prev;
1251+ if (TT.fields) TT.fields = ((struct ofields *)TT.fields)->prev;
12481252 comma_args(TT.ps.O, &TT.fields, "bad -O", parse_ko);
1249- if (TT.fields) TT.fields = ((struct strawberry *)TT.fields)->next;
1253+ if (TT.fields) TT.fields = ((struct ofields *)TT.fields)->next;
12501254 }
12511255 dlist_terminate(TT.fields);
12521256
12531257 // -f and -n change the meaning of some fields
12541258 if (toys.optflags&(FLAG_f|FLAG_n)) {
1255- struct strawberry *ever;
1259+ struct ofields *field;
12561260
1257- for (ever = TT.fields; ever; ever = ever->next) {
1258- if ((toys.optflags&FLAG_n) && ever->which>=PS_UID
1259- && ever->which<=PS_RGROUP && (typos[ever->which].slot&64))
1260- ever->which--;
1261+ for (field = TT.fields; field; field = field->next) {
1262+ if ((toys.optflags&FLAG_n) && field->which>=PS_UID
1263+ && field->which<=PS_RGROUP && (typos[field->which].slot&64))
1264+ field->which--;
12611265 }
12621266 }
12631267
@@ -1272,11 +1276,11 @@ void ps_main(void)
12721276 ? get_threads : get_ps);
12731277
12741278 if ((dt != DIRTREE_ABORTVAL) && toys.optflags&(FLAG_k|FLAG_M)) {
1275- struct carveup **tbsort = collate(TT.kcount, dt);
1279+ struct procpid **tbsort = collate(TT.kcount, dt);
12761280
12771281 if (toys.optflags&FLAG_M) {
12781282 for (i = 0; i<TT.kcount; i++) {
1279- struct strawberry *field;
1283+ struct ofields *field;
12801284
12811285 for (field = TT.fields; field; field = field->next) {
12821286 int len = strlen(string_field(tbsort[i], field));
@@ -1291,7 +1295,7 @@ void ps_main(void)
12911295 }
12921296
12931297 if (toys.optflags&FLAG_k)
1294- qsort(tbsort, TT.kcount, sizeof(struct carveup *), (void *)ksort);
1298+ qsort(tbsort, TT.kcount, sizeof(struct procpid *), (void *)ksort);
12951299 for (i = 0; i<TT.kcount; i++) {
12961300 show_ps(tbsort[i]);
12971301 free(tbsort[i]);
@@ -1319,16 +1323,16 @@ void ps_main(void)
13191323 // select which of the -o fields to sort by
13201324 static void setsort(int pos)
13211325 {
1322- struct strawberry *field, *going2;
1326+ struct ofields *field, *field2;
13231327 int i = 0;
13241328
13251329 if (pos<0) pos = 0;
13261330
13271331 for (field = TT.fields; field; field = field->next) {
13281332 if ((TT.sortpos = i++)<pos && field->next) continue;
1329- going2 = TT.kfields;
1330- going2->which = field->which;
1331- going2->len = field->len;
1333+ field2 = TT.kfields;
1334+ field2->which = field->which;
1335+ field2->len = field->len;
13321336 break;
13331337 }
13341338 }
@@ -1367,7 +1371,7 @@ static void top_common(
13671371 {
13681372 long long timeout = 0, now, stats[16];
13691373 struct proclist {
1370- struct carveup **tb;
1374+ struct procpid **tb;
13711375 int count;
13721376 long long whence;
13731377 } plist[2], *plold, *plnew, old, new, mix;
@@ -1413,11 +1417,11 @@ static void top_common(
14131417 // Collate old and new into "mix", depends on /proc read in pid sort order
14141418 old = *plold;
14151419 new = *plnew;
1416- mix.tb = xmalloc((old.count+new.count)*sizeof(struct carveup));
1420+ mix.tb = xmalloc((old.count+new.count)*sizeof(struct procpid));
14171421 mix.count = 0;
14181422
14191423 while (old.count || new.count) {
1420- struct carveup *otb = old.count ? *old.tb : 0,
1424+ struct procpid *otb = old.count ? *old.tb : 0,
14211425 *ntb = new.count ? *new.tb : 0;
14221426
14231427 // If we just have old for this process, it exited. Discard it.
@@ -1448,7 +1452,7 @@ static void top_common(
14481452 char was, is;
14491453
14501454 if (recalc) {
1451- qsort(mix.tb, mix.count, sizeof(struct carveup *), (void *)ksort);
1455+ qsort(mix.tb, mix.count, sizeof(struct procpid *), (void *)ksort);
14521456 if (!(toys.optflags&FLAG_b)) {
14531457 printf("\033[H\033[J");
14541458 if (toys.signal) {
@@ -1462,16 +1466,16 @@ static void top_common(
14621466 if (recalc && !(toys.optflags&FLAG_q)) {
14631467 // Display "top" header.
14641468 if (*toys.which->name == 't') {
1465- struct strawberry alluc;
1469+ struct ofields field;
14661470 long long ll, up = 0;
14671471 long run[6];
14681472 int j;
14691473
14701474 // Count running, sleeping, stopped, zombie processes.
1471- alluc.which = PS_S;
1475+ field.which = PS_S;
14721476 memset(run, 0, sizeof(run));
14731477 for (i = 0; i<mix.count; i++)
1474- run[1+stridx("RSTZ", *string_field(mix.tb[i], &alluc))]++;
1478+ run[1+stridx("RSTZ", *string_field(mix.tb[i], &field))]++;
14751479 sprintf(toybuf,
14761480 "Tasks: %d total,%4ld running,%4ld sleeping,%4ld stopped,"
14771481 "%4ld zombie", mix.count, run[1], run[2], run[3], run[4]);
@@ -1513,24 +1517,24 @@ static void top_common(
15131517 }
15141518 lines = header_line(lines, 0);
15151519 } else {
1516- struct strawberry *fields;
1517- struct carveup tb;
1520+ struct ofields *field;
1521+ struct procpid tb;
15181522
1519- memset(&tb, 0, sizeof(struct carveup));
1523+ memset(&tb, 0, sizeof(struct procpid));
15201524 pos = stpcpy(toybuf, "Totals:");
1521- for (fields = TT.fields; fields; fields = fields->next) {
1525+ for (field = TT.fields; field; field = field->next) {
15221526 long long ll, bits = 0;
1523- int slot = typos[fields->which].slot&63;
1527+ int slot = typos[field->which].slot&63;
15241528
1525- if (fields->which<PS_C || fields->which>PS_DIO) continue;
1526- ll = 1LL<<fields->which;
1529+ if (field->which<PS_C || field->which>PS_DIO) continue;
1530+ ll = 1LL<<field->which;
15271531 if (bits&ll) continue;
15281532 bits |= ll;
15291533 for (i=0; i<mix.count; i++)
15301534 tb.slot[slot] += mix.tb[i]->slot[slot];
15311535 pos += snprintf(pos, sizeof(toybuf)/2-(pos-toybuf),
1532- " %s: %*s,", typos[fields->which].name,
1533- fields->len, string_field(&tb, fields));
1536+ " %s: %*s,", typos[field->which].name,
1537+ field->len, string_field(&tb, field));
15341538 }
15351539 *--pos = 0;
15361540 lines = header_line(lines, 0);
@@ -1587,7 +1591,7 @@ static void top_common(
15871591 timeout = 0;
15881592 break;
15891593 } else if (toupper(i)=='R')
1590- ((struct strawberry *)TT.kfields)->reverse *= -1;
1594+ ((struct ofields *)TT.kfields)->reverse *= -1;
15911595 else {
15921596 i -= 256;
15931597 if (i == KEY_LEFT) setsort(TT.sortpos-1);
@@ -1658,10 +1662,10 @@ void top_main(void)
16581662 if (!TT.top.s) TT.top.s = TT.top.O ? 3 : 9;
16591663 top_setup(toybuf, "-%CPU,-ETIME,-PID");
16601664 if (TT.top.O) {
1661- struct strawberry *fields = TT.fields;
1665+ struct ofields *field = TT.fields;
16621666
1663- fields = fields->next->next;
1664- comma_args(TT.top.O, &fields, "bad -O", parse_ko);
1667+ field = field->next->next;
1668+ comma_args(TT.top.O, &field, "bad -O", parse_ko);
16651669 }
16661670
16671671 top_common(merge_deltas);
@@ -1705,7 +1709,7 @@ struct regex_list {
17051709 regex_t reg;
17061710 };
17071711
1708-static void do_pgk(struct carveup *tb)
1712+static void do_pgk(struct procpid *tb)
17091713 {
17101714 if (TT.pgrep.signal) {
17111715 if (kill(*tb->slot, TT.pgrep.signal)) {
@@ -1726,7 +1730,7 @@ static void do_pgk(struct carveup *tb)
17261730
17271731 static void match_pgrep(void *p)
17281732 {
1729- struct carveup *tb = p;
1733+ struct procpid *tb = p;
17301734 regmatch_t match;
17311735 struct regex_list *reg;
17321736 char *name = tb->str+tb->offset[4]*!!(toys.optflags&FLAG_f);;
Show on old repository browser