From d4a83dee051ff4e2ace853721efc9ff72e0d5926 Mon Sep 17 00:00:00 2001 From: Emma Anholt Date: Mon, 23 Sep 2024 16:58:16 -0700 Subject: [PATCH] Don't forget to push the arguments to scripts being interpreted. Includes an integration test that passes on Linux as well. --- kernel/process/process.rs | 12 +++++++++++- testing/integration_tests/echo_args.sh | 6 ++++++ testing/integration_tests/script_args.test | 22 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100755 testing/integration_tests/echo_args.sh create mode 100755 testing/integration_tests/script_args.test diff --git a/kernel/process/process.rs b/kernel/process/process.rs index 414c923a..1ef35a71 100644 --- a/kernel/process/process.rs +++ b/kernel/process/process.rs @@ -563,11 +563,12 @@ fn setup_userspace( fn do_script_binfmt( executable_path: &Arc, - _argv: &[&[u8]], // TODO: Ignoring this seems wrong + script_argv: &[&[u8]], envp: &[&[u8]], root_fs: &Arc>, buf: &[u8], ) -> Result { + // Set up argv[] with the interpreter and its arguments from the shebang line. let mut argv: Vec<&[u8]> = buf[2..buf.iter().position(|&ch| ch == b'\n').unwrap()] .split(|&ch| ch == b' ') .collect(); @@ -575,9 +576,18 @@ fn do_script_binfmt( return Err(Errno::EINVAL.into()); } + // Push the path to the script file as the first argument to the + // interpreter. let executable_pathbuf = executable_path.resolve_absolute_path(); argv.push(executable_pathbuf.as_str().as_bytes()); + // Push the original arguments to the script on after the new script + // invocation (leaving out argv[0] of the previous path of invoking the + // script.) + for arg in script_argv.iter().skip(1) { + argv.push(arg); + } + let shebang_path = root_fs.lock().lookup_path( Path::new(core::str::from_utf8(argv[0]).map_err(|_| Error::new(Errno::EINVAL))?), true, diff --git a/testing/integration_tests/echo_args.sh b/testing/integration_tests/echo_args.sh new file mode 100755 index 00000000..4b79ba69 --- /dev/null +++ b/testing/integration_tests/echo_args.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +for arg in "$@"; do + echo $arg +done + diff --git a/testing/integration_tests/script_args.test b/testing/integration_tests/script_args.test new file mode 100755 index 00000000..ecfcd133 --- /dev/null +++ b/testing/integration_tests/script_args.test @@ -0,0 +1,22 @@ +#!/bin/sh + +if [ -z "$TESTS_DIR" ]; then + TESTS_DIR="." +fi + +result=`${TESTS_DIR}/echo_args.sh 1 2 "3 4"` + +expected=$(cat <