external/toybox
Revision | 371dfd41efca697e72832cdf5db61ffd4c7e7a98 (tree) |
---|---|
Time | 2018-02-11 01:34:42 |
Author | Rob Landley <rob@land...> |
Commiter | Rob Landley |
Rename struct strawberry -> struct ofields, and carveup -> procpid.
The first contains display fields selectable by the -o argument,
the second contains the /proc/$PID data for one process.
@@ -286,21 +286,20 @@ GLOBALS( | ||
286 | 286 | void (*show_process)(void *tb); |
287 | 287 | ) |
288 | 288 | |
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 | |
290 | 290 | |
291 | -struct strawberry { | |
292 | - struct strawberry *next, *prev; | |
291 | +struct ofields { | |
292 | + struct ofields *next, *prev; | |
293 | 293 | short which, len, reverse; |
294 | 294 | char *title; |
295 | - char forever[]; | |
296 | 295 | }; |
297 | 296 | |
298 | 297 | /* 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 | |
301 | 300 | * for further processing once all processes have been read. |
302 | 301 | * |
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 | |
304 | 303 | * data at each position in the array. Most is read from /proc/$PID/stat (see |
305 | 304 | * https://kernel.org/doc/Documentation/filesystems/proc.txt table 1-4) but |
306 | 305 | * we we replace several fields with don't use with other data. */ |
@@ -346,7 +345,7 @@ enum { | ||
346 | 345 | starting position of each string after the first (which is always 0). */ |
347 | 346 | |
348 | 347 | // Data layout in toybuf |
349 | -struct carveup { | |
348 | +struct procpid { | |
350 | 349 | long long slot[SLOT_count]; // data (see enum above) |
351 | 350 | unsigned short offset[6]; // offset of fields in str[] (skip CMD, always 0) |
352 | 351 | char state; |
@@ -364,7 +363,7 @@ struct carveup { | ||
364 | 363 | * the display code reclaims unused padding from later fields to try to |
365 | 364 | * get the overflow back). |
366 | 365 | * |
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. | |
368 | 367 | * Setting bit |64 requests extra display/sort processing. |
369 | 368 | * |
370 | 369 | * The TAGGED_ARRAY plumbing produces an enum of indexes, the "tag" is the |
@@ -391,7 +390,7 @@ struct typography { | ||
391 | 390 | {"RTPRIO", 6, SLOT_rtprio}, {"SCH", 3, SLOT_policy}, {"CPU", 3, SLOT_taskcpu}, |
392 | 391 | {"TID", 5, SLOT_tid}, {"TCNT", 4, SLOT_tcount}, {"BIT", 3, SLOT_bits}, |
393 | 392 | |
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]) | |
395 | 394 | {"TTY", -8, -2}, {"WCHAN", -6, -3}, {"LABEL", -30, -4}, {"COMM", -27, -5}, |
396 | 395 | {"NAME", -27, -7}, {"COMMAND", -27, -5}, {"CMDLINE", -27, -6}, |
397 | 396 | {"ARGS", -27, -6}, {"CMD", -15, -1}, |
@@ -464,7 +463,7 @@ static int ps_match_process(long long *slot) | ||
464 | 463 | } |
465 | 464 | |
466 | 465 | // 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) | |
468 | 467 | { |
469 | 468 | char *buf = toybuf+sizeof(toybuf)-260, *out = buf, *s; |
470 | 469 | int which = field->which, sl = typos[which].slot; |
@@ -593,8 +592,8 @@ static char *string_field(struct carveup *tb, struct strawberry *field) | ||
593 | 592 | // Display process data that get_ps() read from /proc, formatting with TT.fields |
594 | 593 | static void show_ps(void *p) |
595 | 594 | { |
596 | - struct carveup *tb = p; | |
597 | - struct strawberry *field; | |
595 | + struct procpid *tb = p; | |
596 | + struct ofields *field; | |
598 | 597 | int pad, len, width = TT.width, abslen, sign, olen, extra = 0; |
599 | 598 | |
600 | 599 | // Loop through fields to display |
@@ -654,7 +653,7 @@ static void show_ps(void *p) | ||
654 | 653 | } |
655 | 654 | |
656 | 655 | // 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 | |
658 | 657 | // (in -k mode) or calls show_ps on toybuf (no malloc/copy/free there). |
659 | 658 | static int get_ps(struct dirtree *new) |
660 | 659 | { |
@@ -662,12 +661,12 @@ static int get_ps(struct dirtree *new) | ||
662 | 661 | char *name; // Path under /proc/$PID directory |
663 | 662 | long long bits; // Only fetch extra data if an -o field is displaying it |
664 | 663 | } fetch[] = { |
665 | - // sources for carveup->offset[] data | |
664 | + // sources for procpid->offset[] data | |
666 | 665 | {"fd/", _PS_TTY}, {"wchan", _PS_WCHAN}, {"attr/current", _PS_LABEL}, |
667 | 666 | {"exe", _PS_COMMAND|_PS_COMM}, {"cmdline", _PS_CMDLINE|_PS_ARGS|_PS_NAME}, |
668 | 667 | {"", _PS_NAME} |
669 | 668 | }; |
670 | - struct carveup *tb = (void *)toybuf; | |
669 | + struct procpid *tb = (void *)toybuf; | |
671 | 670 | long long *slot = tb->slot; |
672 | 671 | char *name, *s, *buf = tb->str, *end = 0; |
673 | 672 | int i, j, fd; |
@@ -681,7 +680,7 @@ static int get_ps(struct dirtree *new) | ||
681 | 680 | memset(slot, 0, sizeof(tb->slot)); |
682 | 681 | tb->slot[SLOT_tid] = *slot = atol(new->name); |
683 | 682 | if (TT.threadparent && TT.threadparent->extra) |
684 | - if (*slot == *(((struct carveup *)TT.threadparent->extra)->slot)) return 0; | |
683 | + if (*slot == *(((struct procpid *)TT.threadparent->extra)->slot)) return 0; | |
685 | 684 | fd = dirtree_parentfd(new); |
686 | 685 | |
687 | 686 | len = 2048; |
@@ -804,7 +803,7 @@ static int get_ps(struct dirtree *new) | ||
804 | 803 | |
805 | 804 | // For exe we readlink instead of read contents |
806 | 805 | if (j==3 || j==5) { |
807 | - struct carveup *ptb = 0; | |
806 | + struct procpid *ptb = 0; | |
808 | 807 | int k; |
809 | 808 | |
810 | 809 | // Thread doesn't have exe or argv[0], so use parent's |
@@ -925,7 +924,7 @@ static int get_ps(struct dirtree *new) | ||
925 | 924 | static int get_threads(struct dirtree *new) |
926 | 925 | { |
927 | 926 | struct dirtree *dt; |
928 | - struct carveup *tb; | |
927 | + struct procpid *tb; | |
929 | 928 | unsigned pid, kcount; |
930 | 929 | |
931 | 930 | if (!new->parent) return get_ps(new); |
@@ -975,7 +974,7 @@ static int get_threads(struct dirtree *new) | ||
975 | 974 | |
976 | 975 | static char *parse_ko(void *data, char *type, int length) |
977 | 976 | { |
978 | - struct strawberry *field; | |
977 | + struct ofields *field; | |
979 | 978 | char *width, *title, *end, *s; |
980 | 979 | int i, j, k; |
981 | 980 |
@@ -995,10 +994,11 @@ static char *parse_ko(void *data, char *type, int length) | ||
995 | 994 | if (!title) length = width-type; |
996 | 995 | } else width = 0; |
997 | 996 | |
998 | - // Allocate structure, copy title | |
999 | - field = xzalloc(sizeof(struct strawberry)+(length+1)*!!title); | |
997 | + // Allocate structure plus extra space to append a copy of title data | |
998 | + // (this way it's same lifetime, freeing struct automatically frees title) | |
999 | + field = xzalloc(sizeof(struct ofields)+(length+1)*!!title); | |
1000 | 1000 | if (title) { |
1001 | - memcpy(field->title = field->forever, title, length); | |
1001 | + memcpy(field->title = (char *)(field+1), title, length); | |
1002 | 1002 | field->title[field->len = length] = 0; |
1003 | 1003 | } |
1004 | 1004 |
@@ -1036,15 +1036,15 @@ static char *parse_ko(void *data, char *type, int length) | ||
1036 | 1036 | return 0; |
1037 | 1037 | } |
1038 | 1038 | |
1039 | -static long long get_headers(struct strawberry *fields, char *buf, int blen) | |
1039 | +static long long get_headers(struct ofields *field, char *buf, int blen) | |
1040 | 1040 | { |
1041 | 1041 | long long bits = 0; |
1042 | 1042 | int len = 0; |
1043 | 1043 | |
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; | |
1044 | + for (; field; field = field->next) { | |
1045 | + len += snprintf(buf+len, blen-len, " %*s"+!bits, field->len, | |
1046 | + field->title); | |
1047 | + bits |= 1LL<<field->which; | |
1048 | 1048 | } |
1049 | 1049 | |
1050 | 1050 | return bits; |
@@ -1131,8 +1131,8 @@ static char *parse_rest(void *data, char *str, int len) | ||
1131 | 1131 | // sort for -k |
1132 | 1132 | static int ksort(void *aa, void *bb) |
1133 | 1133 | { |
1134 | - struct strawberry *field; | |
1135 | - struct carveup *ta = *(struct carveup **)aa, *tb = *(struct carveup **)bb; | |
1134 | + struct ofields *field; | |
1135 | + struct procpid *ta = *(struct procpid **)aa, *tb = *(struct procpid **)bb; | |
1136 | 1136 | int ret = 0, slot; |
1137 | 1137 | |
1138 | 1138 | for (field = TT.kfields; field && !ret; field = field->next) { |
@@ -1156,7 +1156,7 @@ static int ksort(void *aa, void *bb) | ||
1156 | 1156 | return ret; |
1157 | 1157 | } |
1158 | 1158 | |
1159 | -static struct carveup **collate_leaves(struct carveup **tb, struct dirtree *dt) | |
1159 | +static struct procpid **collate_leaves(struct procpid **tb, struct dirtree *dt) | |
1160 | 1160 | { |
1161 | 1161 | while (dt) { |
1162 | 1162 | struct dirtree *next = dt->next; |
@@ -1170,9 +1170,9 @@ static struct carveup **collate_leaves(struct carveup **tb, struct dirtree *dt) | ||
1170 | 1170 | return tb; |
1171 | 1171 | } |
1172 | 1172 | |
1173 | -static struct carveup **collate(int count, struct dirtree *dt) | |
1173 | +static struct procpid **collate(int count, struct dirtree *dt) | |
1174 | 1174 | { |
1175 | - struct carveup **tbsort = xmalloc(count*sizeof(struct carveup *)); | |
1175 | + struct procpid **tbsort = xmalloc(count*sizeof(struct procpid *)); | |
1176 | 1176 | |
1177 | 1177 | collate_leaves(tbsort, dt); |
1178 | 1178 |
@@ -1244,20 +1244,20 @@ void ps_main(void) | ||
1244 | 1244 | default_ko(toybuf, &TT.fields, "bad -o", TT.ps.o); |
1245 | 1245 | |
1246 | 1246 | if (TT.ps.O) { |
1247 | - if (TT.fields) TT.fields = ((struct strawberry *)TT.fields)->prev; | |
1247 | + if (TT.fields) TT.fields = ((struct ofields *)TT.fields)->prev; | |
1248 | 1248 | comma_args(TT.ps.O, &TT.fields, "bad -O", parse_ko); |
1249 | - if (TT.fields) TT.fields = ((struct strawberry *)TT.fields)->next; | |
1249 | + if (TT.fields) TT.fields = ((struct ofields *)TT.fields)->next; | |
1250 | 1250 | } |
1251 | 1251 | dlist_terminate(TT.fields); |
1252 | 1252 | |
1253 | 1253 | // -f and -n change the meaning of some fields |
1254 | 1254 | if (toys.optflags&(FLAG_f|FLAG_n)) { |
1255 | - struct strawberry *ever; | |
1255 | + struct ofields *field; | |
1256 | 1256 | |
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--; | |
1257 | + for (field = TT.fields; field; field = field->next) { | |
1258 | + if ((toys.optflags&FLAG_n) && field->which>=PS_UID | |
1259 | + && field->which<=PS_RGROUP && (typos[field->which].slot&64)) | |
1260 | + field->which--; | |
1261 | 1261 | } |
1262 | 1262 | } |
1263 | 1263 |
@@ -1272,11 +1272,11 @@ void ps_main(void) | ||
1272 | 1272 | ? get_threads : get_ps); |
1273 | 1273 | |
1274 | 1274 | if ((dt != DIRTREE_ABORTVAL) && toys.optflags&(FLAG_k|FLAG_M)) { |
1275 | - struct carveup **tbsort = collate(TT.kcount, dt); | |
1275 | + struct procpid **tbsort = collate(TT.kcount, dt); | |
1276 | 1276 | |
1277 | 1277 | if (toys.optflags&FLAG_M) { |
1278 | 1278 | for (i = 0; i<TT.kcount; i++) { |
1279 | - struct strawberry *field; | |
1279 | + struct ofields *field; | |
1280 | 1280 | |
1281 | 1281 | for (field = TT.fields; field; field = field->next) { |
1282 | 1282 | int len = strlen(string_field(tbsort[i], field)); |
@@ -1291,7 +1291,7 @@ void ps_main(void) | ||
1291 | 1291 | } |
1292 | 1292 | |
1293 | 1293 | if (toys.optflags&FLAG_k) |
1294 | - qsort(tbsort, TT.kcount, sizeof(struct carveup *), (void *)ksort); | |
1294 | + qsort(tbsort, TT.kcount, sizeof(struct procpid *), (void *)ksort); | |
1295 | 1295 | for (i = 0; i<TT.kcount; i++) { |
1296 | 1296 | show_ps(tbsort[i]); |
1297 | 1297 | free(tbsort[i]); |
@@ -1319,16 +1319,16 @@ void ps_main(void) | ||
1319 | 1319 | // select which of the -o fields to sort by |
1320 | 1320 | static void setsort(int pos) |
1321 | 1321 | { |
1322 | - struct strawberry *field, *going2; | |
1322 | + struct ofields *field, *field2; | |
1323 | 1323 | int i = 0; |
1324 | 1324 | |
1325 | 1325 | if (pos<0) pos = 0; |
1326 | 1326 | |
1327 | 1327 | for (field = TT.fields; field; field = field->next) { |
1328 | 1328 | if ((TT.sortpos = i++)<pos && field->next) continue; |
1329 | - going2 = TT.kfields; | |
1330 | - going2->which = field->which; | |
1331 | - going2->len = field->len; | |
1329 | + field2 = TT.kfields; | |
1330 | + field2->which = field->which; | |
1331 | + field2->len = field->len; | |
1332 | 1332 | break; |
1333 | 1333 | } |
1334 | 1334 | } |
@@ -1367,7 +1367,7 @@ static void top_common( | ||
1367 | 1367 | { |
1368 | 1368 | long long timeout = 0, now, stats[16]; |
1369 | 1369 | struct proclist { |
1370 | - struct carveup **tb; | |
1370 | + struct procpid **tb; | |
1371 | 1371 | int count; |
1372 | 1372 | long long whence; |
1373 | 1373 | } plist[2], *plold, *plnew, old, new, mix; |
@@ -1413,11 +1413,11 @@ static void top_common( | ||
1413 | 1413 | // Collate old and new into "mix", depends on /proc read in pid sort order |
1414 | 1414 | old = *plold; |
1415 | 1415 | new = *plnew; |
1416 | - mix.tb = xmalloc((old.count+new.count)*sizeof(struct carveup)); | |
1416 | + mix.tb = xmalloc((old.count+new.count)*sizeof(struct procpid)); | |
1417 | 1417 | mix.count = 0; |
1418 | 1418 | |
1419 | 1419 | while (old.count || new.count) { |
1420 | - struct carveup *otb = old.count ? *old.tb : 0, | |
1420 | + struct procpid *otb = old.count ? *old.tb : 0, | |
1421 | 1421 | *ntb = new.count ? *new.tb : 0; |
1422 | 1422 | |
1423 | 1423 | // If we just have old for this process, it exited. Discard it. |
@@ -1448,7 +1448,7 @@ static void top_common( | ||
1448 | 1448 | char was, is; |
1449 | 1449 | |
1450 | 1450 | if (recalc) { |
1451 | - qsort(mix.tb, mix.count, sizeof(struct carveup *), (void *)ksort); | |
1451 | + qsort(mix.tb, mix.count, sizeof(struct procpid *), (void *)ksort); | |
1452 | 1452 | if (!(toys.optflags&FLAG_b)) { |
1453 | 1453 | printf("\033[H\033[J"); |
1454 | 1454 | if (toys.signal) { |
@@ -1462,16 +1462,16 @@ static void top_common( | ||
1462 | 1462 | if (recalc && !(toys.optflags&FLAG_q)) { |
1463 | 1463 | // Display "top" header. |
1464 | 1464 | if (*toys.which->name == 't') { |
1465 | - struct strawberry alluc; | |
1465 | + struct ofields field; | |
1466 | 1466 | long long ll, up = 0; |
1467 | 1467 | long run[6]; |
1468 | 1468 | int j; |
1469 | 1469 | |
1470 | 1470 | // Count running, sleeping, stopped, zombie processes. |
1471 | - alluc.which = PS_S; | |
1471 | + field.which = PS_S; | |
1472 | 1472 | memset(run, 0, sizeof(run)); |
1473 | 1473 | for (i = 0; i<mix.count; i++) |
1474 | - run[1+stridx("RSTZ", *string_field(mix.tb[i], &alluc))]++; | |
1474 | + run[1+stridx("RSTZ", *string_field(mix.tb[i], &field))]++; | |
1475 | 1475 | sprintf(toybuf, |
1476 | 1476 | "Tasks: %d total,%4ld running,%4ld sleeping,%4ld stopped," |
1477 | 1477 | "%4ld zombie", mix.count, run[1], run[2], run[3], run[4]); |
@@ -1513,24 +1513,24 @@ static void top_common( | ||
1513 | 1513 | } |
1514 | 1514 | lines = header_line(lines, 0); |
1515 | 1515 | } else { |
1516 | - struct strawberry *fields; | |
1517 | - struct carveup tb; | |
1516 | + struct ofields *field; | |
1517 | + struct procpid tb; | |
1518 | 1518 | |
1519 | - memset(&tb, 0, sizeof(struct carveup)); | |
1519 | + memset(&tb, 0, sizeof(struct procpid)); | |
1520 | 1520 | pos = stpcpy(toybuf, "Totals:"); |
1521 | - for (fields = TT.fields; fields; fields = fields->next) { | |
1521 | + for (field = TT.fields; field; field = field->next) { | |
1522 | 1522 | long long ll, bits = 0; |
1523 | - int slot = typos[fields->which].slot&63; | |
1523 | + int slot = typos[field->which].slot&63; | |
1524 | 1524 | |
1525 | - if (fields->which<PS_C || fields->which>PS_DIO) continue; | |
1526 | - ll = 1LL<<fields->which; | |
1525 | + if (field->which<PS_C || field->which>PS_DIO) continue; | |
1526 | + ll = 1LL<<field->which; | |
1527 | 1527 | if (bits&ll) continue; |
1528 | 1528 | bits |= ll; |
1529 | 1529 | for (i=0; i<mix.count; i++) |
1530 | 1530 | tb.slot[slot] += mix.tb[i]->slot[slot]; |
1531 | 1531 | pos += snprintf(pos, sizeof(toybuf)/2-(pos-toybuf), |
1532 | - " %s: %*s,", typos[fields->which].name, | |
1533 | - fields->len, string_field(&tb, fields)); | |
1532 | + " %s: %*s,", typos[field->which].name, | |
1533 | + field->len, string_field(&tb, field)); | |
1534 | 1534 | } |
1535 | 1535 | *--pos = 0; |
1536 | 1536 | lines = header_line(lines, 0); |
@@ -1587,7 +1587,7 @@ static void top_common( | ||
1587 | 1587 | timeout = 0; |
1588 | 1588 | break; |
1589 | 1589 | } else if (toupper(i)=='R') |
1590 | - ((struct strawberry *)TT.kfields)->reverse *= -1; | |
1590 | + ((struct ofields *)TT.kfields)->reverse *= -1; | |
1591 | 1591 | else { |
1592 | 1592 | i -= 256; |
1593 | 1593 | if (i == KEY_LEFT) setsort(TT.sortpos-1); |
@@ -1658,10 +1658,10 @@ void top_main(void) | ||
1658 | 1658 | if (!TT.top.s) TT.top.s = TT.top.O ? 3 : 9; |
1659 | 1659 | top_setup(toybuf, "-%CPU,-ETIME,-PID"); |
1660 | 1660 | if (TT.top.O) { |
1661 | - struct strawberry *fields = TT.fields; | |
1661 | + struct ofields *field = TT.fields; | |
1662 | 1662 | |
1663 | - fields = fields->next->next; | |
1664 | - comma_args(TT.top.O, &fields, "bad -O", parse_ko); | |
1663 | + field = field->next->next; | |
1664 | + comma_args(TT.top.O, &field, "bad -O", parse_ko); | |
1665 | 1665 | } |
1666 | 1666 | |
1667 | 1667 | top_common(merge_deltas); |
@@ -1705,7 +1705,7 @@ struct regex_list { | ||
1705 | 1705 | regex_t reg; |
1706 | 1706 | }; |
1707 | 1707 | |
1708 | -static void do_pgk(struct carveup *tb) | |
1708 | +static void do_pgk(struct procpid *tb) | |
1709 | 1709 | { |
1710 | 1710 | if (TT.pgrep.signal) { |
1711 | 1711 | if (kill(*tb->slot, TT.pgrep.signal)) { |
@@ -1726,7 +1726,7 @@ static void do_pgk(struct carveup *tb) | ||
1726 | 1726 | |
1727 | 1727 | static void match_pgrep(void *p) |
1728 | 1728 | { |
1729 | - struct carveup *tb = p; | |
1729 | + struct procpid *tb = p; | |
1730 | 1730 | regmatch_t match; |
1731 | 1731 | struct regex_list *reg; |
1732 | 1732 | char *name = tb->str+tb->offset[4]*!!(toys.optflags&FLAG_f);; |