* basic_actions.c (parse_inject, parse_fault, apply_fault): Implement.
(apply_inject): Change inject private data.
* defs.h (inject_vec): Remove.
(inject_opts): Add init flag.
* filter.h (parse_inject_token): Add definition.
* filter_action.c: Add fault action.
* filter_qualify.c (parse_inject_common): Generate new inject private data.
---
 basic_actions.c  | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 defs.h           |  2 +-
 filter.h         |  2 ++
 filter_action.c  |  3 ++
 filter_qualify.c | 42 ++++++++++---------------
 5 files changed, 108 insertions(+), 36 deletions(-)

diff --git a/basic_actions.c b/basic_actions.c
index de87cde..1eb597e 100644
--- a/basic_actions.c
+++ b/basic_actions.c
@@ -25,6 +25,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "defs.h"
+#include "filter.h"
 
 bool
 is_traced(struct tcb *tcp)
@@ -49,50 +50,134 @@ apply_trace(struct tcb *tcp, void *_priv_data)
 {
        tcp->qual_flg |= QUAL_TRACE;
 }
+
+struct inject_priv_data {
+       struct inject_opts opts;
+       struct inject_opts **inject_vec;
+};
+
 void
 apply_inject(struct tcb *tcp, void *_priv_data)
 {
-       struct inject_opts **inject_vec = (struct inject_opts **)_priv_data;
+       struct inject_priv_data *data = (struct inject_priv_data *)_priv_data;
+       struct inject_opts *opts;
+       if (!(scno_in_range(tcp->scno) && 
data->inject_vec[current_personality]))
+               return;
+       opts = &data->inject_vec[current_personality][tcp->scno];
+       if (!opts->init) {
+               data->inject_vec[current_personality][tcp->scno] = data->opts;
+               opts = &data->inject_vec[current_personality][tcp->scno];
+               opts->init = true;
+       }
        tcp->qual_flg |= QUAL_INJECT;
-       tcp->inject_opts = (scno_in_range(tcp->scno) && 
inject_vec[current_personality])
-              ? &inject_vec[current_personality][tcp->scno] : NULL;
+       tcp->inject_opts = opts;
 }
-void*
+
+static void *
+parse_inject_common_args(const char *const str,
+                         const bool fault_tokens_only,
+                         const char *const description)
+{
+       struct inject_priv_data *data = xmalloc(sizeof(struct 
inject_priv_data));
+       data->inject_vec = xcalloc(SUPPORTED_PERSONALITIES,
+                                  sizeof(struct inject_opts *));
+       unsigned int p;
+       for (p = 0; p < SUPPORTED_PERSONALITIES; ++p) {
+               data->inject_vec[p] = xcalloc(nsyscall_vec[p],
+                                             sizeof(struct inject_opts));
+       }
+       data->opts.first = 1;
+       data->opts.step = 1;
+       data->opts.rval = INJECT_OPTS_RVAL_DEFAULT;
+       data->opts.signo = 0;
+       if (!str) {
+               if (fault_tokens_only) {
+                       data->opts.rval = -ENOSYS;
+                       return data;
+               } else {
+                       error_msg_and_die("inject argument is required");
+               }
+       }
+       char *buf = xstrdup(str);
+       char *saveptr = NULL;
+       char *token;
+       for (token = strtok_r(buf, ";", &saveptr); token;
+            token = strtok_r(NULL, ";", &saveptr)) {
+               if (!parse_inject_token(token, &data->opts, fault_tokens_only))
+                       error_msg_and_die("invalid %s argument '%s'",
+                                         description, token);
+       }
+       free(buf);
+       if (data->opts.rval == INJECT_OPTS_RVAL_DEFAULT && !data->opts.signo) {
+               if (fault_tokens_only) {
+                       data->opts.rval = -ENOSYS;
+               } else {
+                       error_msg_and_die("invalid %s arguments '%s'",
+                                         description, str);
+               }
+       }
+       return data;
+}
+
+void *
 parse_inject(const char *str)
 {
-       return NULL;
+       return parse_inject_common_args(str, false, "inject");
 }
+
 void free_inject(void *_priv_data)
 {
-       struct inject_opts **vec = (struct inject_opts **)_priv_data;
+       struct inject_priv_data *data = (struct inject_priv_data *)_priv_data;
        unsigned int p;
        for (p = 0; p < SUPPORTED_PERSONALITIES; ++p)
-               if (vec[p])
-                       free(vec[p]);
-       free(vec);
+               if (data->inject_vec[p])
+                       free(data->inject_vec[p]);
+       free(data->inject_vec);
+       free(data);
 }
+
 void
 apply_read(struct tcb *tcp, void *_priv_data)
 {
        tcp->qual_flg |= QUAL_READ;
 }
+
 void
 apply_write(struct tcb *tcp, void *_priv_data)
 {
        tcp->qual_flg |= QUAL_WRITE;
 }
+
 void
 apply_raw(struct tcb *tcp, void *_priv_data)
 {
        tcp->qual_flg |= QUAL_RAW;
 }
+
 void
 apply_abbrev(struct tcb *tcp, void *_priv_data)
 {
        tcp->qual_flg |= QUAL_ABBREV;
 }
+
 void
 apply_verbose(struct tcb *tcp, void *_priv_data)
 {
        tcp->qual_flg |= QUAL_VERBOSE;
 }
+
+void *
+parse_fault(const char *str)
+{
+       return parse_inject_common_args(str, true, "fault");
+}
+
+void
+apply_fault(struct tcb *tcp, void *_priv_data)
+{
+       apply_inject(tcp, _priv_data);
+}
+
+void free_fault(void *_priv_data) {
+       free_inject(_priv_data);
+}
diff --git a/defs.h b/defs.h
index 9242b16..21dec65 100644
--- a/defs.h
+++ b/defs.h
@@ -203,6 +203,7 @@ struct inject_opts {
        uint16_t step;
        uint16_t signo;
        int rval;
+       bool init;
 };
 
 #define MAX_ERRNO_VALUE                        4095
@@ -970,7 +971,6 @@ extern unsigned nioctlents;
 
 extern const unsigned int nsyscall_vec[SUPPORTED_PERSONALITIES];
 extern const struct_sysent *const sysent_vec[SUPPORTED_PERSONALITIES];
-extern struct inject_opts *inject_vec[SUPPORTED_PERSONALITIES];
 
 #ifdef IN_MPERS_BOOTSTRAP
 /* Transform multi-line MPERS_PRINTER_DECL statements to one-liners.  */
diff --git a/filter.h b/filter.h
index ed435c8..7e03d75 100644
--- a/filter.h
+++ b/filter.h
@@ -41,6 +41,8 @@ extern bool is_traced(struct tcb *);
 typedef int (*string_to_uint_func)(const char *);
 void parse_set(const char *const, struct number_set *const,
                string_to_uint_func, const char *const);
+bool parse_inject_token(const char *const, struct inject_opts *const,
+                        const bool);
 
 struct filter* add_filter_to_array(struct filter **, unsigned int *nfilters,
                                    const char *name);
diff --git a/filter_action.c b/filter_action.c
index f71f140..fd3fa92 100644
--- a/filter_action.c
+++ b/filter_action.c
@@ -34,6 +34,7 @@ apply_ ## name(struct tcb *, void *)
 
 DECL_FILTER_ACTION(trace);
 DECL_FILTER_ACTION(inject);
+DECL_FILTER_ACTION(fault);
 DECL_FILTER_ACTION(read);
 DECL_FILTER_ACTION(write);
 DECL_FILTER_ACTION(raw);
@@ -50,6 +51,7 @@ free_ ## name(void *)
 
 DECL_FILTER_ACTION_PARSER(null);
 DECL_FILTER_ACTION_PARSER(inject);
+DECL_FILTER_ACTION_PARSER(fault);
 
 #undef DECL_FILTER_ACTION_PARSER
 
@@ -68,6 +70,7 @@ static const struct filter_action_type {
 } action_types[] = {
        FILTER_ACTION_TYPE(trace,       2,      null,   NULL),
        FILTER_ACTION_TYPE(inject,      2,      inject, NULL),
+       FILTER_ACTION_TYPE(fault,       2,      fault,  NULL),
        FILTER_ACTION_TYPE(read,        1,      null,   is_traced),
        FILTER_ACTION_TYPE(write,       1,      null,   is_traced),
        FILTER_ACTION_TYPE(raw,         1,      null,   is_traced),
diff --git a/filter_qualify.c b/filter_qualify.c
index 6020ce8..79c1202 100644
--- a/filter_qualify.c
+++ b/filter_qualify.c
@@ -80,7 +80,7 @@ sigstr_to_uint(const char *s)
        return -1;
 }
 
-static bool
+bool
 parse_inject_token(const char *const token, struct inject_opts *const fopts,
                   const bool fault_tokens_only)
 {
@@ -233,6 +233,11 @@ parse_raw(const char *const str)
        set_qualify_mode(action);
 }
 
+struct inject_priv_data {
+       struct inject_opts opts;
+       struct inject_opts **inject_vec;
+};
+
 static void
 parse_inject_common(const char *const str,
                      const bool fault_tokens_only,
@@ -242,7 +247,8 @@ parse_inject_common(const char *const str,
                .first = 1,
                .step = 1,
                .rval = INJECT_OPTS_RVAL_DEFAULT,
-               .signo = 0
+               .signo = 0,
+               .init = true
        };
        char *buf = NULL;
        char *name = parse_inject_expression(str, &buf, &opts, 
fault_tokens_only);
@@ -265,35 +271,19 @@ parse_inject_common(const char *const str,
        struct filter *filter = create_filter(action, "syscall");
        parse_filter(filter, name, description);
        set_qualify_mode(action);
-
        free(buf);
-       const struct number_set *tmp_set = (const struct number_set *)
-                                           get_filter_priv_data(filter);
-       struct inject_opts **inject_vec = xcalloc(SUPPORTED_PERSONALITIES,
-                                                 sizeof(struct inject_opts *));
-       /*
-        * Initialize inject_vec accourding to tmp_set.
-        */
+
+       struct inject_priv_data *data = xmalloc(sizeof(struct 
inject_priv_data));
+       data->opts = opts;
+       data->inject_vec = xcalloc(SUPPORTED_PERSONALITIES,
+                                  sizeof(struct inject_opts *));
 
        unsigned int p;
        for (p = 0; p < SUPPORTED_PERSONALITIES; ++p) {
-               if (is_empty(&tmp_set[p])) {
-                       continue;
-               }
-
-               if (!inject_vec[p]) {
-                       inject_vec[p] = xcalloc(nsyscall_vec[p],
-                                              sizeof(*inject_vec[p]));
-               }
-
-               unsigned int i;
-               for (i = 0; i < nsyscall_vec[p]; ++i) {
-                       if (is_number_in_set(i, &tmp_set[p])) {
-                               inject_vec[p][i] = opts;
-                       }
-               }
+               data->inject_vec[p] = xcalloc(nsyscall_vec[p],
+                                             sizeof(struct inject_opts));
        }
-       set_filter_action_priv_data(action, inject_vec);
+       set_filter_action_priv_data(action, data);
 }
 
 static void
-- 
2.1.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Strace-devel mailing list
Strace-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to