From 73c5cb9dacbcf2e988fffa66750c4206fccc8cbc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:08 -0600 Subject: [PATCH] sandbox: Add a function to load a relative file path 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 --- arch/sandbox/cpu/start.c | 16 +++++++--------- arch/sandbox/cpu/state.c | 22 ++++++++++++++++++++++ arch/sandbox/include/asm/state.h | 14 ++++++++++++++ 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 90a84e93c7..642be164a3 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -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; diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index e0d01125bb..787e021659 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -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; diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 07c768ae5d..12741ee064 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -265,6 +265,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 */ -- 2.39.5