Hello,
While experimenting with the `wasm32-wasip2` target and CPython, I
discovered an issue with the `getaddrinfo()` implementation: it fails to
resolve the provided service into a port number, causing `sin_port` to
always be set to 0. This issue leads to failures in network-related
functions that rely on `getaddrinfo()`, such as Python's `urllib3`
library, which passes the result directly to `connect()`. This results
in connection attempts using a port value of 0, which naturally fails.
### Minimal example to reproduce the problem
```c
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
int main(void) {
struct addrinfo *res = NULL;
getaddrinfo("google.com", "443", NULL, &res);
for (struct addrinfo *i = res; i != NULL; i = i->ai_next) {
char str[INET6_ADDRSTRLEN];
if (i->ai_addr->sa_family == AF_INET) {
struct sockaddr_in *p = (struct sockaddr_in *)i->ai_addr;
int port = ntohs(p->sin_port);
printf("%s: %i\n", inet_ntop(AF_INET, &p->sin_addr, str, sizeof(str)), port);
} else if (i->ai_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *p = (struct sockaddr_in6 *)i->ai_addr;
int port = ntohs(p->sin6_port);
printf("%s: %i\n", inet_ntop(AF_INET6, &p->sin6_addr, str, sizeof(str)), port);
}
}
return 0;
}
```
```
$ /opt/wasi-sdk/bin/clang -target wasm32-wasip2 -o foo foo.c
$ wasmtime run -S allow-ip-name-lookup=y foo
216.58.211.238: 0
2a00:1450:4026:808::200e: 0
```
Expected output:
```
216.58.211.238: 443
2a00:1450:4026:808::200e: 443
```
### Root Cause
The root cause is that `getaddrinfo()` does not correctly translate the
provided service into a port number. As described in the `getaddrinfo()`
man [page](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html),
the function should:
> service sets the port in each returned address structure. If
this argument is a service name (see
[services(5)](https://man7.org/linux/man-pages/man5/services.5.html)),
it is
translated to the corresponding port number. This argument can
also be specified as a decimal number, which is simply converted
to binary. If service is NULL, then the port number of the
returned socket addresses will be left uninitialized.
### Proposed Fix
This pull request addresses the issue by implementing the following
behavior for `getaddrinfo()`:
* If the service is `NULL`, the port number in the returned socket
addresses remains uninitialized.
* The value is converted to an integer and validated if the service is
numeric.
The PR does not currently add support for translating named services
into port numbers because `getservbyname()` has not been implemented. In
cases where a named service is provided, the `EAI_NONAME` error code is
returned.
* implement basic TCP/UDP client support
This implements `socket`, `connect`, `recv`, `send`, etc. in terms of
`wasi-sockets` for the `wasm32-wasip2` target.
I've introduced a new public header file: `__wasi_snapshot.h`, which will define
a preprocessor symbol `__wasilibc_use_wasip2` if using the `wasm32-wasip2`
version of the header, in which case we provide features only available for that
target.
Co-authored-by: Dave Bakker <github@davebakker.io>
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* fix grammar in __wasi_snapshot.h comment
Co-authored-by: Dan Gohman <dev@sunfishcode.online>
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
---------
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
Co-authored-by: Dave Bakker <github@davebakker.io>
Co-authored-by: Dan Gohman <dev@sunfishcode.online>
* Start renaming preview1 to p1 and preview2 to p2
This is an initial start at renaming the "preview" terminology in WASI
targets to "pX". For example the `wasm32-wasi` target should transition
to `wasm32-wasip1`, `wasm32-wasi-preview2` should transition to
`wasm32-wasip2`, and `wasm32-wasi-threads` should transition to
`wasm32-wasip1-threads`. This commit applies a few renames in the
`Makefile` such as:
* `WASI_SNAPSHOT` is now either "p1" or "p2"
* The default p2 target triple is now `wasm32-wasip2` instead of
`wasm32-wasi-preview2` (in the hopes that it's early enough to change
the default).
* Bindings for WASIp2 were renamed from "preview2" terminology to "wasip2".
* The expected-defines files are renamed and the logic of which
expectation was used has been updated slightly.
With this commit the intention is that non-preview2 defaults do not
change. For example the default build still produces a `wasm32-wasi`
sysroot. If `TARGET_TRIPLE=wasm32-wasip1` is passed, however, then that
sysroot is produced instead. Similarly a `THREAD_MODEL=posix` build
produces a `wasm32-wasi-threads` sysroot target but you can now also
pass `TARGET_TRIPLE=wasm32-wasip1-threads` to rename the sysroot.
My hope is to integrate this into the wasi-sdk repository and build a
dual sysroot for these new targets for a release or two so both are
supported and then in the future the defaults can be switched away from
`wasm32-wasi` to `wasm32-wasip1` as built-by-default.
* Update builds in CI
* Update test workflow
* Fix test for wasm32-wasip1-threads
* Make github actions rules a bit more readable
* add descriptor table for mapping fds to handles
This introduces `descriptor_table.h` and `descriptor_table.c`, providing a
global hashtable for tracking `wasi-libc`-managed file descriptors.
WASI Preview 2 has no notion of file descriptors and instead uses unforgeable
resource handles. Moreover, there's not necessarily a one-to-one correspondence
between POSIX file descriptors and resource handles (e.g. a TCP connection may
require separate handles for reading, writing, and polling the same connection).
We use this table to map each POSIX descriptor to a set of one or more handles
and any extra state which libc needs to track.
Note that we've added `descriptor_table.h` to the
libc-bottom-half/headers/public/wasi directory, making it part of the public
API. The intention is to give applications access to the mapping, enabling them
to convert descriptors to handles and vice-versa should they need to
interoperate with both libc and WASI directly.
Co-authored-by: Dave Bakker <github@davebakker.io>
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* add dummy fields to otherwise empty structs
The C standard doesn't allow empty structs. Clang doesn't currently complain,
but we might as well stick to the spec in case it becomes more strict in the
future.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* move descriptor_table.h to headers/private
We're not yet ready to commit to making this API public, so we'll make it
private for now.
I've also expanded a comment in descriptor_table.c to explain the current ABI
for resource handles.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* re-run clang-format to fix indentation
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
---------
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
Co-authored-by: Dave Bakker <github@davebakker.io>
* make the Makefiles a bit more robust
- Escape "." character in `sed` regex
- Ensure that %.wasm target fails cleanly (i.e. without generating the target file) if `wasm-tools` fails
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* split `component new` rule out of link rule for Preview 2
We now explicitly distinquish between core module files (%.core.wasm) and
component files (%.wasm), which helps avoid the trickery in my previous commit.
In order to test this properly, I needed to update the Wasmtime URL to point to
v17.0.0 instead of dev (which we needed to do anyway), and that in turn required
updating the bindings to use the final WASI 0.2.0 release.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
---------
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
Per https://github.com/WebAssembly/wasi-sdk/issues/373, LLVM's libc++ no longer
allows us to enable `<fstream>` and `<filesystem>` separately -- it's both or
neither. Consequently, we either need to patch libc++ to not use `statvfs`,
`chmod`, etc. or add stub functions for those features to `wasi-libc`. Since
we're planning to eventually support those features with WASI Preview 2 and
beyond, it makes sense to do the latter.
Note that since libc++ uses `DT_SOCK`, I've added a definition for it -- even
though WASI Preview 1 does not define it. No Preview 1 file will ever have that
type, so code that handles that type will never be reached, but defining it
allows us to avoid WASI-specific patches to libc++.
Related to `DT_SOCK`, I had to change the `S_IFIFO` value so it does not
conflict with `S_IFSOCK`, thereby avoiding ambiguity in `__wasilibc_iftodt`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* add WASI Preview 2 bindings
This adds C bindings generated from the `wasi:cli/imports@0.2.0-rc-2023-12-05`
world, plus a makefile target to regenerate them from the WIT source files.
We'll use these bindings to call Preview 2 host functions when building for the
`wasm32-wasi-preview2` target.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* update to pre-release of `wit-bindgen` 0.17.0
This includes https://github.com/bytecodealliance/wit-bindgen/pull/804 (fix
broken indentation in generated code) and
https://github.com/bytecodealliance/wit-bindgen/pull/805 (support overriding
world name and adding a suffix to the component type custom section).
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* test all targets; update preview2 expected output files
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* build for `wasm32-wasi-threads` before testing it
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* move generated bindings per review feedback
Since these files aren't part of cloudlibc, no reason to put them under the
cloudlibc directory.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* move preview2.h to wasi directory
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
---------
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* add shared library support
This adds support for building WASI shared libraries per
https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md.
For the time being, the goal is to allow "pseudo-dynamic" linking using the
Component Model per
https://github.com/WebAssembly/component-model/blob/main/design/mvp/examples/SharedEverythingDynamicLinking.md.
This requires all libraries to be available when the component is created, but
still allows runtime symbol resolution via `dlopen`/`dlsym` backed by a static
lookup table. This is sufficient to support Python native extensions, for
example. A complete demo using `wit-component` is available at
https://github.com/dicej/component-linking-demo.
This commit adds support for building `libc.so`, `libc++.so`, and `libc++abi.so`
alongside their static counterparts.
Notes:
- I had to refactor `errno` support a bit to avoid a spurious `_ZTH5errno` (AKA "thread-local initialization routine for errno") import in `libc++.so`.
- Long double print and scan are included by default in `libc.so` rather than in a separate library.
- `__main_argc_argv` is now a weak symbol since it's not relevant for reactors.
- `dlopen`/`dlsym` rely on a lookup table provided by the "dynamic" linker via `__wasm_set_libraries`. Not all flags are supported yet, and unrecognized flags will result in an error.
- This requires https://reviews.llvm.org/D153293, which we will need to backport to LLVM 16 until 17 is released. I'll open a `wasi-sdk` PR with that change and various Makefile tweaks to support shared libraries.
- `libc.so` is temporarily disabled for the `wasi-threads` build until someone can make `wasi_thread_start.s` position-independent.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
build `-fPIC` .o files separately from non-`-fPIC` ones
This allows us to build both libc.so and libc.a without incurring indirection
penalties in the latter.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
only build libc.so when explicitly requested
Shared library support in LLVM for non-Emscripten Wasm targets will be added in
version 17, which has not yet been released, so we should not attempt to build
libc.so by default (at least not yet).
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove dl.c
I'll open a separate PR for this later.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `check-symbols` files
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* generate separate .so files for emulated features
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* revert errno changes in favor of a smaller change
@yamt pointed out there's an easier way to address the `_ZTH5errno` issue I
described in an earlier commit: use `_Thread_local` for both C and C++. This
gives us a simpler ABI and avoids needing to import a thread-local initializer
for `errno` in libc++.so.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* remove redundant `$(OBJDIR)/%.long-double.pic.o` rule in Makefile
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* consolidate libwasi-emulated-*.so into a single library
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* add comment explaining use of `--whole-archive`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* Revert "remove redundant `$(OBJDIR)/%.long-double.pic.o` rule in Makefile"
This reverts commit dbe2cb10541dd27e4e0ed71d30ce304b9c9133d6.
* move `__main_void` from __main_void.c to crt1-command.c
This and `__main_argc_argv` are only relevant for commands (not reactors), so it
makes sense to scope them accordingly. In addition, the latter was being
imported from libc.so, forcing applications to provide it even if it wasn't
relevant.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* Revert "consolidate libwasi-emulated-*.so into a single library"
This reverts commit c6518223a49f60e4bb254a3e77a411fdade18df2.
* build crt1-*.o with `-fPIC`
This ensures they can be used in a PIE or PIC context.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* ignore `__memory_base` when checking undefined symbols
Whether this symbol appears varies between LLVM versions.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* Revert "move `__main_void` from __main_void.c to crt1-command.c"
This reverts commit f3038354610b7eb18bfd39092a2ccc3b72842dc4.
* add explanatory comments to __main_void.c
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* add `__wasilibc_unmodified_upstream` and comment to `__lctrans_cur`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
---------
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
Given there are already AF_* definitions, and they are (now) essentially
synonyms, we add those definitions to enable compilation of code that
already use PF_* macros.
* Convert preopen initialization to be lazy.
Insteead of eagerly initializing the preopens in a static constructor,
perform preopen initialization the first time it's needed, or before a
close or a renumber which might disrupt the file descriptor space.
And, use a weak symbol with a stub function for use by `close` or
`fd_renumber`, we that they can trigger preopen initialization only
if it's actually needed.
This way, if a program doesn't contain any calls to any function that
needs preopens, it can avoid linking in the preopen initialization code.
And if it contains calls but doesn't execute them at runtime, it can
avoid executing the preopen intiailization code.
A downside here is that this may cause problems for users that call
`__wasi_fd_close` or `__wasi_fd_renumber` directly and close over
overwrite some preopens before libc has a chance to scan them. To
partially address this, this PR does add a declaration for
`__wasilibc_populate_preopens` to <wasi/libc.h> so that users can call
it manually if they need to.
* Fix calling `internal_register_preopened_fd` with the lock held.
Factor out the lock acquisition from the implementation of
`internal_register_preopened_fd` so that we can call it from
`__wasilibc_populate_preopens` with the lock held.
as __wasi_errno_t is uint16_t, with the current coding,
__pthread_create will never see negative return values from
wasi:thread_spawn.
eg. (int)(uint16_t)-1 == 65535.
* threads: implement `pthread_create`
As described in the [`wasi-threads`] proposal, this change implements
`pthread_create` using the new `wasi_thread_spawn(void *arg)` API. As
described there, `wasi-libc` exports the thread entry point with the
expected name, `wasi_thread_start`, and then unwraps the passed argument
`struct` to invoke the user function with the user argument `struct`.
[`wasi-threads`]: https://github.com/WebAssembly/wasi-threads/pull/5
Previously, the TID was only passed to the child thread entry point; the
parent thread was forced to wait until the child thread set the TID in
the pthread structure. With this change, the TID will be passed not only
to the child thread but also returned to the parent thread, so that
either side can make progress. The `i32.store` becomes an
`i32.atomic.store` to avoid concurrent writes.
This change extracts the `weak*`-related parts of #303 as a separate PR.
Note that this is slightly strange in that it uses some top-half MUSL
headers in the bottom-half code, but discussion around this led me to
believe that the advantages of, e.g., `LOCK` made this worthwhile.
Beyond just changing uses of `weak` to `__weak__`, we also MUSL's `weak`
and `weak_alias` macros in a few more places.
* Delete several blocks of unused code.
Delete several pieces of code from libc-bottom-half/cloudlibc that aren't in
use on wasi-libc.
* Delete more of `_CLOCK_PROCESS_CPUTIME_ID` or `_CLOCK_THREAD_CPUTIME_ID`.
* Add a `getpagesize` function.
This adds a `getpagesize` function. This interface is deprecated in POSIX,
but it's sufficiently widely used and not problematic in practice.
* Use musl's `getpagesize`.
* Enable the `getpagesize` declaration in unistd.h.
The WASI signal constants and proc_raise function were removed in the
latest [ephemeral], which had been scheduled to be in the next snapshot,
however WASI itself is now transitioning away from the snapshot system.
WASI libc will also be transitioning to updated wit specs once they're
ready, however until that time, we can make the simple change of
removing these signal constants to avoid confusion.
Fixes#271.
Fixes#272.
[ephemeral]: https://github.com/WebAssembly/WASI/tree/main/phases/ephemeral/witx
Add a `__wasilibc_deinit_environ` function which clears the current
environment variable state to the state where next time the environment
variable functions are called, they'll reinitialize the environment.
And add a `__wasilibc_maybe_reinitialize_environ_eagerly` function to
reinitialize the environment variable state if `environ` or `_environ`
are needed.
These functions are needed by wizer to be able to suspend and resume
a program and have it read new environment variables from the host
environment; see bytecodealliance/wizer#8 for background.
* Update to the next version of the `witx` crate
* Generate adapter functions instead of simply a header file to have a
place where adapter code can go.
* Implement adapters in terms of the instructions that the `witx` crate
tells us about.
* Update the interface of functions to what `witx` expects, notably
string arguments are now only taken as `char*` and `strlen` happens in
the adapter function.
* Update defined/predefined/undefined symbol lists for types that have
been updated.
Some precise generated code has changed but the actual APIs should all
be the same except for the change to not take the length of the string
in the raw WASI call, since idiomatically C doesn't pass the length of
strings around.
Eventually it's expected that the shim functions, while sometimes not
necessary today, will implement more checks and more conversions as
necessary for new APIs.
* Actually update witx submodule
* Comment how to regenerate files
* Tweak name of actual function imports
Make it a bit clearer that they're the ones that we're importing and
calling.
* Update submodule to point to WebAssembly
AT_FDCWD is a special constant in POSIX that can be passed to *at
functions to indicate the current working directory. Since the
current working directory is emulated in wasi libc, add emulated
AT_FDCWD support as well.
Fixes#42.
* Add basic emulation of getcwd/chdir
This commit adds basic emulation of a current working directory to
wasi-libc. The `getcwd` and `chdir` symbols are now implemented and
available for use. The `getcwd` implementation is pretty simple in that
it just copies out of a new global, `__wasilibc_cwd`, which defaults to
`"/"`. The `chdir` implementation is much more involved and has more
ramification, however.
A new function, `make_absolute`, was added to the preopens object. Paths
stored in the preopen table are now always stored as absolute paths
instead of relative paths, and initial relative paths are interpreted as
being relative to `/`. Looking up a path to preopen now always turns it
into an absolute path, relative to the current working directory, and an
appropriate path is then returned.
The signature of `__wasilibc_find_relpath` has changed as well. It now
returns two path components, one for the absolute part and one for the
relative part. Additionally the relative part is always dynamically
allocated since it may no longer be a substring of the original input
path.
This has been tested lightly against the Rust standard library so far,
but I'm not a regular C developer so there's likely a few things to
improve!
* Amortize mallocs made in syscalls
* Avoid size bloat on programs that don't use `chdir`
* Add threading compat
* Collect `link`/`renameat` second path lookup
* Update comments about chdir.c in makefile
* Move definition of `__wasilibc_find_relpath_alloc` to header
* Expand comments
* Document the format of strings a bit more
* Fixup a few issues in path logic
* Fix GitHub Actions
Normally bits like this would be considered implementation details, but
in this case, `X_OK`, `W_OK`, and `R_OK` line up with `S_IXOTH`,
`S_IWOTH`, and `S_IROTH` on other systems, and those bits do have
well-known values.
* Rewrite the preopen functionality.
Rewrite the preopen functionality to be simpler, better organized,
and better integrated into WASI libc. Preopen support has diverged so
much from libpreopen that it no longer makes sense to track libpreopen
as an explicit upstream. And add more documentation.
* Fix missing #include.
* Fix a compilation error.
* Lazy-initialize the environment variables.
This is the first in a series of PRs to make it easier to use WASI libc
in Wasm modules that don't have a `main` function. By initializing the
environment on demand, we avoid depending on having `__wasm_call_ctors`
run.
This uses weak symbols strategically to ensure that if `environ` is
used, it is initialized eagerly, but if only `getenv` and friends
are used, the environment is initialized lazily.
Eventually, I expect we'll have a convention for wasm modules without
main functions which will allow the `__wasm_call_ctors` function to be
called automatically, but this helps in simple cases for now.
Fixes#180.
* Add comments explaining the libc-environ-compat.h header usage.
See the WHATSNEW file for details; this doesn't have any major changes
for wasi-libc; in particular, the new catgets and GLOB_TILDE features
are disabled.
* use pch/layout branch for witx; generate assertions of layout
* address review comments, add asserts for handle
* change wasm32 support comment to a preprocessor error
* expose `to_c_header` in wasi-headers crate for use in external test harness
* main.rs: inputs and output arguments are optional
so that generate-libc command works
* regen header
The header api.h was update using the following command:
$ cd tools/wasi-headers
$ cargo run -- WASI/phases/snapshot/witx/typenames.witx \
WASI/phases/snapshot/witx/wasi_snapshot_preview1.witx \
--output ../../libc-bottom-half/headers/public/wasi/api.h
This should probably have been part of #140 but we don't actually
support signals so this doesn't get much testing I imagine.
The old names like `__WASI_SIGBUS` no longer exist and the new names
look like `__WASI_SIGNAL_BUS`.
* Use constructor functions for optional init routines.
Instead of using weak symbols, use constructor function attributes for the
environment and preopen initialization routines. This is simpler, uses
less code, and is more LTO-friendly.
* Change the constructor priorities to start at 50.
We don't currently have specific plans for other levels in the reserved
range (0-100), so leave room for both lower and higher priorities.
* Add the WASI repo as a submodule.
Also, add the witx filenames to the generated output, and just have
`cargo run` auto-generate the api.h header, rather than using clap.
* Switch witx to a path dependency.
* Add a test.
* Add a test that the generated file is in sync with the generator.
* Enable CI testing with Github Actions.
* Fix the name of the wasi-headers directory.
* Enable submodules.
* Add a diff mechanism to help explain failures.
* Sort the inputs for display.
* More debugging.
* More debugging.
* Add a .gitattributes file forcing text files to be eol=lf.
Most editors these days can deal with eof=lf files, even on Windows, and
this avoids trouble with headers and other generated files differing in
line endings.
* Make __wasi_linkcount_t a uint64_t (#134)
Refs: https://github.com/WebAssembly/WASI/pull/127
* Generate the WASI interface from witx.
This replaces the hand-maintained <wasi/core.h> header with a
<wasi/api.h> generated from witx.
Most of the churn here is caused by upstream WASI renamings; hopefully
in the future ABI updates will be less noisy.
Don't ignore paths which don't have the required rights. This means
that if the lookup finds a path that doesn't have the required
rights, it'll just proceed to the actual operation which will fail
with `ENOTCAPABLE`.
Intuitively, use cases which would depend on having multiple
overlapping matching paths for a given lookup and intelligently
picking the one with the required rights seems like they should
be uncommon.
This is simpler overall, and requires less code.
* Link `populate_environ` only if we actually need environment variables.
This avoids linking in the environment variable initialization code,
and the __wasi_environ_sizes_get and __wasi_environ_get imports, in
programs that don't use environment variables.
This also removes the "___environ" (three underscores) alias symbol,
which is only in musl for backwards compatibility.
* Switch to //-style comments.
* If malloc fails, don't leave `__environ` pointing to an uninitialized buffer.
* Fix a memory leak if one malloc succeeds and the other fails.
* Use calloc to handle multiplication overflow.
This also handles the NULL terminator.
* Don't initialize __environ until everything has succeeded.
* Avoid leaking in case __wasi_environ_get fails.
* Handle overflow in the add too.
* Add #include <stdlib.h> for malloc etc.
* If the environment is empty, don't allocate any memory.