Skip to content

Commit 08799da

Browse files
Port command-line arguments to use wasip2 methods (#609)
Co-authored-by: Pat Hickey <[email protected]>
1 parent 93bd1f6 commit 08799da

File tree

5 files changed

+74
-2
lines changed

5 files changed

+74
-2
lines changed

libc-bottom-half/sources/__main_void.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
#ifdef __wasilibc_use_wasip2
2+
#include <wasi/wasip2.h>
3+
#else
14
#include <wasi/api.h>
5+
#endif
26
#include <stdlib.h>
37
#include <sysexits.h>
48

@@ -21,6 +25,46 @@ int __main_argc_argv(int argc, char *argv[]);
2125
// (e.g. crt0.o or crtend.o) and teach Clang to use it when needed.
2226
__attribute__((__weak__, nodebug))
2327
int __main_void(void) {
28+
#ifdef __wasilibc_use_wasip2
29+
wasip2_list_string_t argument_list;
30+
31+
environment_get_arguments(&argument_list);
32+
33+
// Add 1 for the NULL pointer to mark the end, and check for overflow.
34+
size_t argc = argument_list.len;
35+
size_t num_ptrs = argc + 1;
36+
if (num_ptrs == 0) {
37+
wasip2_list_string_free(&argument_list);
38+
_Exit(EX_SOFTWARE);
39+
}
40+
41+
// Allocate memory for the array of pointers. This uses `calloc` both to
42+
// handle overflow and to initialize the NULL pointer at the end.
43+
char **argv = calloc(num_ptrs, sizeof(char *));
44+
if (argv == NULL) {
45+
wasip2_list_string_free(&argument_list);
46+
_Exit(EX_SOFTWARE);
47+
}
48+
49+
// Copy the arguments
50+
for (size_t i = 0; i < argc; i++) {
51+
wasip2_string_t wasi_string = argument_list.ptr[i];
52+
size_t len = wasi_string.len;
53+
argv[i] = malloc(len + 1);
54+
if (!argv[i]) {
55+
wasip2_list_string_free(&argument_list);
56+
_Exit(EX_SOFTWARE);
57+
}
58+
memcpy(argv[i], wasi_string.ptr, len);
59+
argv[i][len] = '\0';
60+
}
61+
62+
// Free the WASI argument list
63+
wasip2_list_string_free(&argument_list);
64+
65+
// Call `__main_argc_argv` with the arguments!
66+
return __main_argc_argv(argc, argv);
67+
#else
2468
__wasi_errno_t err;
2569

2670
// Get the sizes of the arrays we'll have to create to copy in the args.
@@ -62,4 +106,5 @@ int __main_void(void) {
62106

63107
// Call `__main_argc_argv` with the arguments!
64108
return __main_argc_argv(argc, argv);
109+
#endif
65110
}

test/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ $(RUNDIR)/%/success: $(OBJPAT)
212212
@DIR="$(abspath $(@D))" \
213213
WASM="$(abspath $<)" \
214214
ENGINE="$(ENGINE) $(shell scripts/add-flags.py RUN $(call wasm_to_c,$<))" \
215+
ARGS="$(shell scripts/add-flags.py ARGS $(call wasm_to_c,$<))" \
215216
scripts/run-test.sh
216217

217218
# Use the provided Wasm engine to execute each test, emitting its output into

test/scripts/browser-test/harness.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const SKIP_TESTS = [
2424
// atomic.wait32 can't be executed on the main thread
2525
"libc-test/functional/pthread_mutex",
2626
"libc-test/functional/pthread_tsd",
27+
// Skip test that uses command-line arguments
28+
"misc/argv_two_args",
2729
// XFAIL: @bjorn3/browser_wasi_shim doesn't support symlinks for now
2830
"misc/fts",
2931
];

test/scripts/run-test.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
# - a `fs` directory which the test may have used for file IO
77
# - an `output.log` file containing the output of the test
88
#
9-
# Usage: DIR=... WASM=... ENGINE=... ./run-test.sh
9+
# Usage: DIR=... WASM=... ENGINE=... ARGS="..." ./run-test.sh
1010

1111
ENGINE="${ENGINE:-wasmtime}"
1212
[ -n "$WASM" ] || (echo "missing WASM variable" && exit 1)
1313
[ -n "$DIR" ] || (echo "missing DIR variable" && exit 1)
1414

1515
cd $DIR
1616
mkdir -p fs
17-
echo "$ENGINE $WASM" > cmd.sh
17+
echo "$ENGINE $WASM $ARGS" > cmd.sh
1818
chmod +x cmd.sh
1919
./cmd.sh &> output.log
2020
[ $? -eq 0 ] || echo "Test failed" >> output.log

test/src/misc/argv_two_args.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//! add-flags.py(CFLAGS): -I.
2+
//! add-flags.py(ARGS): foo bar
3+
#include <limits.h>
4+
#include <stdio.h>
5+
#include "test.h"
6+
7+
#define TEST(c, ...) \
8+
( (c) || (t_error(#c " failed: " __VA_ARGS__),0) )
9+
10+
int main(int argc, char **argv)
11+
{
12+
char buf[PATH_MAX];
13+
TEST(argc == 3, "argc should be 3\n");
14+
TEST(argv[0] != 0, "argv[0] should not be NULL\n");
15+
TEST(argv[1] != 0, "argv[1] should not be NULL\n");
16+
TEST(argv[2] != 0, "argv[2] should not be NULL\n");
17+
TEST(argv[3] == NULL, "argv[3] should be NULL\n");
18+
19+
for (int i = 0; i < argc; i++) {
20+
TEST(argv[i][0] != 0, "argument should not be empty\n");
21+
TEST(snprintf(buf, sizeof buf, "%s", argv[i]) < sizeof buf, "argument is not a valid path\n");
22+
}
23+
return t_status;
24+
}

0 commit comments

Comments
 (0)