summaryrefslogtreecommitdiffstats
path: root/commands/test.c
diff options
context:
space:
mode:
Diffstat (limited to 'commands/test.c')
-rw-r--r--commands/test.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/commands/test.c b/commands/test.c
index c4f493860f..86636de1c2 100644
--- a/commands/test.c
+++ b/commands/test.c
@@ -40,6 +40,8 @@ typedef enum {
OPT_DIRECTORY,
OPT_FILE,
OPT_EXISTS,
+ OPT_BLOCK,
+ OPT_CHAR,
OPT_SYMBOLIC_LINK,
OPT_MAX,
} test_opts;
@@ -60,6 +62,8 @@ static char *test_options[] = {
[OPT_FILE] = "-f",
[OPT_DIRECTORY] = "-d",
[OPT_EXISTS] = "-e",
+ [OPT_BLOCK] = "-b",
+ [OPT_CHAR] = "-c",
[OPT_SYMBOLIC_LINK] = "-L",
};
@@ -129,8 +133,11 @@ static int do_test(int argc, char *argv[])
case OPT_ZERO:
case OPT_NONZERO:
adv = 2;
+ if (left < 2)
+ break;
zero = 1;
- if (ap[1] && *ap[1] != ']' && strlen(ap[1]))
+
+ if (strlen(ap[1]))
zero = 0;
expr = (opt == OPT_ZERO) ? zero : !zero;
@@ -139,9 +146,13 @@ static int do_test(int argc, char *argv[])
case OPT_FILE:
case OPT_DIRECTORY:
case OPT_EXISTS:
+ case OPT_BLOCK:
+ case OPT_CHAR:
case OPT_SYMBOLIC_LINK:
adv = 2;
- if (ap[1] && *ap[1] != ']' && strlen(ap[1])) {
+ if (left < 2)
+ break;
+ if (strlen(ap[1])) {
expr = (opt == OPT_SYMBOLIC_LINK ? lstat : stat)(ap[1], &statbuf);
if (expr < 0) {
expr = 0;
@@ -164,16 +175,22 @@ static int do_test(int argc, char *argv[])
expr = 1;
break;
}
+ if (opt == OPT_BLOCK && S_ISBLK(statbuf.st_mode)) {
+ expr = 1;
+ break;
+ }
+ if (opt == OPT_CHAR && S_ISCHR(statbuf.st_mode)) {
+ expr = 1;
+ break;
+ }
}
break;
/* three argument options */
default:
adv = 3;
- if (left < 3) {
- expr = 1;
+ if (left < 3)
break;
- }
a = simple_strtol(ap[0], NULL, 0);
b = simple_strtol(ap[2], NULL, 0);
@@ -208,6 +225,11 @@ static int do_test(int argc, char *argv[])
}
}
+ if (left < adv) {
+ printf("test: failed to parse arguments\n");
+ return 1;
+ }
+
if (last_cmp == 0)
expr = last_expr || expr;
else if (last_cmp == 1)