sandbox: Add a function to load a relative file path
authorSimon Glass <sjg@chromium.org>
Wed, 7 Sep 2022 02:27:08 +0000 (20:27 -0600)
committerTom Rini <trini@konsulko.com>
Thu, 29 Sep 2022 20:09:56 +0000 (16:09 -0400)
At present this implementation is specific to loading the test FDT. We
plan to load others, so create a generic function to handle this.

The path is now limited to 256 characters, to simplify the code.

When there is an empty argv[0] (which should not happen), the function now
just uses the path as is, with no prefix.

Signed-off-by: Simon Glass <sjg@chromium.org>
arch/sandbox/cpu/start.c
arch/sandbox/cpu/state.c
arch/sandbox/include/asm/state.h

index 90a84e9..642be16 100644 (file)
@@ -205,21 +205,19 @@ SANDBOX_CMDLINE_OPT_SHORT(default_fdt, 'D', 0,
 static int sandbox_cmdline_cb_test_fdt(struct sandbox_state *state,
                                       const char *arg)
 {
-       const char *fmt = "/arch/sandbox/dts/test.dtb";
-       char *p;
+       char buf[256];
        char *fname;
        int len;
 
-       len = strlen(state->argv[0]) + strlen(fmt) + 1;
+       len = state_get_rel_filename("arch/sandbox/dts/test.dtb", buf,
+                                    sizeof(buf));
+       if (len < 0)
+               return len;
+
        fname = os_malloc(len);
        if (!fname)
                return -ENOMEM;
-       strcpy(fname, state->argv[0]);
-       p = strrchr(fname, '/');
-       if (!p)
-               p = fname + strlen(fname);
-       len -= p - fname;
-       snprintf(p, len, fmt);
+       strcpy(fname, buf);
        state->fdt_fname = fname;
 
        return 0;
index e0d0112..787e021 100644 (file)
@@ -396,6 +396,28 @@ bool autoboot_set_keyed(bool autoboot_keyed)
        return old_val;
 }
 
+int state_get_rel_filename(const char *rel_path, char *buf, int size)
+{
+       struct sandbox_state *state = state_get_current();
+       int rel_len, prog_len;
+       char *p;
+       int len;
+
+       rel_len = strlen(rel_path);
+       p = strrchr(state->argv[0], '/');
+       prog_len = p ? p - state->argv[0] : 0;
+
+       /* allow space for a / and a terminator */
+       len = prog_len + 1 + rel_len + 1;
+       if (len > size)
+               return -ENOSPC;
+       strncpy(buf, state->argv[0], prog_len);
+       buf[prog_len] = '/';
+       strcpy(buf + prog_len + 1, rel_path);
+
+       return len;
+}
+
 int state_init(void)
 {
        state = &main_state;
index 07c768a..12741ee 100644 (file)
@@ -266,6 +266,20 @@ void state_reset_for_test(struct sandbox_state *state);
 void state_show(struct sandbox_state *state);
 
 /**
+ * state_get_rel_filename() - Get a filename relative to the executable
+ *
+ * This uses argv[0] to obtain a filename path
+ *
+ * @rel_path: Relative path to build, e.g. "arch/sandbox/dts/test.dtb". Must not
+ * have a trailing /
+ * @buf: Buffer to use to return the filename
+ * @size: Size of buffer
+ * @return length of filename (including terminator), -ENOSPC if @size is too
+ * small
+ */
+int state_get_rel_filename(const char *rel_path, char *buf, int size);
+
+/**
  * Initialize the test system state
  */
 int state_init(void);