aboutsummaryrefslogtreecommitdiff
path: root/toys/posix
diff options
context:
space:
mode:
Diffstat (limited to 'toys/posix')
-rw-r--r--toys/posix/ps.c62
1 files changed, 44 insertions, 18 deletions
diff --git a/toys/posix/ps.c b/toys/posix/ps.c
index abeb9ce5..95f8b9f9 100644
--- a/toys/posix/ps.c
+++ b/toys/posix/ps.c
@@ -145,6 +145,14 @@ struct strawberry {
char forever[];
};
+// Data layout in toybuf
+struct carveup {
+ long long slot[50]; // data from /proc, skippint #2 and #3
+ unsigned short offset[4]; // offset of fields in str[] (skip name, always 0)
+ char state;
+ char str[]; // name, tty, wchan, attr, cmdline
+};
+
// Return 1 to keep, 0 to discard
static int match_process(long long *slot)
{
@@ -174,14 +182,6 @@ static int match_process(long long *slot)
return 1;
}
-// Data layout in toybuf
-struct carveup {
- long long slot[50]; // data from /proc, skippint #2 and #3
- unsigned short offset[4]; // offset of fields in str[] (skip name, always 0)
- char state;
- char str[]; // name, tty, wchan, attr, cmdline
-};
-
static char *string_field(struct carveup *tb, struct strawberry *field)
{
char *buf = toybuf+sizeof(toybuf)-64, *out = buf, *s;
@@ -667,8 +667,28 @@ static char *parse_rest(char *str, int len)
// sort for -k
static int ksort(void *aa, void *bb)
{
- // TODO: sort!
- return 1;
+ long long lla, llb;
+ char *out, *end;
+
+ // Convert fields to string version, saving first in toybuf
+ out = string_field((void *)aa, TT.fields);
+ memccpy(toybuf, out, 0, 2048);
+ toybuf[2048] = 0;
+ out = string_field((void *)bb, TT.fields);
+
+ // Numeric comparison?
+ llb = strtoll(out, &end, 10);
+ if (!*end) {
+ lla = strtoll(toybuf, &end, 10);
+ if (!*end) {
+ if (lla<llb) return -1;
+ if (lla>llb) return 1;
+ return 0;
+ }
+ }
+
+ // String compare
+ return strcmp(toybuf, out);
}
void ps_main(void)
@@ -736,21 +756,27 @@ void ps_main(void)
dt = dirtree_read("/proc", get_ps);
if (toys.optflags&FLAG_k) {
- struct dirtree **dtsort = xmalloc(TT.kcount*sizeof(struct dirtree *));
+ struct carveup **tbsort = xmalloc(TT.kcount*sizeof(struct carveup *));
// descend into child list
- *dtsort = dt;
+ *tbsort = (void *)dt;
dt = dt->child;
- free(*dtsort);
+ free(*tbsort);
// populate array
i = 0;
- for (i = 0; dt; dt = dt->next) dtsort[i++] = dt;
- qsort(dtsort, TT.kcount, sizeof(struct dirtree *), (void *)ksort);
+ while (dt) {
+ void *temp = dt->next;
+
+ tbsort[i++] = (void *)dt->extra;
+ free(dt);
+ dt = temp;
+ }
+
+ qsort(tbsort, TT.kcount, sizeof(struct dirtree *), (void *)ksort);
for (i = 0; i<TT.kcount; i++) {
- show_ps((void *)dtsort[i]->extra);
- free((void *)dtsort[i]->extra);
- free(dtsort[i]);
+ show_ps(tbsort[i]);
+ free(tbsort[i]);
}
}