]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
veristat: @files-list.txt notation for object files list
authorEduard Zingerman <eddyz87@gmail.com>
Sat, 1 Mar 2025 00:01:45 +0000 (16:01 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Sat, 15 Mar 2025 18:48:26 +0000 (11:48 -0700)
Allow reading object file list from file.
E.g. the following command:

  ./veristat @list.txt

Is equivalent to the following invocation:

  ./veristat line-1 line-2 ... line-N

Where line-i corresponds to lines from list.txt.
Lines starting with '#' are ignored.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Mykyta Yatsenko <mykyta.yatsenko5@gmail.com>
Link: https://lore.kernel.org/bpf/20250301000147.1583999-2-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/veristat.c

index 175a03e6c5ef47b7cb03c1548cbc9e9a549d50ac..8bc462299290250d23914aa22b7f08bbd47e0e16 100644 (file)
@@ -268,10 +268,11 @@ static int append_filter(struct filter **filters, int *cnt, const char *str);
 static int append_filter_file(const char *path);
 static int append_var_preset(struct var_preset **presets, int *cnt, const char *expr);
 static int append_var_preset_file(const char *filename);
+static int append_file(const char *path);
+static int append_file_from_file(const char *path);
 
 static error_t parse_arg(int key, char *arg, struct argp_state *state)
 {
-       void *tmp;
        int err;
 
        switch (key) {
@@ -381,14 +382,14 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
                break;
        }
        case ARGP_KEY_ARG:
-               tmp = realloc(env.filenames, (env.filename_cnt + 1) * sizeof(*env.filenames));
-               if (!tmp)
-                       return -ENOMEM;
-               env.filenames = tmp;
-               env.filenames[env.filename_cnt] = strdup(arg);
-               if (!env.filenames[env.filename_cnt])
-                       return -ENOMEM;
-               env.filename_cnt++;
+               if (arg[0] == '@')
+                       err = append_file_from_file(arg + 1);
+               else
+                       err = append_file(arg);
+               if (err) {
+                       fprintf(stderr, "Failed to collect BPF object files: %d\n", err);
+                       return err;
+               }
                break;
        default:
                return ARGP_ERR_UNKNOWN;
@@ -689,6 +690,49 @@ static const struct stat_specs default_output_spec = {
        },
 };
 
+static int append_file(const char *path)
+{
+       void *tmp;
+
+       tmp = realloc(env.filenames, (env.filename_cnt + 1) * sizeof(*env.filenames));
+       if (!tmp)
+               return -ENOMEM;
+       env.filenames = tmp;
+       env.filenames[env.filename_cnt] = strdup(path);
+       if (!env.filenames[env.filename_cnt])
+               return -ENOMEM;
+       env.filename_cnt++;
+       return 0;
+}
+
+static int append_file_from_file(const char *path)
+{
+       char buf[1024];
+       int err = 0;
+       FILE *f;
+
+       f = fopen(path, "r");
+       if (!f) {
+               err = -errno;
+               fprintf(stderr, "Failed to open object files list in '%s': %s\n",
+                       path, strerror(errno));
+               return err;
+       }
+
+       while (fscanf(f, " %1023[^\n]\n", buf) == 1) {
+               /* lines starting with # are comments, skip them */
+               if (buf[0] == '\0' || buf[0] == '#')
+                       continue;
+               err = append_file(buf);
+               if (err)
+                       goto cleanup;
+       }
+
+cleanup:
+       fclose(f);
+       return err;
+}
+
 static const struct stat_specs default_csv_output_spec = {
        .spec_cnt = 14,
        .ids = {