summaryrefslogtreecommitdiffstats
path: root/bin/sh/var.c
diff options
context:
space:
mode:
authorstefanf <stefanf@FreeBSD.org>2006-04-29 12:57:53 +0000
committerstefanf <stefanf@FreeBSD.org>2006-04-29 12:57:53 +0000
commitac3eb05d71b3f6ce3588c6baf390403ab84d6ba4 (patch)
tree46b9d7095fc66e8ee35724b30c26992f34f72cec /bin/sh/var.c
parentf2c5013e89cb7741bd6f283d5d97ba567a882973 (diff)
downloadFreeBSD-src-ac3eb05d71b3f6ce3588c6baf390403ab84d6ba4.zip
FreeBSD-src-ac3eb05d71b3f6ce3588c6baf390403ab84d6ba4.tar.gz
POSIX demands that set's output (when invoked without arguments) should be
sorted. Sort the variables before printing. PR: 96415
Diffstat (limited to 'bin/sh/var.c')
-rw-r--r--bin/sh/var.c56
1 files changed, 47 insertions, 9 deletions
diff --git a/bin/sh/var.c b/bin/sh/var.c
index c7c7bff..4dc54b0 100644
--- a/bin/sh/var.c
+++ b/bin/sh/var.c
@@ -479,6 +479,21 @@ shprocvar(void)
}
+static int
+var_compare(const void *a, const void *b)
+{
+ const char *const *sa, *const *sb;
+
+ sa = a;
+ sb = b;
+ /*
+ * This compares two var=value strings which creates a different
+ * order from what you would probably expect. POSIX is somewhat
+ * ambiguous on what should be sorted exactly.
+ */
+ return strcoll(*sa, *sb);
+}
+
/*
* Command to list all variables which are set. Currently this command
@@ -492,18 +507,41 @@ showvarscmd(int argc __unused, char **argv __unused)
struct var **vpp;
struct var *vp;
const char *s;
+ const char **vars;
+ int i, n;
- for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
- for (vp = *vpp ; vp ; vp = vp->next) {
- if (vp->flags & VUNSET)
- continue;
- for (s = vp->text; *s != '='; s++)
- out1c(*s);
- out1c('=');
- out1qstr(s + 1);
- out1c('\n');
+ /*
+ * POSIX requires us to sort the variables.
+ */
+ n = 0;
+ for (vpp = vartab; vpp < vartab + VTABSIZE; vpp++) {
+ for (vp = *vpp; vp; vp = vp->next) {
+ if (!(vp->flags & VUNSET))
+ n++;
}
}
+
+ INTON;
+ vars = ckmalloc(n * sizeof(*vars));
+ i = 0;
+ for (vpp = vartab; vpp < vartab + VTABSIZE; vpp++) {
+ for (vp = *vpp; vp; vp = vp->next) {
+ if (!(vp->flags & VUNSET))
+ vars[i++] = vp->text;
+ }
+ }
+
+ qsort(vars, n, sizeof(*vars), var_compare);
+ for (i = 0; i < n; i++) {
+ for (s = vars[i]; *s != '='; s++)
+ out1c(*s);
+ out1c('=');
+ out1qstr(s + 1);
+ out1c('\n');
+ }
+ ckfree(vars);
+ INTOFF;
+
return 0;
}
OpenPOWER on IntegriCloud