]> granicus.if.org Git - strace/commitdiff
Change parser of fault expressions to conform the documentation
authorDmitry V. Levin <ldv@altlinux.org>
Fri, 25 Nov 2016 23:47:32 +0000 (23:47 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Fri, 25 Nov 2016 23:47:32 +0000 (23:47 +0000)
Make expressions like fault=SYSCALL1,SYSCALL2:error=EPERM work
as documented, i.e. fail both SYSCALL1 and SYSCALL2 with EPERM.

* syscall.c (parse_fault_expression): Remove const qualifier from
"name" and "token: variables, as well as from the return value.
(qual_fault): Remove const qualifier from "name" variables.
Split "name" into comma delimited tokens and pass each token
to individual qual_syscall_ex call.
(qualify): For QUAL_FAULT options, pass the whole option value
to their qualify methods without prior splitting into comma
delimited tokens.
* tests/fault_injection.test: Check it.
* tests/fault_syntax.test: Check empty syscall sets.

syscall.c
tests/fault_injection.test
tests/fault_syntax.test

index 4143bc0cfdd2e65acb16bdb67b426d68b23c9fed..57c2945a4a24fd44357924844c287068737ad514 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -628,13 +628,13 @@ parse_fault_token(const char *const token, struct fault_opts *const fopts)
        return true;
 }
 
-static const char *
+static char *
 parse_fault_expression(const char *const s, char **buf,
                       struct fault_opts *const fopts)
 {
        char *saveptr = NULL;
-       const char *name = NULL;
-       const char *token;
+       char *name = NULL;
+       char *token;
 
        *buf = xstrdup(s);
        for (token = strtok_r(*buf, ":", &saveptr); token;
@@ -663,12 +663,20 @@ qual_fault(const char *const s, const unsigned int bitflag, const int not)
        };
 
        char *buf = NULL;
-       const char *name = parse_fault_expression(s, &buf, &opts);
+       char *name = parse_fault_expression(s, &buf, &opts);
+       char *saveptr = NULL;
+       const char *token;
+       int rc = -1;
 
        if (!name)
                return -1;
 
-       int rc = qual_syscall_ex(name, bitflag, not, &opts);
+       for (token = strtok_r(name, ",", &saveptr); token;
+            token = strtok_r(NULL, ",", &saveptr)) {
+               rc = qual_syscall_ex(token, bitflag, not, &opts);
+               if (rc)
+                       break;
+       }
 
        free(buf);
        return rc;
@@ -744,16 +752,21 @@ qualify(const char *s)
                not = 1 - not;
                s = "all";
        }
-       if (opt->bitflag != QUAL_FAULT) {
-               if (strcmp(s, "all") == 0) {
-                       for (i = 0; i < num_quals; ++i) {
-                               qualify_one(i, opt->bitflag, not, -1, NULL);
-                       }
-                       return;
+       if (opt->bitflag == QUAL_FAULT) {
+               if (opt->qualify(s, opt->bitflag, not)) {
+                       error_msg_and_die("invalid %s '%s'",
+                               opt->argument_name, s);
                }
+               return;
+       }
+       if (strcmp(s, "all") == 0) {
                for (i = 0; i < num_quals; ++i) {
-                       qualify_one(i, opt->bitflag, !not, -1, NULL);
+                       qualify_one(i, opt->bitflag, not, -1, NULL);
                }
+               return;
+       }
+       for (i = 0; i < num_quals; ++i) {
+               qualify_one(i, opt->bitflag, !not, -1, NULL);
        }
        copy = xstrdup(s);
        for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) {
index 004bcb0dbc4c79537f370567487427ef8a2bec1a..40d44aac0f8f36e33ca5b8ac1aba57e4b7712a85 100755 (executable)
@@ -85,7 +85,7 @@ check_fault_injection()
 }
 
 for err in '' ENOSYS 22 EINVAL; do
-       for fault in writev 51,desc; do
+       for fault in writev desc,51; do
                check_fault_injection \
                        writev $fault "$err" '' '' -efault=chdir
                for F in 1 2 3 5 7 11; do
index 97766d258bb8699c7d9f3557e04714324ef7925f..bd306bb37440d2440bb5653401fbe9ae1995a078 100755 (executable)
@@ -40,7 +40,8 @@ fail_with()
                "strace -e fault=$* failed to handle an argument error properly"
 }
 
-for arg in invalid_syscall_name \
+for arg in '' , ,, ,,, : :: ::: \
+          invalid_syscall_name \
           invalid_syscall_name:when=3 \
           -1 \
           -1:when=4 \