]> granicus.if.org Git - strace/blobdiff - qualify.c
tests: check decoding of netlink smc_diag_msg attributes
[strace] / qualify.c
index 006f207d9acb87770637b3a78acbba1e68c95b73..3df4805a46ae317f639f9096f5975e2dfce4597c 100644 (file)
--- a/qualify.c
+++ b/qualify.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
+ * Copyright (c) 2016-2017 The strace developers.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -262,8 +263,13 @@ lookup_class(const char *s)
                { "%signal",    TRACE_SIGNAL    },
                { "%ipc",       TRACE_IPC       },
                { "%network",   TRACE_NETWORK   },
-               { "%sched",     TRACE_SCHED     },
+               { "%stat",      TRACE_STAT      },
+               { "%lstat",     TRACE_LSTAT     },
+               { "%fstat",     TRACE_FSTAT     },
+               { "%%stat",     TRACE_STAT_LIKE },
                { "%statfs",    TRACE_STATFS    },
+               { "%fstatfs",   TRACE_FSTATFS   },
+               { "%%statfs",   TRACE_STATFS_LIKE       },
        };
 
        unsigned int i;
@@ -324,12 +330,19 @@ qualify_syscall_name(const char *s, struct number_set *set)
 static bool
 qualify_syscall(const char *token, struct number_set *set)
 {
+       bool ignore_fail = false;
+
+       while (*token == '?') {
+               token++;
+               ignore_fail = true;
+       }
        if (*token >= '0' && *token <= '9')
-               return qualify_syscall_number(token, set);
+               return qualify_syscall_number(token, set) || ignore_fail;
        if (*token == '/')
-               return qualify_syscall_regex(token + 1, set);
+               return qualify_syscall_regex(token + 1, set) || ignore_fail;
        return qualify_syscall_class(token, set)
-              || qualify_syscall_name(token, set);
+              || qualify_syscall_name(token, set)
+              || ignore_fail;
 }
 
 /*
@@ -401,18 +414,6 @@ handle_inversion:
        }
 }
 
-/*
- * Returns NULL if STR does not start with PREFIX,
- * or a pointer to the first char in STR after PREFIX.
- */
-static const char *
-strip_prefix(const char *prefix, const char *str)
-{
-       size_t len = strlen(prefix);
-
-       return strncmp(prefix, str, len) ? NULL : str + len;
-}
-
 static int
 find_errno_by_name(const char *name)
 {
@@ -433,9 +434,9 @@ parse_inject_token(const char *const token, struct inject_opts *const fopts,
        const char *val;
        int intval;
 
-       if ((val = strip_prefix("when=", token))) {
+       if ((val = STR_STRIP_PREFIX(token, "when=")) != token) {
                /*
-                *      == 1+1
+                *      == 1+1
                 * F    == F+0
                 * F+   == F+1
                 * F+S
@@ -463,7 +464,7 @@ parse_inject_token(const char *const token, struct inject_opts *const fopts,
                        /* F == F+0 */
                        fopts->step = 0;
                }
-       } else if ((val = strip_prefix("error=", token))) {
+       } else if ((val = STR_STRIP_PREFIX(token, "error=")) != token) {
                if (fopts->rval != INJECT_OPTS_RVAL_DEFAULT)
                        return false;
                intval = string_to_uint_upto(val, MAX_ERRNO_VALUE);
@@ -472,14 +473,16 @@ parse_inject_token(const char *const token, struct inject_opts *const fopts,
                if (intval < 1)
                        return false;
                fopts->rval = -intval;
-       } else if (!fault_tokens_only && (val = strip_prefix("retval=", token))) {
+       } else if (!fault_tokens_only
+                  && (val = STR_STRIP_PREFIX(token, "retval=")) != token) {
                if (fopts->rval != INJECT_OPTS_RVAL_DEFAULT)
                        return false;
                intval = string_to_uint(val);
                if (intval < 0)
                        return false;
                fopts->rval = intval;
-       } else if (!fault_tokens_only && (val = strip_prefix("signal=", token))) {
+       } else if (!fault_tokens_only
+                  && (val = STR_STRIP_PREFIX(token, "signal=")) != token) {
                intval = sigstr_to_uint(val);
                if (intval < 1 || intval > NSIG_BYTES * 8)
                        return false;
@@ -664,14 +667,14 @@ qualify(const char *str)
        unsigned int i;
 
        for (i = 0; i < ARRAY_SIZE(qual_options); ++i) {
-               const char *p = qual_options[i].name;
-               unsigned int len = strlen(p);
+               const char *name = qual_options[i].name;
+               const size_t len = strlen(name);
+               const char *val = str_strip_prefix_len(str, name, len);
 
-               if (strncmp(str, p, len) || str[len] != '=')
+               if (val == str || *val != '=')
                        continue;
-
+               str = val + 1;
                opt = &qual_options[i];
-               str += len + 1;
                break;
        }