New upstream version 0.0~git20210922.ad51334

This commit is contained in:
Ximin Luo 2022-03-06 21:16:47 +00:00
commit f497c1d131
252 changed files with 4104 additions and 2785 deletions

View File

@ -23,11 +23,15 @@ jobs:
if: matrix.os == 'windows-latest' if: matrix.os == 'windows-latest'
- name: Install llvm-nm (Windows) - name: Install llvm-nm (Windows)
shell: bash
run: | run: |
rustup update stable rustup update stable
rustup default stable rustup default stable
rustup component add llvm-tools-preview rustup component add llvm-tools-preview
if: matrix.os == 'windows-latest'
- name: Register llvm-nm in environment (Windows)
shell: bash
run: |
echo "WASM_NM=$(rustc --print sysroot|sed 's|C:|/c|'|sed 's|\\|/|g')/lib/rustlib/x86_64-pc-windows-msvc/bin/llvm-nm.exe" >> $GITHUB_ENV echo "WASM_NM=$(rustc --print sysroot|sed 's|C:|/c|'|sed 's|\\|/|g')/lib/rustlib/x86_64-pc-windows-msvc/bin/llvm-nm.exe" >> $GITHUB_ENV
if: matrix.os == 'windows-latest' if: matrix.os == 'windows-latest'

107
Makefile
View File

@ -1,8 +1,8 @@
# These variables are specifically meant to be overridable via the make # These variables are specifically meant to be overridable via the make
# command-line. # command-line.
WASM_CC ?= clang WASM_CC ?= clang
WASM_NM ?= $(patsubst %clang,%llvm-nm,$(WASM_CC)) WASM_NM ?= $(patsubst %clang,%llvm-nm,$(filter-out ccache sccache,$(WASM_CC)))
WASM_AR ?= $(patsubst %clang,%llvm-ar,$(WASM_CC)) WASM_AR ?= $(patsubst %clang,%llvm-ar,$(filter-out ccache sccache,$(WASM_CC)))
WASM_CFLAGS ?= -O2 -DNDEBUG WASM_CFLAGS ?= -O2 -DNDEBUG
# The directory where we build the sysroot. # The directory where we build the sysroot.
SYSROOT ?= $(CURDIR)/sysroot SYSROOT ?= $(CURDIR)/sysroot
@ -10,17 +10,13 @@ SYSROOT ?= $(CURDIR)/sysroot
INSTALL_DIR ?= /usr/local INSTALL_DIR ?= /usr/local
# single or posix # single or posix
THREAD_MODEL ?= single THREAD_MODEL ?= single
# dlmalloc or none
MALLOC_IMPL ?= dlmalloc
# yes or no # yes or no
BUILD_DLMALLOC ?= yes
BUILD_LIBC_TOP_HALF ?= yes BUILD_LIBC_TOP_HALF ?= yes
# The directory where we're store intermediate artifacts. # The directory where we're store intermediate artifacts.
OBJDIR ?= $(CURDIR)/build OBJDIR ?= $(CURDIR)/build
# Check dependencies.
ifneq ($(BUILD_DLMALLOC),yes)
$(error build currently depends on BUILD_DLMALLOC=yes)
endif
# Variables from this point on are not meant to be overridable via the # Variables from this point on are not meant to be overridable via the
# make command-line. # make command-line.
@ -54,6 +50,10 @@ LIBC_BOTTOM_HALF_ALL_SOURCES := $(LIBC_BOTTOM_HALF_ALL_SOURCES) $(LIBC_BOTTOM_HA
LIBWASI_EMULATED_MMAN_SOURCES = \ LIBWASI_EMULATED_MMAN_SOURCES = \
$(shell find $(LIBC_BOTTOM_HALF_DIR)/mman -name \*.c) $(shell find $(LIBC_BOTTOM_HALF_DIR)/mman -name \*.c)
LIBWASI_EMULATED_PROCESS_CLOCKS_SOURCES = \
$(shell find $(LIBC_BOTTOM_HALF_DIR)/clocks -name \*.c)
LIBWASI_EMULATED_GETPID_SOURCES = \
$(shell find $(LIBC_BOTTOM_HALF_DIR)/getpid -name \*.c)
LIBWASI_EMULATED_SIGNAL_SOURCES = \ LIBWASI_EMULATED_SIGNAL_SOURCES = \
$(shell find $(LIBC_BOTTOM_HALF_DIR)/signal -name \*.c) $(shell find $(LIBC_BOTTOM_HALF_DIR)/signal -name \*.c)
LIBWASI_EMULATED_SIGNAL_MUSL_SOURCES = \ LIBWASI_EMULATED_SIGNAL_MUSL_SOURCES = \
@ -166,8 +166,8 @@ LIBC_TOP_HALF_MUSL_SOURCES = \
%/fminf.c %/fmaxf.c \ %/fminf.c %/fmaxf.c \
%/fmin.c %/fmax.c, \ %/fmin.c %/fmax.c, \
$(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/math/*.c)) \ $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/math/*.c)) \
$(filter-out %/crealf.c %/creal.c \ $(filter-out %/crealf.c %/creal.c %creall.c \
%/cimagf.c %/cimag.c, \ %/cimagf.c %/cimag.c %cimagl.c, \
$(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/complex/*.c)) \ $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/complex/*.c)) \
$(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/crypt/*.c) $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/crypt/*.c)
MUSL_PRINTSCAN_SOURCES = \ MUSL_PRINTSCAN_SOURCES = \
@ -184,21 +184,33 @@ LIBC_TOP_HALF_ALL_SOURCES = \
$(shell find $(LIBC_TOP_HALF_SOURCES) -name \*.c) $(shell find $(LIBC_TOP_HALF_SOURCES) -name \*.c)
# Set the target. # Set the target.
WASM_CFLAGS += --target=$(TARGET_TRIPLE) CFLAGS = $(WASM_CFLAGS) --target=$(TARGET_TRIPLE)
# WebAssembly floating-point match doesn't trap. # WebAssembly floating-point match doesn't trap.
# TODO: Add -fno-signaling-nans when the compiler supports it. # TODO: Add -fno-signaling-nans when the compiler supports it.
WASM_CFLAGS += -fno-trapping-math CFLAGS += -fno-trapping-math
# Add all warnings, but disable a few which occur in third-party code.
CFLAGS += -Wall -Wextra -Werror \
-Wno-null-pointer-arithmetic \
-Wno-unused-parameter \
-Wno-sign-compare \
-Wno-unused-variable \
-Wno-unused-function \
-Wno-ignored-attributes \
-Wno-missing-braces \
-Wno-ignored-pragmas \
-Wno-unused-but-set-variable \
-Wno-unknown-warning-option
# Configure support for threads. # Configure support for threads.
ifeq ($(THREAD_MODEL), single) ifeq ($(THREAD_MODEL), single)
WASM_CFLAGS += -mthread-model single CFLAGS += -mthread-model single
endif endif
ifeq ($(THREAD_MODEL), posix) ifeq ($(THREAD_MODEL), posix)
WASM_CFLAGS += -mthread-model posix -pthread CFLAGS += -mthread-model posix -pthread
endif endif
# Set the sysroot. # Set the sysroot.
WASM_CFLAGS += --sysroot="$(SYSROOT)" CFLAGS += --sysroot="$(SYSROOT)"
# These variables describe the locations of various files and directories in # These variables describe the locations of various files and directories in
# the build tree. # the build tree.
@ -206,8 +218,12 @@ objs = $(patsubst $(CURDIR)/%.c,$(OBJDIR)/%.o,$(1))
DLMALLOC_OBJS = $(call objs,$(DLMALLOC_SOURCES)) DLMALLOC_OBJS = $(call objs,$(DLMALLOC_SOURCES))
LIBC_BOTTOM_HALF_ALL_OBJS = $(call objs,$(LIBC_BOTTOM_HALF_ALL_SOURCES)) LIBC_BOTTOM_HALF_ALL_OBJS = $(call objs,$(LIBC_BOTTOM_HALF_ALL_SOURCES))
LIBC_TOP_HALF_ALL_OBJS = $(call objs,$(LIBC_TOP_HALF_ALL_SOURCES)) LIBC_TOP_HALF_ALL_OBJS = $(call objs,$(LIBC_TOP_HALF_ALL_SOURCES))
ifeq ($(BUILD_DLMALLOC),yes) ifeq ($(MALLOC_IMPL),dlmalloc)
LIBC_OBJS += $(DLMALLOC_OBJS) LIBC_OBJS += $(DLMALLOC_OBJS)
else ifeq ($(MALLOC_IMPL),none)
# No object files to add.
else
$(error unknown malloc implementation $(MALLOC_IMPL))
endif endif
# Add libc-bottom-half's objects. # Add libc-bottom-half's objects.
LIBC_OBJS += $(LIBC_BOTTOM_HALF_ALL_OBJS) LIBC_OBJS += $(LIBC_BOTTOM_HALF_ALL_OBJS)
@ -219,6 +235,8 @@ MUSL_PRINTSCAN_OBJS = $(call objs,$(MUSL_PRINTSCAN_SOURCES))
MUSL_PRINTSCAN_LONG_DOUBLE_OBJS = $(patsubst %.o,%.long-double.o,$(MUSL_PRINTSCAN_OBJS)) MUSL_PRINTSCAN_LONG_DOUBLE_OBJS = $(patsubst %.o,%.long-double.o,$(MUSL_PRINTSCAN_OBJS))
MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS = $(patsubst %.o,%.no-floating-point.o,$(MUSL_PRINTSCAN_OBJS)) MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS = $(patsubst %.o,%.no-floating-point.o,$(MUSL_PRINTSCAN_OBJS))
LIBWASI_EMULATED_MMAN_OBJS = $(call objs,$(LIBWASI_EMULATED_MMAN_SOURCES)) LIBWASI_EMULATED_MMAN_OBJS = $(call objs,$(LIBWASI_EMULATED_MMAN_SOURCES))
LIBWASI_EMULATED_PROCESS_CLOCKS_OBJS = $(call objs,$(LIBWASI_EMULATED_PROCESS_CLOCKS_SOURCES))
LIBWASI_EMULATED_GETPID_OBJS = $(call objs,$(LIBWASI_EMULATED_GETPID_SOURCES))
LIBWASI_EMULATED_SIGNAL_OBJS = $(call objs,$(LIBWASI_EMULATED_SIGNAL_SOURCES)) LIBWASI_EMULATED_SIGNAL_OBJS = $(call objs,$(LIBWASI_EMULATED_SIGNAL_SOURCES))
LIBWASI_EMULATED_SIGNAL_MUSL_OBJS = $(call objs,$(LIBWASI_EMULATED_SIGNAL_MUSL_SOURCES)) LIBWASI_EMULATED_SIGNAL_MUSL_OBJS = $(call objs,$(LIBWASI_EMULATED_SIGNAL_MUSL_SOURCES))
@ -322,6 +340,10 @@ $(SYSROOT_LIB)/libc-printscan-no-floating-point.a: $(MUSL_PRINTSCAN_NO_FLOATING_
$(SYSROOT_LIB)/libwasi-emulated-mman.a: $(LIBWASI_EMULATED_MMAN_OBJS) $(SYSROOT_LIB)/libwasi-emulated-mman.a: $(LIBWASI_EMULATED_MMAN_OBJS)
$(SYSROOT_LIB)/libwasi-emulated-process-clocks.a: $(LIBWASI_EMULATED_PROCESS_CLOCKS_OBJS)
$(SYSROOT_LIB)/libwasi-emulated-getpid.a: $(LIBWASI_EMULATED_GETPID_OBJS)
$(SYSROOT_LIB)/libwasi-emulated-signal.a: $(LIBWASI_EMULATED_SIGNAL_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS) $(SYSROOT_LIB)/libwasi-emulated-signal.a: $(LIBWASI_EMULATED_SIGNAL_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS)
%.a: %.a:
@ -335,40 +357,40 @@ $(SYSROOT_LIB)/libwasi-emulated-signal.a: $(LIBWASI_EMULATED_SIGNAL_OBJS) $(LIBW
# silently dropping the tail. # silently dropping the tail.
$(WASM_AR) crs $@ $(wordlist 800, 100000, $^) $(WASM_AR) crs $@ $(wordlist 800, 100000, $^)
$(MUSL_PRINTSCAN_OBJS): WASM_CFLAGS += \ $(MUSL_PRINTSCAN_OBJS): CFLAGS += \
-D__wasilibc_printscan_no_long_double \ -D__wasilibc_printscan_no_long_double \
-D__wasilibc_printscan_full_support_option="\"add -lc-printscan-long-double to the link command\"" -D__wasilibc_printscan_full_support_option="\"add -lc-printscan-long-double to the link command\""
$(MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS): WASM_CFLAGS += \ $(MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS): CFLAGS += \
-D__wasilibc_printscan_no_floating_point \ -D__wasilibc_printscan_no_floating_point \
-D__wasilibc_printscan_floating_point_support_option="\"remove -lc-printscan-no-floating-point from the link command\"" -D__wasilibc_printscan_floating_point_support_option="\"remove -lc-printscan-no-floating-point from the link command\""
$(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS): WASM_CFLAGS += \ $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS): CFLAGS += \
-D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_SIGNAL
$(OBJDIR)/%.long-double.o: $(CURDIR)/%.c include_dirs $(OBJDIR)/%.long-double.o: $(CURDIR)/%.c include_dirs
@mkdir -p "$(@D)" @mkdir -p "$(@D)"
"$(WASM_CC)" $(WASM_CFLAGS) -MD -MP -o $@ -c $< $(WASM_CC) $(CFLAGS) -MD -MP -o $@ -c $<
$(OBJDIR)/%.no-floating-point.o: $(CURDIR)/%.c include_dirs $(OBJDIR)/%.no-floating-point.o: $(CURDIR)/%.c include_dirs
@mkdir -p "$(@D)" @mkdir -p "$(@D)"
"$(WASM_CC)" $(WASM_CFLAGS) -MD -MP -o $@ -c $< $(WASM_CC) $(CFLAGS) -MD -MP -o $@ -c $<
$(OBJDIR)/%.o: $(CURDIR)/%.c include_dirs $(OBJDIR)/%.o: $(CURDIR)/%.c include_dirs
@mkdir -p "$(@D)" @mkdir -p "$(@D)"
"$(WASM_CC)" $(WASM_CFLAGS) -MD -MP -o $@ -c $< $(WASM_CC) $(CFLAGS) -MD -MP -o $@ -c $<
-include $(shell find $(OBJDIR) -name \*.d) -include $(shell find $(OBJDIR) -name \*.d)
$(DLMALLOC_OBJS): WASM_CFLAGS += \ $(DLMALLOC_OBJS): CFLAGS += \
-I$(DLMALLOC_INC) -I$(DLMALLOC_INC)
startup_files $(LIBC_BOTTOM_HALF_ALL_OBJS): WASM_CFLAGS += \ startup_files $(LIBC_BOTTOM_HALF_ALL_OBJS): CFLAGS += \
-I$(LIBC_BOTTOM_HALF_HEADERS_PRIVATE) \ -I$(LIBC_BOTTOM_HALF_HEADERS_PRIVATE) \
-I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_INC) \ -I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_INC) \
-I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC) -I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)
$(LIBC_TOP_HALF_ALL_OBJS) $(MUSL_PRINTSCAN_LONG_DOUBLE_OBJS) $(MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS): WASM_CFLAGS += \ $(LIBC_TOP_HALF_ALL_OBJS) $(MUSL_PRINTSCAN_LONG_DOUBLE_OBJS) $(MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS): CFLAGS += \
-I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/include \ -I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/include \
-I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal \ -I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal \
-I$(LIBC_TOP_HALF_MUSL_DIR)/arch/wasm32 \ -I$(LIBC_TOP_HALF_MUSL_DIR)/arch/wasm32 \
@ -382,6 +404,9 @@ $(LIBC_TOP_HALF_ALL_OBJS) $(MUSL_PRINTSCAN_LONG_DOUBLE_OBJS) $(MUSL_PRINTSCAN_NO
-Wno-dangling-else \ -Wno-dangling-else \
-Wno-unknown-pragmas -Wno-unknown-pragmas
$(LIBWASI_EMULATED_PROCESS_CLOCKS_OBJS): CFLAGS += \
-I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)
include_dirs: include_dirs:
$(RM) -r "$(SYSROOT)" $(RM) -r "$(SYSROOT)"
@ -413,7 +438,7 @@ startup_files: include_dirs
# #
@mkdir -p "$(OBJDIR)" @mkdir -p "$(OBJDIR)"
cd "$(OBJDIR)" && \ cd "$(OBJDIR)" && \
"$(WASM_CC)" $(WASM_CFLAGS) -c $(LIBC_BOTTOM_HALF_CRT_SOURCES) -MD -MP && \ $(WASM_CC) $(CFLAGS) -c $(LIBC_BOTTOM_HALF_CRT_SOURCES) -MD -MP && \
mkdir -p "$(SYSROOT_LIB)" && \ mkdir -p "$(SYSROOT_LIB)" && \
mv *.o "$(SYSROOT_LIB)" mv *.o "$(SYSROOT_LIB)"
@ -422,6 +447,8 @@ libc: include_dirs \
$(SYSROOT_LIB)/libc-printscan-long-double.a \ $(SYSROOT_LIB)/libc-printscan-long-double.a \
$(SYSROOT_LIB)/libc-printscan-no-floating-point.a \ $(SYSROOT_LIB)/libc-printscan-no-floating-point.a \
$(SYSROOT_LIB)/libwasi-emulated-mman.a \ $(SYSROOT_LIB)/libwasi-emulated-mman.a \
$(SYSROOT_LIB)/libwasi-emulated-process-clocks.a \
$(SYSROOT_LIB)/libwasi-emulated-getpid.a \
$(SYSROOT_LIB)/libwasi-emulated-signal.a $(SYSROOT_LIB)/libwasi-emulated-signal.a
finish: startup_files libc finish: startup_files libc
@ -432,6 +459,18 @@ finish: startup_files libc
$(WASM_AR) crs "$(SYSROOT_LIB)/lib$${name}.a"; \ $(WASM_AR) crs "$(SYSROOT_LIB)/lib$${name}.a"; \
done done
#
# The build succeeded! The generated sysroot is in $(SYSROOT).
#
# The check for defined and undefined symbols expects there to be a heap
# alloctor (providing malloc, calloc, free, etc). Skip this step if the build
# is done without a malloc implementation.
ifneq ($(MALLOC_IMPL),none)
finish: check-symbols
endif
check-symbols: startup_files libc
# #
# Collect metadata on the sysroot and perform sanity checks. # Collect metadata on the sysroot and perform sanity checks.
# #
@ -444,20 +483,20 @@ finish: startup_files libc
@# LLVM PR40497, which is fixed in 9.0, but not in 8.0. @# LLVM PR40497, which is fixed in 9.0, but not in 8.0.
@# Ignore certain llvm builtin symbols such as those starting with __mul @# Ignore certain llvm builtin symbols such as those starting with __mul
@# since these dependencies can vary between llvm versions. @# since these dependencies can vary between llvm versions.
"$(WASM_NM)" --defined-only "$(SYSROOT_LIB)"/libc.a "$(SYSROOT_LIB)"/*.o \ "$(WASM_NM)" --defined-only "$(SYSROOT_LIB)"/libc.a "$(SYSROOT_LIB)"/libwasi-emulated-*.a "$(SYSROOT_LIB)"/*.o \
|grep ' [[:upper:]] ' |sed 's/.* [[:upper:]] //' |LC_ALL=C sort > "$(SYSROOT_SHARE)/defined-symbols.txt" |grep ' [[:upper:]] ' |sed 's/.* [[:upper:]] //' |LC_ALL=C sort > "$(SYSROOT_SHARE)/defined-symbols.txt"
for undef_sym in $$("$(WASM_NM)" --undefined-only "$(SYSROOT_LIB)"/libc.a "$(SYSROOT_LIB)"/libc-*.a "$(SYSROOT_LIB)"/*.o \ for undef_sym in $$("$(WASM_NM)" --undefined-only "$(SYSROOT_LIB)"/libc.a "$(SYSROOT_LIB)"/libc-*.a "$(SYSROOT_LIB)"/*.o \
|grep ' U ' |sed 's/.* U //' |LC_ALL=C sort |uniq); do \ |grep ' U ' |sed 's/.* U //' |LC_ALL=C sort |uniq); do \
grep -q '\<'$$undef_sym'\>' "$(SYSROOT_SHARE)/defined-symbols.txt" || echo $$undef_sym; \ grep -q '\<'$$undef_sym'\>' "$(SYSROOT_SHARE)/defined-symbols.txt" || echo $$undef_sym; \
done | grep -v "^__mul" > "$(SYSROOT_SHARE)/undefined-symbols.txt" done | grep -v "^__mul" > "$(SYSROOT_SHARE)/undefined-symbols.txt"
grep '^_*wasi_' "$(SYSROOT_SHARE)/undefined-symbols.txt" \ grep '^_*imported_wasi_' "$(SYSROOT_SHARE)/undefined-symbols.txt" \
> "$(SYSROOT_LIB)/libc.imports" > "$(SYSROOT_LIB)/libc.imports"
# #
# Generate a test file that includes all public header files. # Generate a test file that includes all public header files.
# #
cd "$(SYSROOT)" && \ cd "$(SYSROOT)" && \
for header in $$(find include -type f -not -name mman.h -not -name signal.h |grep -v /bits/); do \ for header in $$(find include -type f -not -name mman.h -not -name signal.h -not -name times.h -not -name resource.h |grep -v /bits/); do \
echo '#include <'$$header'>' | sed 's/include\///' ; \ echo '#include <'$$header'>' | sed 's/include\///' ; \
done |LC_ALL=C sort >share/$(MULTIARCH_TRIPLE)/include-all.c ; \ done |LC_ALL=C sort >share/$(MULTIARCH_TRIPLE)/include-all.c ; \
cd - >/dev/null cd - >/dev/null
@ -465,7 +504,7 @@ finish: startup_files libc
# #
# Test that it compiles. # Test that it compiles.
# #
"$(WASM_CC)" $(WASM_CFLAGS) -fsyntax-only "$(SYSROOT_SHARE)/include-all.c" -Wno-\#warnings $(WASM_CC) $(CFLAGS) -fsyntax-only "$(SYSROOT_SHARE)/include-all.c" -Wno-\#warnings
# #
# Collect all the predefined macros, except for compiler version macros # Collect all the predefined macros, except for compiler version macros
@ -481,7 +520,7 @@ finish: startup_files libc
@# @#
@# TODO: Undefine __FLOAT128__ for now since it's not in clang 8.0. @# TODO: Undefine __FLOAT128__ for now since it's not in clang 8.0.
@# TODO: Filter out __FLT16_* for now, as not all versions of clang have these. @# TODO: Filter out __FLT16_* for now, as not all versions of clang have these.
"$(WASM_CC)" $(WASM_CFLAGS) "$(SYSROOT_SHARE)/include-all.c" \ $(WASM_CC) $(CFLAGS) "$(SYSROOT_SHARE)/include-all.c" \
-isystem $(SYSROOT_INC) \ -isystem $(SYSROOT_INC) \
-std=gnu17 \ -std=gnu17 \
-E -dM -Wno-\#warnings \ -E -dM -Wno-\#warnings \
@ -492,6 +531,8 @@ finish: startup_files libc
-U__clang_minor__ \ -U__clang_minor__ \
-U__clang_patchlevel__ \ -U__clang_patchlevel__ \
-U__clang_version__ \ -U__clang_version__ \
-U__clang_literal_encoding__ \
-U__clang_wide_literal_encoding__ \
-U__GNUC__ \ -U__GNUC__ \
-U__GNUC_MINOR__ \ -U__GNUC_MINOR__ \
-U__GNUC_PATCHLEVEL__ \ -U__GNUC_PATCHLEVEL__ \
@ -505,10 +546,6 @@ finish: startup_files libc
# This ignores whitespace because on Windows the output has CRLF line endings. # This ignores whitespace because on Windows the output has CRLF line endings.
diff -wur "$(CURDIR)/expected/$(MULTIARCH_TRIPLE)" "$(SYSROOT_SHARE)" diff -wur "$(CURDIR)/expected/$(MULTIARCH_TRIPLE)" "$(SYSROOT_SHARE)"
#
# The build succeeded! The generated sysroot is in $(SYSROOT).
#
install: finish install: finish
mkdir -p "$(INSTALL_DIR)" mkdir -p "$(INSTALL_DIR)"
cp -r "$(SYSROOT)/lib" "$(SYSROOT)/share" "$(SYSROOT)/include" "$(INSTALL_DIR)" cp -r "$(SYSROOT)/lib" "$(SYSROOT)/share" "$(SYSROOT)/include" "$(INSTALL_DIR)"

View File

@ -43,4 +43,8 @@ or libc++abi.a, respectively, so they may not be usable without
extra setup. This is one of the things [wasi-sdk] simplifies, as it includes extra setup. This is one of the things [wasi-sdk] simplifies, as it includes
cross-compiled builds of compiler-rt, libc++.a, and libc++abi.a. cross-compiled builds of compiler-rt, libc++.a, and libc++abi.a.
## Arch Linux AUR package
For Arch Linux users, there's an unofficial AUR package tracking this git repo that can be installed under the name [wasi-libc-git].
[wasi-sdk]: https://github.com/WebAssembly/wasi-sdk [wasi-sdk]: https://github.com/WebAssembly/wasi-sdk
[wasi-libc-git]: https://aur.archlinux.org/packages/wasi-libc-git/

View File

@ -91,3 +91,8 @@ void* aligned_alloc(size_t alignment, size_t bytes) {
size_t malloc_usable_size(void *ptr) { size_t malloc_usable_size(void *ptr) {
return dlmalloc_usable_size(ptr); return dlmalloc_usable_size(ptr);
} }
// Define these to satisfy musl references.
void *__libc_malloc(size_t) __attribute__((alias("malloc")));
void __libc_free(void *) __attribute__((alias("free")));
void *__libc_calloc(size_t nmemb, size_t size) __attribute__((alias("calloc")));

View File

@ -11,11 +11,14 @@ _IO_putc
_IO_putc_unlocked _IO_putc_unlocked
__EINVAL __EINVAL
__ENOMEM __ENOMEM
__SIG_ERR
__SIG_IGN
__asctime_r __asctime_r
__assert_fail __assert_fail
__c_dot_utf8 __c_dot_utf8
__c_dot_utf8_locale __c_dot_utf8_locale
__c_locale __c_locale
__clock
__clock_gettime __clock_gettime
__cos __cos
__cosdf __cosdf
@ -132,6 +135,9 @@ __lgamma_r
__lgammaf_r __lgammaf_r
__lgammal_r __lgammal_r
__libc __libc
__libc_calloc
__libc_free
__libc_malloc
__loc_is_allocated __loc_is_allocated
__localtime_r __localtime_r
__log2_data __log2_data
@ -145,6 +151,7 @@ __math_divzero
__math_divzerof __math_divzerof
__math_invalid __math_invalid
__math_invalidf __math_invalidf
__math_invalidl
__math_oflow __math_oflow
__math_oflowf __math_oflowf
__math_uflow __math_uflow
@ -181,6 +188,7 @@ __rem_pio2
__rem_pio2_large __rem_pio2_large
__rem_pio2f __rem_pio2f
__rem_pio2l __rem_pio2l
__rsqrt_tab
__secs_to_tm __secs_to_tm
__secs_to_zone __secs_to_zone
__seed48 __seed48
@ -227,6 +235,7 @@ __strtoull_internal
__strtoumax_internal __strtoumax_internal
__strxfrm_l __strxfrm_l
__sysinfo __sysinfo
__sysv_signal
__tan __tan
__tandf __tandf
__tanl __tanl
@ -249,7 +258,54 @@ __uflow
__unlist_locked_file __unlist_locked_file
__uselocale __uselocale
__utc __utc
__wasi_args_get
__wasi_args_sizes_get
__wasi_clock_res_get
__wasi_clock_time_get
__wasi_environ_get
__wasi_environ_sizes_get
__wasi_fd_advise
__wasi_fd_allocate
__wasi_fd_close
__wasi_fd_datasync
__wasi_fd_fdstat_get
__wasi_fd_fdstat_set_flags
__wasi_fd_fdstat_set_rights
__wasi_fd_filestat_get
__wasi_fd_filestat_set_size
__wasi_fd_filestat_set_times
__wasi_fd_pread
__wasi_fd_prestat_dir_name
__wasi_fd_prestat_get
__wasi_fd_pwrite
__wasi_fd_read
__wasi_fd_readdir
__wasi_fd_renumber
__wasi_fd_seek
__wasi_fd_sync
__wasi_fd_tell
__wasi_fd_write
__wasi_path_create_directory
__wasi_path_filestat_get
__wasi_path_filestat_set_times
__wasi_path_link
__wasi_path_open
__wasi_path_readlink
__wasi_path_remove_directory
__wasi_path_rename
__wasi_path_symlink
__wasi_path_unlink_file
__wasi_poll_oneoff
__wasi_proc_exit
__wasi_proc_raise
__wasi_random_get
__wasi_sched_yield
__wasi_sock_recv
__wasi_sock_send
__wasi_sock_shutdown
__wasilibc_access
__wasilibc_cwd __wasilibc_cwd
__wasilibc_deinitialize_environ
__wasilibc_ensure_environ __wasilibc_ensure_environ
__wasilibc_environ __wasilibc_environ
__wasilibc_environ __wasilibc_environ
@ -257,13 +313,35 @@ __wasilibc_fd_renumber
__wasilibc_find_abspath __wasilibc_find_abspath
__wasilibc_find_relpath __wasilibc_find_relpath
__wasilibc_find_relpath_alloc __wasilibc_find_relpath_alloc
__wasilibc_get_environ
__wasilibc_initialize_environ __wasilibc_initialize_environ
__wasilibc_link
__wasilibc_link_newat
__wasilibc_link_oldat
__wasilibc_maybe_reinitialize_environ_eagerly
__wasilibc_maybe_reinitialize_environ_eagerly
__wasilibc_nocwd___wasilibc_rmdirat
__wasilibc_nocwd___wasilibc_unlinkat
__wasilibc_nocwd_faccessat
__wasilibc_nocwd_fstatat
__wasilibc_nocwd_linkat
__wasilibc_nocwd_mkdirat_nomode
__wasilibc_nocwd_openat_nomode
__wasilibc_nocwd_opendirat
__wasilibc_nocwd_readlinkat
__wasilibc_nocwd_renameat
__wasilibc_nocwd_scandirat
__wasilibc_nocwd_symlinkat
__wasilibc_nocwd_utimensat
__wasilibc_open_nomode __wasilibc_open_nomode
__wasilibc_openat_nomode
__wasilibc_register_preopened_fd __wasilibc_register_preopened_fd
__wasilibc_rename_newat
__wasilibc_rename_oldat
__wasilibc_rmdirat __wasilibc_rmdirat
__wasilibc_stat
__wasilibc_tell __wasilibc_tell
__wasilibc_unlinkat __wasilibc_unlinkat
__wasilibc_utimens
__wasm_call_dtors __wasm_call_dtors
__wcscoll_l __wcscoll_l
__wcsftime_l __wcsftime_l
@ -322,6 +400,7 @@ atoll
basename basename
bcmp bcmp
bcopy bcopy
bsd_signal
bsearch bsearch
btowc btowc
bzero bzero
@ -594,6 +673,7 @@ getline
getopt getopt
getopt_long getopt_long
getopt_long_only getopt_long_only
getpid
getrusage getrusage
getsockopt getsockopt
getsubopt getsubopt
@ -773,10 +853,12 @@ memset
mkdir mkdir
mkdirat mkdirat
mktime mktime
mmap
modf modf
modff modff
modfl modfl
mrand48 mrand48
munmap
nan nan
nanf nanf
nanl nanl
@ -828,6 +910,7 @@ printf
program_invocation_name program_invocation_name
program_invocation_short_name program_invocation_short_name
pselect pselect
psignal
putc putc
putc_unlocked putc_unlocked
putchar putchar
@ -843,6 +926,7 @@ pwrite
pwritev pwritev
qsort qsort
quick_exit quick_exit
raise
rand rand
rand_r rand_r
random random
@ -904,6 +988,7 @@ setlocale
setstate setstate
setvbuf setvbuf
shutdown shutdown
signal
signgam signgam
significand significand
significandf significandf
@ -965,6 +1050,7 @@ strpbrk
strptime strptime
strrchr strrchr
strsep strsep
strsignal
strspn strspn
strstr strstr
strtod strtod

View File

@ -137,7 +137,6 @@
#include <sys/poll.h> #include <sys/poll.h>
#include <sys/random.h> #include <sys/random.h>
#include <sys/reg.h> #include <sys/reg.h>
#include <sys/resource.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -146,7 +145,6 @@
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/timeb.h> #include <sys/timeb.h>
#include <sys/times.h>
#include <sys/timex.h> #include <sys/timex.h>
#include <sys/ttydefaults.h> #include <sys/ttydefaults.h>
#include <sys/types.h> #include <sys/types.h>
@ -166,6 +164,7 @@
#include <wasi/api.h> #include <wasi/api.h>
#include <wasi/libc-environ.h> #include <wasi/libc-environ.h>
#include <wasi/libc-find-relpath.h> #include <wasi/libc-find-relpath.h>
#include <wasi/libc-nocwd.h>
#include <wasi/libc.h> #include <wasi/libc.h>
#include <wchar.h> #include <wchar.h>
#include <wctype.h> #include <wctype.h>

View File

@ -46,6 +46,7 @@
#define ARG_MAX 131072 #define ARG_MAX 131072
#define ARMAG "!<arch>\n" #define ARMAG "!<arch>\n"
#define AT_EACCESS (0x0) #define AT_EACCESS (0x0)
#define AT_FDCWD (-2)
#define AT_REMOVEDIR (0x4) #define AT_REMOVEDIR (0x4)
#define AT_SYMLINK_FOLLOW (0x2) #define AT_SYMLINK_FOLLOW (0x2)
#define AT_SYMLINK_NOFOLLOW (0x1) #define AT_SYMLINK_NOFOLLOW (0x1)
@ -891,6 +892,7 @@
#define IP_PMTUDISC_PROBE 3 #define IP_PMTUDISC_PROBE 3
#define IP_PMTUDISC_WANT 1 #define IP_PMTUDISC_WANT 1
#define IP_RECVERR 11 #define IP_RECVERR 11
#define IP_RECVERR_RFC4884 26
#define IP_RECVFRAGSIZE 25 #define IP_RECVFRAGSIZE 25
#define IP_RECVOPTS 6 #define IP_RECVOPTS 6
#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR #define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
@ -1705,6 +1707,7 @@
#define TCP_CONGESTION 13 #define TCP_CONGESTION 13
#define TCP_CORK 3 #define TCP_CORK 3
#define TCP_DEFER_ACCEPT 9 #define TCP_DEFER_ACCEPT 9
#define TCP_ENCAP_ESPINTCP 7
#define TCP_ESTABLISHED 1 #define TCP_ESTABLISHED 1
#define TCP_FASTOPEN 23 #define TCP_FASTOPEN 23
#define TCP_FASTOPEN_CONNECT 30 #define TCP_FASTOPEN_CONNECT 30
@ -1723,7 +1726,8 @@
#define TCP_MAXSEG 2 #define TCP_MAXSEG 2
#define TCP_MD5SIG 14 #define TCP_MD5SIG 14
#define TCP_MD5SIG_EXT 32 #define TCP_MD5SIG_EXT 32
#define TCP_MD5SIG_FLAG_PREFIX 1 #define TCP_MD5SIG_FLAG_IFINDEX 0x2
#define TCP_MD5SIG_FLAG_PREFIX 0x1
#define TCP_MD5SIG_MAXKEYLEN 80 #define TCP_MD5SIG_MAXKEYLEN 80
#define TCP_NODELAY 1 #define TCP_NODELAY 1
#define TCP_NOTSENT_LOWAT 25 #define TCP_NOTSENT_LOWAT 25
@ -2305,14 +2309,12 @@
#define _SYS_PARAM_H #define _SYS_PARAM_H
#define _SYS_RANDOM_H #define _SYS_RANDOM_H
#define _SYS_REG_H #define _SYS_REG_H
#define _SYS_RESOURCE_H
#define _SYS_SELECT_H #define _SYS_SELECT_H
#define _SYS_SOCKET_H #define _SYS_SOCKET_H
#define _SYS_STAT_H #define _SYS_STAT_H
#define _SYS_SYSCALL_H #define _SYS_SYSCALL_H
#define _SYS_SYSINFO_H #define _SYS_SYSINFO_H
#define _SYS_TIMEB_H #define _SYS_TIMEB_H
#define _SYS_TIMES_H
#define _SYS_TIMEX_H #define _SYS_TIMEX_H
#define _SYS_TIME_H #define _SYS_TIME_H
#define _SYS_TTYDEFAULTS_H #define _SYS_TTYDEFAULTS_H
@ -2893,15 +2895,15 @@
#define __WASI_ERRNO_TIMEDOUT (UINT16_C(73)) #define __WASI_ERRNO_TIMEDOUT (UINT16_C(73))
#define __WASI_ERRNO_TXTBSY (UINT16_C(74)) #define __WASI_ERRNO_TXTBSY (UINT16_C(74))
#define __WASI_ERRNO_XDEV (UINT16_C(75)) #define __WASI_ERRNO_XDEV (UINT16_C(75))
#define __WASI_EVENTRWFLAGS_FD_READWRITE_HANGUP (UINT16_C(1)) #define __WASI_EVENTRWFLAGS_FD_READWRITE_HANGUP ((__wasi_eventrwflags_t)(1 << 0))
#define __WASI_EVENTTYPE_CLOCK (UINT8_C(0)) #define __WASI_EVENTTYPE_CLOCK (UINT8_C(0))
#define __WASI_EVENTTYPE_FD_READ (UINT8_C(1)) #define __WASI_EVENTTYPE_FD_READ (UINT8_C(1))
#define __WASI_EVENTTYPE_FD_WRITE (UINT8_C(2)) #define __WASI_EVENTTYPE_FD_WRITE (UINT8_C(2))
#define __WASI_FDFLAGS_APPEND (UINT16_C(1)) #define __WASI_FDFLAGS_APPEND ((__wasi_fdflags_t)(1 << 0))
#define __WASI_FDFLAGS_DSYNC (UINT16_C(2)) #define __WASI_FDFLAGS_DSYNC ((__wasi_fdflags_t)(1 << 1))
#define __WASI_FDFLAGS_NONBLOCK (UINT16_C(4)) #define __WASI_FDFLAGS_NONBLOCK ((__wasi_fdflags_t)(1 << 2))
#define __WASI_FDFLAGS_RSYNC (UINT16_C(8)) #define __WASI_FDFLAGS_RSYNC ((__wasi_fdflags_t)(1 << 3))
#define __WASI_FDFLAGS_SYNC (UINT16_C(16)) #define __WASI_FDFLAGS_SYNC ((__wasi_fdflags_t)(1 << 4))
#define __WASI_FILETYPE_BLOCK_DEVICE (UINT8_C(1)) #define __WASI_FILETYPE_BLOCK_DEVICE (UINT8_C(1))
#define __WASI_FILETYPE_CHARACTER_DEVICE (UINT8_C(2)) #define __WASI_FILETYPE_CHARACTER_DEVICE (UINT8_C(2))
#define __WASI_FILETYPE_DIRECTORY (UINT8_C(3)) #define __WASI_FILETYPE_DIRECTORY (UINT8_C(3))
@ -2910,50 +2912,50 @@
#define __WASI_FILETYPE_SOCKET_STREAM (UINT8_C(6)) #define __WASI_FILETYPE_SOCKET_STREAM (UINT8_C(6))
#define __WASI_FILETYPE_SYMBOLIC_LINK (UINT8_C(7)) #define __WASI_FILETYPE_SYMBOLIC_LINK (UINT8_C(7))
#define __WASI_FILETYPE_UNKNOWN (UINT8_C(0)) #define __WASI_FILETYPE_UNKNOWN (UINT8_C(0))
#define __WASI_FSTFLAGS_ATIM (UINT16_C(1)) #define __WASI_FSTFLAGS_ATIM ((__wasi_fstflags_t)(1 << 0))
#define __WASI_FSTFLAGS_ATIM_NOW (UINT16_C(2)) #define __WASI_FSTFLAGS_ATIM_NOW ((__wasi_fstflags_t)(1 << 1))
#define __WASI_FSTFLAGS_MTIM (UINT16_C(4)) #define __WASI_FSTFLAGS_MTIM ((__wasi_fstflags_t)(1 << 2))
#define __WASI_FSTFLAGS_MTIM_NOW (UINT16_C(8)) #define __WASI_FSTFLAGS_MTIM_NOW ((__wasi_fstflags_t)(1 << 3))
#define __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW (UINT32_C(1)) #define __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW ((__wasi_lookupflags_t)(1 << 0))
#define __WASI_OFLAGS_CREAT (UINT16_C(1)) #define __WASI_OFLAGS_CREAT ((__wasi_oflags_t)(1 << 0))
#define __WASI_OFLAGS_DIRECTORY (UINT16_C(2)) #define __WASI_OFLAGS_DIRECTORY ((__wasi_oflags_t)(1 << 1))
#define __WASI_OFLAGS_EXCL (UINT16_C(4)) #define __WASI_OFLAGS_EXCL ((__wasi_oflags_t)(1 << 2))
#define __WASI_OFLAGS_TRUNC (UINT16_C(8)) #define __WASI_OFLAGS_TRUNC ((__wasi_oflags_t)(1 << 3))
#define __WASI_PREOPENTYPE_DIR (UINT8_C(0)) #define __WASI_PREOPENTYPE_DIR (UINT8_C(0))
#define __WASI_RIFLAGS_RECV_PEEK (UINT16_C(1)) #define __WASI_RIFLAGS_RECV_PEEK ((__wasi_riflags_t)(1 << 0))
#define __WASI_RIFLAGS_RECV_WAITALL (UINT16_C(2)) #define __WASI_RIFLAGS_RECV_WAITALL ((__wasi_riflags_t)(1 << 1))
#define __WASI_RIGHTS_FD_ADVISE (UINT64_C(128)) #define __WASI_RIGHTS_FD_ADVISE ((__wasi_rights_t)(1 << 7))
#define __WASI_RIGHTS_FD_ALLOCATE (UINT64_C(256)) #define __WASI_RIGHTS_FD_ALLOCATE ((__wasi_rights_t)(1 << 8))
#define __WASI_RIGHTS_FD_DATASYNC (UINT64_C(1)) #define __WASI_RIGHTS_FD_DATASYNC ((__wasi_rights_t)(1 << 0))
#define __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS (UINT64_C(8)) #define __WASI_RIGHTS_FD_FDSTAT_SET_FLAGS ((__wasi_rights_t)(1 << 3))
#define __WASI_RIGHTS_FD_FILESTAT_GET (UINT64_C(2097152)) #define __WASI_RIGHTS_FD_FILESTAT_GET ((__wasi_rights_t)(1 << 21))
#define __WASI_RIGHTS_FD_FILESTAT_SET_SIZE (UINT64_C(4194304)) #define __WASI_RIGHTS_FD_FILESTAT_SET_SIZE ((__wasi_rights_t)(1 << 22))
#define __WASI_RIGHTS_FD_FILESTAT_SET_TIMES (UINT64_C(8388608)) #define __WASI_RIGHTS_FD_FILESTAT_SET_TIMES ((__wasi_rights_t)(1 << 23))
#define __WASI_RIGHTS_FD_READ (UINT64_C(2)) #define __WASI_RIGHTS_FD_READ ((__wasi_rights_t)(1 << 1))
#define __WASI_RIGHTS_FD_READDIR (UINT64_C(16384)) #define __WASI_RIGHTS_FD_READDIR ((__wasi_rights_t)(1 << 14))
#define __WASI_RIGHTS_FD_SEEK (UINT64_C(4)) #define __WASI_RIGHTS_FD_SEEK ((__wasi_rights_t)(1 << 2))
#define __WASI_RIGHTS_FD_SYNC (UINT64_C(16)) #define __WASI_RIGHTS_FD_SYNC ((__wasi_rights_t)(1 << 4))
#define __WASI_RIGHTS_FD_TELL (UINT64_C(32)) #define __WASI_RIGHTS_FD_TELL ((__wasi_rights_t)(1 << 5))
#define __WASI_RIGHTS_FD_WRITE (UINT64_C(64)) #define __WASI_RIGHTS_FD_WRITE ((__wasi_rights_t)(1 << 6))
#define __WASI_RIGHTS_PATH_CREATE_DIRECTORY (UINT64_C(512)) #define __WASI_RIGHTS_PATH_CREATE_DIRECTORY ((__wasi_rights_t)(1 << 9))
#define __WASI_RIGHTS_PATH_CREATE_FILE (UINT64_C(1024)) #define __WASI_RIGHTS_PATH_CREATE_FILE ((__wasi_rights_t)(1 << 10))
#define __WASI_RIGHTS_PATH_FILESTAT_GET (UINT64_C(262144)) #define __WASI_RIGHTS_PATH_FILESTAT_GET ((__wasi_rights_t)(1 << 18))
#define __WASI_RIGHTS_PATH_FILESTAT_SET_SIZE (UINT64_C(524288)) #define __WASI_RIGHTS_PATH_FILESTAT_SET_SIZE ((__wasi_rights_t)(1 << 19))
#define __WASI_RIGHTS_PATH_FILESTAT_SET_TIMES (UINT64_C(1048576)) #define __WASI_RIGHTS_PATH_FILESTAT_SET_TIMES ((__wasi_rights_t)(1 << 20))
#define __WASI_RIGHTS_PATH_LINK_SOURCE (UINT64_C(2048)) #define __WASI_RIGHTS_PATH_LINK_SOURCE ((__wasi_rights_t)(1 << 11))
#define __WASI_RIGHTS_PATH_LINK_TARGET (UINT64_C(4096)) #define __WASI_RIGHTS_PATH_LINK_TARGET ((__wasi_rights_t)(1 << 12))
#define __WASI_RIGHTS_PATH_OPEN (UINT64_C(8192)) #define __WASI_RIGHTS_PATH_OPEN ((__wasi_rights_t)(1 << 13))
#define __WASI_RIGHTS_PATH_READLINK (UINT64_C(32768)) #define __WASI_RIGHTS_PATH_READLINK ((__wasi_rights_t)(1 << 15))
#define __WASI_RIGHTS_PATH_REMOVE_DIRECTORY (UINT64_C(33554432)) #define __WASI_RIGHTS_PATH_REMOVE_DIRECTORY ((__wasi_rights_t)(1 << 25))
#define __WASI_RIGHTS_PATH_RENAME_SOURCE (UINT64_C(65536)) #define __WASI_RIGHTS_PATH_RENAME_SOURCE ((__wasi_rights_t)(1 << 16))
#define __WASI_RIGHTS_PATH_RENAME_TARGET (UINT64_C(131072)) #define __WASI_RIGHTS_PATH_RENAME_TARGET ((__wasi_rights_t)(1 << 17))
#define __WASI_RIGHTS_PATH_SYMLINK (UINT64_C(16777216)) #define __WASI_RIGHTS_PATH_SYMLINK ((__wasi_rights_t)(1 << 24))
#define __WASI_RIGHTS_PATH_UNLINK_FILE (UINT64_C(67108864)) #define __WASI_RIGHTS_PATH_UNLINK_FILE ((__wasi_rights_t)(1 << 26))
#define __WASI_RIGHTS_POLL_FD_READWRITE (UINT64_C(134217728)) #define __WASI_RIGHTS_POLL_FD_READWRITE ((__wasi_rights_t)(1 << 27))
#define __WASI_RIGHTS_SOCK_SHUTDOWN (UINT64_C(268435456)) #define __WASI_RIGHTS_SOCK_SHUTDOWN ((__wasi_rights_t)(1 << 28))
#define __WASI_ROFLAGS_RECV_DATA_TRUNCATED (UINT16_C(1)) #define __WASI_ROFLAGS_RECV_DATA_TRUNCATED ((__wasi_roflags_t)(1 << 0))
#define __WASI_SDFLAGS_RD (UINT8_C(1)) #define __WASI_SDFLAGS_RD ((__wasi_sdflags_t)(1 << 0))
#define __WASI_SDFLAGS_WR (UINT8_C(2)) #define __WASI_SDFLAGS_WR ((__wasi_sdflags_t)(1 << 1))
#define __WASI_SIGNAL_ABRT (UINT8_C(6)) #define __WASI_SIGNAL_ABRT (UINT8_C(6))
#define __WASI_SIGNAL_ALRM (UINT8_C(14)) #define __WASI_SIGNAL_ALRM (UINT8_C(14))
#define __WASI_SIGNAL_BUS (UINT8_C(7)) #define __WASI_SIGNAL_BUS (UINT8_C(7))
@ -2985,7 +2987,7 @@
#define __WASI_SIGNAL_WINCH (UINT8_C(27)) #define __WASI_SIGNAL_WINCH (UINT8_C(27))
#define __WASI_SIGNAL_XCPU (UINT8_C(23)) #define __WASI_SIGNAL_XCPU (UINT8_C(23))
#define __WASI_SIGNAL_XFSZ (UINT8_C(24)) #define __WASI_SIGNAL_XFSZ (UINT8_C(24))
#define __WASI_SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME (UINT16_C(1)) #define __WASI_SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME ((__wasi_subclockflags_t)(1 << 0))
#define __WASI_WHENCE_CUR (UINT8_C(1)) #define __WASI_WHENCE_CUR (UINT8_C(1))
#define __WASI_WHENCE_END (UINT8_C(2)) #define __WASI_WHENCE_END (UINT8_C(2))
#define __WASI_WHENCE_SET (UINT8_C(0)) #define __WASI_WHENCE_SET (UINT8_C(0))
@ -3021,6 +3023,7 @@
#define __wasi_libc_environ_h #define __wasi_libc_environ_h
#define __wasi_libc_find_relpath_h #define __wasi_libc_find_relpath_h
#define __wasi_libc_h #define __wasi_libc_h
#define __wasi_libc_nocwd_h
#define __wasilibc___errno_h #define __wasilibc___errno_h
#define __wasilibc___errno_values_h #define __wasilibc___errno_values_h
#define __wasilibc___fd_set_h #define __wasilibc___fd_set_h
@ -3120,6 +3123,8 @@
#define cbrt(x) __tg_real(cbrt, (x)) #define cbrt(x) __tg_real(cbrt, (x))
#define ceil(x) __tg_real(ceil, (x)) #define ceil(x) __tg_real(ceil, (x))
#define cimag(x) __tg_complex_retreal(cimag, (x)) #define cimag(x) __tg_complex_retreal(cimag, (x))
#define cimagf(x) (__builtin_cimagf(x))
#define cimagl(x) (__builtin_cimagl(x))
#define clrbit(x,i) __bitop(x,i,&=~) #define clrbit(x,i) __bitop(x,i,&=~)
#define compl ~ #define compl ~
#define complex _Complex #define complex _Complex
@ -3129,6 +3134,8 @@
#define cosh(x) __tg_real_complex(cosh, (x)) #define cosh(x) __tg_real_complex(cosh, (x))
#define cproj(x) __tg_complex(cproj, (x)) #define cproj(x) __tg_complex(cproj, (x))
#define creal(x) __tg_complex_retreal(creal, (x)) #define creal(x) __tg_complex_retreal(creal, (x))
#define crealf(x) (__builtin_crealf(x))
#define creall(x) (__builtin_creall(x))
#define creat64 creat #define creat64 creat
#define d_fileno d_ino #define d_fileno d_ino
#define direct dirent #define direct dirent

View File

@ -11,6 +11,51 @@ __floatunsitf
__getf2 __getf2
__gttf2 __gttf2
__heap_base __heap_base
__imported_wasi_snapshot_preview1_args_get
__imported_wasi_snapshot_preview1_args_sizes_get
__imported_wasi_snapshot_preview1_clock_res_get
__imported_wasi_snapshot_preview1_clock_time_get
__imported_wasi_snapshot_preview1_environ_get
__imported_wasi_snapshot_preview1_environ_sizes_get
__imported_wasi_snapshot_preview1_fd_advise
__imported_wasi_snapshot_preview1_fd_allocate
__imported_wasi_snapshot_preview1_fd_close
__imported_wasi_snapshot_preview1_fd_datasync
__imported_wasi_snapshot_preview1_fd_fdstat_get
__imported_wasi_snapshot_preview1_fd_fdstat_set_flags
__imported_wasi_snapshot_preview1_fd_fdstat_set_rights
__imported_wasi_snapshot_preview1_fd_filestat_get
__imported_wasi_snapshot_preview1_fd_filestat_set_size
__imported_wasi_snapshot_preview1_fd_filestat_set_times
__imported_wasi_snapshot_preview1_fd_pread
__imported_wasi_snapshot_preview1_fd_prestat_dir_name
__imported_wasi_snapshot_preview1_fd_prestat_get
__imported_wasi_snapshot_preview1_fd_pwrite
__imported_wasi_snapshot_preview1_fd_read
__imported_wasi_snapshot_preview1_fd_readdir
__imported_wasi_snapshot_preview1_fd_renumber
__imported_wasi_snapshot_preview1_fd_seek
__imported_wasi_snapshot_preview1_fd_sync
__imported_wasi_snapshot_preview1_fd_tell
__imported_wasi_snapshot_preview1_fd_write
__imported_wasi_snapshot_preview1_path_create_directory
__imported_wasi_snapshot_preview1_path_filestat_get
__imported_wasi_snapshot_preview1_path_filestat_set_times
__imported_wasi_snapshot_preview1_path_link
__imported_wasi_snapshot_preview1_path_open
__imported_wasi_snapshot_preview1_path_readlink
__imported_wasi_snapshot_preview1_path_remove_directory
__imported_wasi_snapshot_preview1_path_rename
__imported_wasi_snapshot_preview1_path_symlink
__imported_wasi_snapshot_preview1_path_unlink_file
__imported_wasi_snapshot_preview1_poll_oneoff
__imported_wasi_snapshot_preview1_proc_exit
__imported_wasi_snapshot_preview1_proc_raise
__imported_wasi_snapshot_preview1_random_get
__imported_wasi_snapshot_preview1_sched_yield
__imported_wasi_snapshot_preview1_sock_recv
__imported_wasi_snapshot_preview1_sock_send
__imported_wasi_snapshot_preview1_sock_shutdown
__letf2 __letf2
__lttf2 __lttf2
__netf2 __netf2
@ -19,48 +64,5 @@ __subtf3
__trunctfdf2 __trunctfdf2
__trunctfsf2 __trunctfsf2
__unordtf2 __unordtf2
__wasi_args_get
__wasi_args_sizes_get
__wasi_clock_res_get
__wasi_clock_time_get
__wasi_environ_get
__wasi_environ_sizes_get
__wasi_fd_advise
__wasi_fd_allocate
__wasi_fd_close
__wasi_fd_datasync
__wasi_fd_fdstat_get
__wasi_fd_fdstat_set_flags
__wasi_fd_filestat_get
__wasi_fd_filestat_set_size
__wasi_fd_filestat_set_times
__wasi_fd_pread
__wasi_fd_prestat_dir_name
__wasi_fd_prestat_get
__wasi_fd_pwrite
__wasi_fd_read
__wasi_fd_readdir
__wasi_fd_renumber
__wasi_fd_seek
__wasi_fd_sync
__wasi_fd_tell
__wasi_fd_write
__wasi_path_create_directory
__wasi_path_filestat_get
__wasi_path_filestat_set_times
__wasi_path_link
__wasi_path_open
__wasi_path_readlink
__wasi_path_remove_directory
__wasi_path_rename
__wasi_path_symlink
__wasi_path_unlink_file
__wasi_poll_oneoff
__wasi_proc_exit
__wasi_random_get
__wasi_sched_yield
__wasi_sock_recv
__wasi_sock_send
__wasi_sock_shutdown
__wasm_call_ctors __wasm_call_ctors
main main

View File

@ -0,0 +1,35 @@
#define _WASI_EMULATED_PROCESS_CLOCKS
#include <time.h>
#include <wasi/api.h>
#include <common/time.h>
_Static_assert(
CLOCKS_PER_SEC == NSEC_PER_SEC,
"This implementation assumes that `clock` is in nanoseconds"
);
// Snapshot of the monotonic clock at the start of the program.
static __wasi_timestamp_t start;
// Use a priority of 10 to run fairly early in the implementation-reserved
// constructor priority range.
__attribute__((constructor(10)))
static void init(void) {
(void)__wasi_clock_time_get(__WASI_CLOCKID_MONOTONIC, 0, &start);
}
// Define the libc symbol as `__clock` so that we can reliably call it
// from elsewhere in libc.
clock_t __clock(void) {
// Use `MONOTONIC` instead of `PROCESS_CPUTIME_ID` since WASI doesn't have
// an inherent concept of a process. Note that this means we'll incorrectly
// include time from other processes, so this function is only declared by
// the headers if `_WASI_EMULATED_PROCESS_CLOCKS` is defined.
__wasi_timestamp_t now = 0;
(void)__wasi_clock_time_get(__WASI_CLOCKID_MONOTONIC, 0, &now);
return now - start;
}
// Define a user-visible alias as a weak symbol.
__attribute__((__weak__, __alias__("__clock")))
clock_t clock(void);

View File

@ -0,0 +1,28 @@
#define _WASI_EMULATED_PROCESS_CLOCKS
#include <sys/resource.h>
#include <errno.h>
#include <time.h>
#include <wasi/api.h>
#include <common/time.h>
// `clock` is a weak symbol so that application code can override it.
// We want to use the function in libc, so use the libc-internal name.
clock_t __clock(void);
int getrusage(int who, struct rusage *r_usage) {
switch (who) {
case RUSAGE_SELF: {
__wasi_timestamp_t usertime = __clock();
*r_usage = (struct rusage) {
.ru_utime = timestamp_to_timeval(usertime)
};
return 0;
}
case RUSAGE_CHILDREN:
*r_usage = (struct rusage) {};
return 0;
default:
errno = EINVAL;
return -1;
}
}

View File

@ -0,0 +1,26 @@
#define _WASI_EMULATED_PROCESS_CLOCKS
#include <time.h>
#include <sys/times.h>
#include <wasi/api.h>
#include <common/time.h>
_Static_assert(
CLOCKS_PER_SEC == NSEC_PER_SEC,
"This implementation assumes that `clock` is in nanoseconds"
);
// `clock` is a weak symbol so that application code can override it.
// We want to use the function in libc, so use the libc-internal name.
clock_t __clock(void);
clock_t times(struct tms *buffer) {
__wasi_timestamp_t user = __clock();
*buffer = (struct tms){
.tms_utime = user,
.tms_cutime = user
};
__wasi_timestamp_t realtime = 0;
(void)__wasi_clock_time_get(__WASI_CLOCKID_MONOTONIC, 0, &realtime);
return realtime;
}

View File

@ -7,78 +7,16 @@
#include <wasi/api.h> #include <wasi/api.h>
#ifdef __wasilibc_unmodified_upstream
// Translates ENOTCAPABLE to ENOTDIR if not a directory.
static inline __wasi_errno_t errno_fixup_directory(__wasi_fd_t fd,
__wasi_errno_t error) {
if (error == __WASI_ENOTCAPABLE) {
__wasi_fdstat_t fds;
if (__wasi_fd_stat_get(fd, &fds) == 0 &&
fds.fs_filetype != __WASI_FILETYPE_DIRECTORY)
return __WASI_ENOTDIR;
}
return error;
}
#else
// WASI syscalls should just return ENOTDIR if that's what the problem is. // WASI syscalls should just return ENOTDIR if that's what the problem is.
static inline __wasi_errno_t errno_fixup_directory(__wasi_fd_t fd, static inline __wasi_errno_t errno_fixup_directory(__wasi_fd_t fd,
__wasi_errno_t error) { __wasi_errno_t error) {
return error; return error;
} }
#endif
#ifdef __wasilibc_unmodified_upstream // posix_spawn etc.
// Translates ENOTCAPABLE to EBADF if a regular file or EACCES otherwise.
static inline __wasi_errno_t errno_fixup_executable(__wasi_fd_t fd,
__wasi_errno_t error) {
if (error == __WASI_ENOTCAPABLE) {
__wasi_fdstat_t fds;
if (__wasi_fd_stat_get(fd, &fds) == 0)
return fds.fs_filetype == __WASI_FILETYPE_REGULAR_FILE
? __WASI_EBADF
: __WASI_EACCES;
}
return error;
}
#endif
#ifdef __wasilibc_unmodified_upstream // process file descriptors
// Translates ENOTCAPABLE to EINVAL if not a process.
static inline __wasi_errno_t errno_fixup_process(__wasi_fd_t fd,
__wasi_errno_t error) {
if (error == __WASI_ENOTCAPABLE) {
__wasi_fdstat_t fds;
if (__wasi_fd_stat_get(fd, &fds) == 0 &&
fds.fs_filetype != __WASI_FILETYPE_PROCESS)
return __WASI_EINVAL;
}
return error;
}
#endif
#ifdef __wasilibc_unmodified_upstream
// Translates ENOTCAPABLE to ENOTSOCK if not a socket.
static inline __wasi_errno_t errno_fixup_socket(__wasi_fd_t fd,
__wasi_errno_t error) {
if (error == __WASI_ENOTCAPABLE) {
__wasi_fdstat_t fds;
if (__wasi_fd_stat_get(fd, &fds) == 0 &&
#ifdef __wasilibc_unmodified_upstream // don't hard-code magic numbers
(fds.fs_filetype & 0xf0) != 0x80)
#else
(fds.fs_filetype != __WASI_FILETYPE_SOCKET_STREAM &&
fds.fs_filetype != __WASI_FILETYPE_SOCKET_DGRAM))
#endif
return __WASI_ENOTSOCK;
}
return error;
}
#else
// WASI syscalls should just return ENOTSOCK if that's what the problem is. // WASI syscalls should just return ENOTSOCK if that's what the problem is.
static inline __wasi_errno_t errno_fixup_socket(__wasi_fd_t fd, static inline __wasi_errno_t errno_fixup_socket(__wasi_fd_t fd,
__wasi_errno_t error) { __wasi_errno_t error) {
return error; return error;
} }
#endif
#endif #endif

View File

@ -69,223 +69,18 @@
#include <_/limits.h> #include <_/limits.h>
#include <_/types.h> #include <_/types.h>
#ifdef __wasilibc_unmodified_upstream
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
#define RAND_MAX _INT_MAX
#define NULL _NULL
typedef struct {
int quot;
int rem;
} div_t;
typedef struct {
long quot;
long rem;
} ldiv_t;
typedef struct {
long long quot;
long long rem;
} lldiv_t;
#ifndef _SIZE_T_DECLARED
typedef __size_t size_t;
#define _SIZE_T_DECLARED
#endif
#ifndef _WCHAR_T_DECLARED
typedef __wchar_t wchar_t;
#define _WCHAR_T_DECLARED
#endif
#ifdef __wasilibc_unmodified_upstream
// Process wide locale always uses ASCII.
#define MB_CUR_MAX ((size_t)1)
#endif
// Keep existing code happy that assumes that MB_CUR_MAX_L is a macro.
#define MB_CUR_MAX_L MB_CUR_MAX_L
#define alloca(size) __builtin_alloca(size)
#endif
__BEGIN_DECLS __BEGIN_DECLS
_Noreturn void _Exit(int); _Noreturn void _Exit(int);
#ifdef __wasilibc_unmodified_upstream
size_t MB_CUR_MAX_L(__locale_t);
long a64l(const char *);
#endif
_Noreturn void abort(void); _Noreturn void abort(void);
#ifdef __wasilibc_unmodified_upstream
int abs(int) __pure2;
int at_quick_exit(void (*)(void));
int atexit(void (*)(void));
void *aligned_alloc(size_t, size_t);
__uint32_t arc4random(void);
void arc4random_buf(void *, size_t);
__uint32_t arc4random_uniform(__uint32_t);
double atof(const char *);
int atoi(const char *);
long atol(const char *);
long long atoll(const char *);
void *bsearch(const void *, const void *, size_t, size_t,
int (*)(const void *, const void *));
#endif
void *calloc(size_t, size_t); void *calloc(size_t, size_t);
#ifdef __wasilibc_unmodified_upstream
div_t div(int, int) __pure2;
double drand48(void);
double erand48(__uint16_t *);
#endif
_Noreturn void exit(int); _Noreturn void exit(int);
void free(void *); void free(void *);
#ifdef __wasilibc_unmodified_upstream
char *getenv(const char *);
int getsubopt(char **, char *const *, char **);
long jrand48(__uint16_t *);
int l64a_r(long, char *, int);
long labs(long) __pure2;
ldiv_t ldiv(long, long) __pure2;
long long llabs(long long) __pure2;
lldiv_t lldiv(long long, long long) __pure2;
long lrand48(void);
#endif
void *malloc(size_t); void *malloc(size_t);
#ifdef __wasilibc_unmodified_upstream
int mblen(const char *, size_t);
int mblen_l(const char *, size_t, __locale_t);
size_t mbstowcs(wchar_t *__restrict, const char *__restrict, size_t);
size_t mbstowcs_l(wchar_t *__restrict, const char *__restrict, size_t,
__locale_t);
int mbtowc(wchar_t *__restrict, const char *__restrict, size_t);
int mbtowc_l(wchar_t *__restrict, const char *__restrict, size_t, __locale_t);
long mrand48(void);
long nrand48(__uint16_t *);
int posix_memalign(void **, size_t, size_t);
#endif
void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
#ifdef __wasilibc_unmodified_upstream
void qsort_r(void *, size_t, size_t,
int (*)(const void *, const void *, void *), void *);
_Noreturn void quick_exit(int);
int rand(void);
long random(void);
#endif
void *realloc(void *, size_t); void *realloc(void *, size_t);
#ifdef __wasilibc_unmodified_upstream
void *reallocarray(void *, size_t, size_t);
double strtod(const char *__restrict, char **__restrict);
double strtod_l(const char *__restrict, char **__restrict, __locale_t);
float strtof(const char *__restrict, char **__restrict);
float strtof_l(const char *__restrict, char **__restrict, __locale_t);
long strtol(const char *__restrict, char **__restrict, int);
long strtol_l(const char *__restrict, char **__restrict, int, __locale_t);
long double strtold(const char *__restrict, char **__restrict);
long double strtold_l(const char *__restrict, char **__restrict, __locale_t);
long long strtoll(const char *__restrict, char **__restrict, int);
long long strtoll_l(const char *__restrict, char **__restrict, int, __locale_t);
unsigned long strtoul(const char *__restrict, char **__restrict, int);
unsigned long strtoul_l(const char *__restrict, char **__restrict, int,
__locale_t);
unsigned long long strtoull(const char *__restrict, char **__restrict, int);
unsigned long long strtoull_l(const char *__restrict, char **__restrict, int,
__locale_t);
size_t wcstombs(char *__restrict, const wchar_t *__restrict, size_t);
size_t wcstombs_l(char *__restrict, const wchar_t *__restrict, size_t,
__locale_t);
int wctomb(char *, wchar_t);
int wctomb_l(char *, wchar_t, __locale_t);
#endif
__END_DECLS __END_DECLS
#if _CLOUDLIBC_INLINE_FUNCTIONS #if _CLOUDLIBC_INLINE_FUNCTIONS
#ifdef __wasilibc_unmodified_upstream
static __inline double __atof(const char *__str) {
return strtod(__str, NULL);
}
#define atof(str) __atof(str)
static __inline int __atoi(const char *__str) {
return (int)strtol(__str, NULL, 10);
}
#define atoi(str) __atoi(str)
static __inline long __atol(const char *__str) {
return strtol(__str, NULL, 10);
}
#define atol(str) __atol(str)
static __inline long long __atoll(const char *__str) {
return strtoll(__str, NULL, 10);
}
#define atoll(str) __atoll(str)
static __inline int __abs(int __i) {
return __i < 0 ? -__i : __i;
}
#define abs(i) __abs(i)
static __inline long __labs(long __i) {
return __i < 0 ? -__i : __i;
}
#define labs(i) __labs(i)
static __inline long long __llabs(long long __i) {
return __i < 0 ? -__i : __i;
}
#define llabs(i) __llabs(i)
static __inline div_t __div(int __numer, int __denom) {
div_t __res = {__numer / __denom, __numer % __denom};
return __res;
}
#define div(numer, denom) __div(numer, denom)
static __inline ldiv_t __ldiv(long __numer, long __denom) {
ldiv_t __res = {__numer / __denom, __numer % __denom};
return __res;
}
#define ldiv(numer, denom) __ldiv(numer, denom)
static __inline lldiv_t __lldiv(long long __numer, long long __denom) {
lldiv_t __res = {__numer / __denom, __numer % __denom};
return __res;
}
#define lldiv(numer, denom) __lldiv(numer, denom)
static __inline void *__bsearch(const void *__key, const void *__base,
size_t __nel, size_t __width,
int (*__compar)(const void *, const void *)) {
const char *__basep, *__obj;
size_t __mid, __skip;
int __cmp;
__basep = (const char *)__base;
while (__nel > 0) {
// Pick pivot.
__mid = __nel / 2;
__obj = __basep + __mid * __width;
__cmp = __compar(__key, (const void *)__obj);
if (__cmp < 0) {
// key < obj. Restrict search to top of the list.
__nel = __mid;
} else if (__cmp > 0) {
// key > obj. Restrict search to bottom of the list.
__skip = __mid + 1;
__basep += __skip * __width;
__nel -= __skip;
} else {
return (void *)__obj;
}
}
return NULL;
}
#define bsearch(key, base, nel, width, compar) \
__preserve_const(void, __bsearch, base, key, base, nel, width, compar)
#endif
// qsort_r() implementation from Bentley and McIlroy's // qsort_r() implementation from Bentley and McIlroy's
// "Engineering a Sort Function". // "Engineering a Sort Function".

View File

@ -25,12 +25,8 @@ DIR *fdopendir(int fd) {
// Ensure that this is really a directory by already loading the first // Ensure that this is really a directory by already loading the first
// chunk of data. // chunk of data.
__wasi_errno_t error = __wasi_errno_t error =
#ifdef __wasilibc_unmodified_upstream
__wasi_file_readdir(fd, dirp->buffer, DIRENT_DEFAULT_BUFFER_SIZE,
#else
// TODO: Remove the cast on `dirp->buffer` once the witx is updated with char8 support. // TODO: Remove the cast on `dirp->buffer` once the witx is updated with char8 support.
__wasi_fd_readdir(fd, (uint8_t *)dirp->buffer, DIRENT_DEFAULT_BUFFER_SIZE, __wasi_fd_readdir(fd, (uint8_t *)dirp->buffer, DIRENT_DEFAULT_BUFFER_SIZE,
#endif
__WASI_DIRCOOKIE_START, &dirp->buffer_used); __WASI_DIRCOOKIE_START, &dirp->buffer_used);
if (error != 0) { if (error != 0) {
free(dirp->buffer); free(dirp->buffer);

View File

@ -3,18 +3,15 @@
// SPDX-License-Identifier: BSD-2-Clause // SPDX-License-Identifier: BSD-2-Clause
#include <wasi/libc.h> #include <wasi/libc.h>
#include <wasi/libc-nocwd.h>
#include <dirent.h> #include <dirent.h>
#include <fcntl.h> #include <fcntl.h>
#include <stddef.h> #include <stddef.h>
#include <unistd.h> #include <unistd.h>
DIR *opendirat(int dir, const char *dirname) { DIR *__wasilibc_nocwd_opendirat(int dir, const char *dirname) {
// Open directory. // Open directory.
#ifdef __wasilibc_unmodified_upstream // avoid making a varargs call int fd = __wasilibc_nocwd_openat_nomode(dir, dirname, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
int fd = openat(dir, dirname, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
#else
int fd = __wasilibc_openat_nomode(dir, dirname, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
#endif
if (fd == -1) if (fd == -1)
return NULL; return NULL;

View File

@ -91,12 +91,8 @@ struct dirent *readdir(DIR *dirp) {
// Load more directory entries and continue. // Load more directory entries and continue.
__wasi_errno_t error = __wasi_errno_t error =
#ifdef __wasilibc_unmodified_upstream
__wasi_file_readdir(dirp->fd, dirp->buffer, dirp->buffer_size,
#else
// TODO: Remove the cast on `dirp->buffer` once the witx is updated with char8 support. // TODO: Remove the cast on `dirp->buffer` once the witx is updated with char8 support.
__wasi_fd_readdir(dirp->fd, (uint8_t *)dirp->buffer, dirp->buffer_size, __wasi_fd_readdir(dirp->fd, (uint8_t *)dirp->buffer, dirp->buffer_size,
#endif
dirp->cookie, &dirp->buffer_used); dirp->cookie, &dirp->buffer_used);
if (error != 0) { if (error != 0) {
errno = error; errno = error;

View File

@ -4,6 +4,7 @@
#include <wasi/api.h> #include <wasi/api.h>
#include <wasi/libc.h> #include <wasi/libc.h>
#include <wasi/libc-nocwd.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@ -17,19 +18,15 @@ static int sel_true(const struct dirent *de) {
return 1; return 1;
} }
int scandirat(int dirfd, const char *dir, struct dirent ***namelist, int __wasilibc_nocwd_scandirat(int dirfd, const char *dir, struct dirent ***namelist,
int (*sel)(const struct dirent *), int (*sel)(const struct dirent *),
int (*compar)(const struct dirent **, const struct dirent **)) { int (*compar)(const struct dirent **, const struct dirent **)) {
// Match all files if no select function is provided. // Match all files if no select function is provided.
if (sel == NULL) if (sel == NULL)
sel = sel_true; sel = sel_true;
// Open the directory. // Open the directory.
#ifdef __wasilibc_unmodified_upstream // avoid making a varargs call int fd = __wasilibc_nocwd_openat_nomode(dirfd, dir, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
int fd = openat(dirfd, dir, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
#else
int fd = __wasilibc_openat_nomode(dirfd, dir, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
#endif
if (fd == -1) if (fd == -1)
return -1; return -1;
@ -119,12 +116,8 @@ int scandirat(int dirfd, const char *dir, struct dirent ***namelist,
read_entries:; read_entries:;
// Load more directory entries and continue. // Load more directory entries and continue.
#ifdef __wasilibc_unmodified_upstream
__wasi_errno_t error = __wasi_file_readdir(fd, buffer, buffer_size,
#else
// TODO: Remove the cast on `buffer` once the witx is updated with char8 support. // TODO: Remove the cast on `buffer` once the witx is updated with char8 support.
__wasi_errno_t error = __wasi_fd_readdir(fd, (uint8_t *)buffer, buffer_size, __wasi_errno_t error = __wasi_fd_readdir(fd, (uint8_t *)buffer, buffer_size,
#endif
cookie, &buffer_used); cookie, &buffer_used);
if (error != 0) { if (error != 0) {
errno = error; errno = error;

View File

@ -18,11 +18,7 @@ int fcntl(int fildes, int cmd, ...) {
case F_GETFL: { case F_GETFL: {
// Obtain the flags and the rights of the descriptor. // Obtain the flags and the rights of the descriptor.
__wasi_fdstat_t fds; __wasi_fdstat_t fds;
#ifdef __wasilibc_unmodified_upstream
__wasi_errno_t error = __wasi_fd_stat_get(fildes, &fds);
#else
__wasi_errno_t error = __wasi_fd_fdstat_get(fildes, &fds); __wasi_errno_t error = __wasi_fd_fdstat_get(fildes, &fds);
#endif
if (error != 0) { if (error != 0) {
errno = error; errno = error;
return -1; return -1;
@ -31,26 +27,13 @@ int fcntl(int fildes, int cmd, ...) {
// Roughly approximate the access mode by converting the rights. // Roughly approximate the access mode by converting the rights.
int oflags = fds.fs_flags; int oflags = fds.fs_flags;
if ((fds.fs_rights_base & if ((fds.fs_rights_base &
#ifdef __wasilibc_unmodified_upstream
(__WASI_RIGHT_FD_READ | __WASI_RIGHT_FILE_READDIR)) != 0) {
if ((fds.fs_rights_base & __WASI_RIGHT_FD_WRITE) != 0)
#else
(__WASI_RIGHTS_FD_READ | __WASI_RIGHTS_FD_READDIR)) != 0) { (__WASI_RIGHTS_FD_READ | __WASI_RIGHTS_FD_READDIR)) != 0) {
if ((fds.fs_rights_base & __WASI_RIGHTS_FD_WRITE) != 0) if ((fds.fs_rights_base & __WASI_RIGHTS_FD_WRITE) != 0)
#endif
oflags |= O_RDWR; oflags |= O_RDWR;
else else
oflags |= O_RDONLY; oflags |= O_RDONLY;
#ifdef __wasilibc_unmodified_upstream
} else if ((fds.fs_rights_base & __WASI_RIGHT_FD_WRITE) != 0) {
#else
} else if ((fds.fs_rights_base & __WASI_RIGHTS_FD_WRITE) != 0) { } else if ((fds.fs_rights_base & __WASI_RIGHTS_FD_WRITE) != 0) {
#endif
oflags |= O_WRONLY; oflags |= O_WRONLY;
#ifdef __wasilibc_unmodified_upstream
} else if ((fds.fs_rights_base & __WASI_RIGHT_PROC_EXEC) != 0) {
oflags |= O_EXEC;
#endif
} else { } else {
oflags |= O_SEARCH; oflags |= O_SEARCH;
} }
@ -63,15 +46,9 @@ int fcntl(int fildes, int cmd, ...) {
int flags = va_arg(ap, int); int flags = va_arg(ap, int);
va_end(ap); va_end(ap);
#ifdef __wasilibc_unmodified_upstream // fstat
__wasi_fdstat_t fds = {.fs_flags = flags & 0xfff};
__wasi_errno_t error =
__wasi_fd_stat_put(fildes, &fds, __WASI_FDSTAT_FLAGS);
#else
__wasi_fdflags_t fs_flags = flags & 0xfff; __wasi_fdflags_t fs_flags = flags & 0xfff;
__wasi_errno_t error = __wasi_errno_t error =
__wasi_fd_fdstat_set_flags(fildes, fs_flags); __wasi_fd_fdstat_set_flags(fildes, fs_flags);
#endif
if (error != 0) { if (error != 0) {
errno = error; errno = error;
return -1; return -1;

View File

@ -11,98 +11,39 @@
#include <fcntl.h> #include <fcntl.h>
#include <string.h> #include <string.h>
#ifdef __wasilibc_unmodified_upstream // fstat
static_assert(O_APPEND == __WASI_FDFLAG_APPEND, "Value mismatch");
static_assert(O_DSYNC == __WASI_FDFLAG_DSYNC, "Value mismatch");
static_assert(O_NONBLOCK == __WASI_FDFLAG_NONBLOCK, "Value mismatch");
static_assert(O_RSYNC == __WASI_FDFLAG_RSYNC, "Value mismatch");
static_assert(O_SYNC == __WASI_FDFLAG_SYNC, "Value mismatch");
#else
static_assert(O_APPEND == __WASI_FDFLAGS_APPEND, "Value mismatch"); static_assert(O_APPEND == __WASI_FDFLAGS_APPEND, "Value mismatch");
static_assert(O_DSYNC == __WASI_FDFLAGS_DSYNC, "Value mismatch"); static_assert(O_DSYNC == __WASI_FDFLAGS_DSYNC, "Value mismatch");
static_assert(O_NONBLOCK == __WASI_FDFLAGS_NONBLOCK, "Value mismatch"); static_assert(O_NONBLOCK == __WASI_FDFLAGS_NONBLOCK, "Value mismatch");
static_assert(O_RSYNC == __WASI_FDFLAGS_RSYNC, "Value mismatch"); static_assert(O_RSYNC == __WASI_FDFLAGS_RSYNC, "Value mismatch");
static_assert(O_SYNC == __WASI_FDFLAGS_SYNC, "Value mismatch"); static_assert(O_SYNC == __WASI_FDFLAGS_SYNC, "Value mismatch");
#endif
#ifdef __wasilibc_unmodified_upstream // fstat
static_assert(O_CREAT >> 12 == __WASI_O_CREAT, "Value mismatch");
static_assert(O_DIRECTORY >> 12 == __WASI_O_DIRECTORY, "Value mismatch");
static_assert(O_EXCL >> 12 == __WASI_O_EXCL, "Value mismatch");
static_assert(O_TRUNC >> 12 == __WASI_O_TRUNC, "Value mismatch");
#else
static_assert(O_CREAT >> 12 == __WASI_OFLAGS_CREAT, "Value mismatch"); static_assert(O_CREAT >> 12 == __WASI_OFLAGS_CREAT, "Value mismatch");
static_assert(O_DIRECTORY >> 12 == __WASI_OFLAGS_DIRECTORY, "Value mismatch"); static_assert(O_DIRECTORY >> 12 == __WASI_OFLAGS_DIRECTORY, "Value mismatch");
static_assert(O_EXCL >> 12 == __WASI_OFLAGS_EXCL, "Value mismatch"); static_assert(O_EXCL >> 12 == __WASI_OFLAGS_EXCL, "Value mismatch");
static_assert(O_TRUNC >> 12 == __WASI_OFLAGS_TRUNC, "Value mismatch"); static_assert(O_TRUNC >> 12 == __WASI_OFLAGS_TRUNC, "Value mismatch");
#endif
int openat(int fd, const char *path, int oflag, ...) { int __wasilibc_nocwd_openat_nomode(int fd, const char *path, int oflag) {
#ifdef __wasilibc_unmodified_upstream // fstat
#else
return __wasilibc_openat_nomode(fd, path, oflag);
}
int __wasilibc_openat_nomode(int fd, const char *path, int oflag) {
#endif
// Compute rights corresponding with the access modes provided. // Compute rights corresponding with the access modes provided.
// Attempt to obtain all rights, except the ones that contradict the // Attempt to obtain all rights, except the ones that contradict the
// access mode provided to openat(). // access mode provided to openat().
#ifdef __wasilibc_unmodified_upstream // Let the WASI implementation check this instead.
__wasi_rights_t min = 0;
#endif
__wasi_rights_t max = __wasi_rights_t max =
#ifdef __wasilibc_unmodified_upstream // fstat
~(__WASI_RIGHT_FD_DATASYNC | __WASI_RIGHT_FD_READ |
__WASI_RIGHT_FD_WRITE | __WASI_RIGHT_FILE_ALLOCATE |
__WASI_RIGHT_FILE_READDIR | __WASI_RIGHT_FILE_STAT_FPUT_SIZE |
#else
~(__WASI_RIGHTS_FD_DATASYNC | __WASI_RIGHTS_FD_READ | ~(__WASI_RIGHTS_FD_DATASYNC | __WASI_RIGHTS_FD_READ |
__WASI_RIGHTS_FD_WRITE | __WASI_RIGHTS_FD_ALLOCATE | __WASI_RIGHTS_FD_WRITE | __WASI_RIGHTS_FD_ALLOCATE |
__WASI_RIGHTS_FD_READDIR | __WASI_RIGHTS_FD_FILESTAT_SET_SIZE | __WASI_RIGHTS_FD_READDIR | __WASI_RIGHTS_FD_FILESTAT_SET_SIZE);
#endif
#ifdef __wasilibc_unmodified_upstream // RIGHT_MEM_MAP_EXEC
__WASI_RIGHT_MEM_MAP_EXEC);
#else
0);
#endif
switch (oflag & O_ACCMODE) { switch (oflag & O_ACCMODE) {
case O_RDONLY: case O_RDONLY:
case O_RDWR: case O_RDWR:
case O_WRONLY: case O_WRONLY:
if ((oflag & O_RDONLY) != 0) { if ((oflag & O_RDONLY) != 0) {
#ifdef __wasilibc_unmodified_upstream // Let the WASI implementation check this instead.
min |= (oflag & O_DIRECTORY) == 0 ? __WASI_RIGHT_FD_READ
: __WASI_RIGHT_FILE_READDIR;
#endif
#ifdef __wasilibc_unmodified_upstream // RIGHT_MEM_MAP_EXEC
max |= __WASI_RIGHT_FD_READ | __WASI_RIGHT_FILE_READDIR |
__WASI_RIGHT_MEM_MAP_EXEC;
#else
max |= __WASI_RIGHTS_FD_READ | __WASI_RIGHTS_FD_READDIR; max |= __WASI_RIGHTS_FD_READ | __WASI_RIGHTS_FD_READDIR;
#endif
} }
if ((oflag & O_WRONLY) != 0) { if ((oflag & O_WRONLY) != 0) {
#ifdef __wasilibc_unmodified_upstream // Let the WASI implementation check this instead.
min |= __WASI_RIGHT_FD_WRITE;
if ((oflag & O_APPEND) == 0)
min |= __WASI_RIGHT_FD_SEEK;
#endif
#ifdef __wasilibc_unmodified_upstream // fstat
max |= __WASI_RIGHT_FD_DATASYNC | __WASI_RIGHT_FD_WRITE |
__WASI_RIGHT_FILE_ALLOCATE |
__WASI_RIGHT_FILE_STAT_FPUT_SIZE;
#else
max |= __WASI_RIGHTS_FD_DATASYNC | __WASI_RIGHTS_FD_WRITE | max |= __WASI_RIGHTS_FD_DATASYNC | __WASI_RIGHTS_FD_WRITE |
__WASI_RIGHTS_FD_ALLOCATE | __WASI_RIGHTS_FD_ALLOCATE |
__WASI_RIGHTS_FD_FILESTAT_SET_SIZE; __WASI_RIGHTS_FD_FILESTAT_SET_SIZE;
#endif
} }
break; break;
case O_EXEC: case O_EXEC:
#ifdef __wasilibc_unmodified_upstream // RIGHT_PROC_EXEC
min |= __WASI_RIGHT_PROC_EXEC;
#endif
break; break;
case O_SEARCH: case O_SEARCH:
break; break;
@ -110,72 +51,31 @@ int __wasilibc_openat_nomode(int fd, const char *path, int oflag) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
#ifdef __wasilibc_unmodified_upstream // Let the WASI implementation check this instead.
assert((min & max) == min &&
"Minimal rights should be a subset of the maximum");
#endif
// Ensure that we can actually obtain the minimal rights needed. // Ensure that we can actually obtain the minimal rights needed.
__wasi_fdstat_t fsb_cur; __wasi_fdstat_t fsb_cur;
#ifdef __wasilibc_unmodified_upstream
__wasi_errno_t error = __wasi_fd_stat_get(fd, &fsb_cur);
#else
__wasi_errno_t error = __wasi_fd_fdstat_get(fd, &fsb_cur); __wasi_errno_t error = __wasi_fd_fdstat_get(fd, &fsb_cur);
#endif
if (error != 0) { if (error != 0) {
errno = error; errno = error;
return -1; return -1;
} }
#ifdef __wasilibc_unmodified_upstream // Let the WASI implementation check this instead.
if (fsb_cur.fs_filetype != __WASI_FILETYPE_DIRECTORY) {
errno = ENOTDIR;
return -1;
}
if ((min & fsb_cur.fs_rights_inheriting) != min) {
errno = ENOTCAPABLE;
return -1;
}
#endif
// Path lookup properties. // Path lookup properties.
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
__wasi_lookup_t lookup = {.fd = fd, .flags = 0};
#else
__wasi_lookupflags_t lookup_flags = 0; __wasi_lookupflags_t lookup_flags = 0;
#endif
if ((oflag & O_NOFOLLOW) == 0) if ((oflag & O_NOFOLLOW) == 0)
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
lookup.flags |= __WASI_LOOKUP_SYMLINK_FOLLOW;
#else
lookup_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW; lookup_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW;
#endif
// Open file with appropriate rights. // Open file with appropriate rights.
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t and __wasi_fdstat_t
__wasi_fdstat_t fsb_new = {
.fs_flags = oflag & 0xfff,
.fs_rights_base = max & fsb_cur.fs_rights_inheriting,
.fs_rights_inheriting = fsb_cur.fs_rights_inheriting,
};
__wasi_fd_t newfd;
error = __wasi_file_open(lookup, path, strlen(path),
(oflag >> 12) & 0xfff, &fsb_new, &newfd);
#else
__wasi_fdflags_t fs_flags = oflag & 0xfff; __wasi_fdflags_t fs_flags = oflag & 0xfff;
__wasi_rights_t fs_rights_base = max & fsb_cur.fs_rights_inheriting; __wasi_rights_t fs_rights_base = max & fsb_cur.fs_rights_inheriting;
__wasi_rights_t fs_rights_inheriting = fsb_cur.fs_rights_inheriting; __wasi_rights_t fs_rights_inheriting = fsb_cur.fs_rights_inheriting;
__wasi_fd_t newfd; __wasi_fd_t newfd;
error = __wasi_path_open(fd, lookup_flags, path, strlen(path), error = __wasi_path_open(fd, lookup_flags, path,
(oflag >> 12) & 0xfff, (oflag >> 12) & 0xfff,
fs_rights_base, fs_rights_inheriting, fs_flags, fs_rights_base, fs_rights_inheriting, fs_flags,
&newfd); &newfd);
#endif
if (error != 0) { if (error != 0) {
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
errno = errno_fixup_directory(lookup.fd, error);
#else
errno = errno_fixup_directory(fd, error); errno = errno_fixup_directory(fd, error);
#endif
return -1; return -1;
} }
return newfd; return newfd;

View File

@ -20,9 +20,5 @@ static_assert(POSIX_FADV_WILLNEED == __WASI_ADVICE_WILLNEED,
int posix_fadvise(int fd, off_t offset, off_t len, int advice) { int posix_fadvise(int fd, off_t offset, off_t len, int advice) {
if (offset < 0 || len < 0) if (offset < 0 || len < 0)
return EINVAL; return EINVAL;
#ifdef __wasilibc_unmodified_upstream
return __wasi_file_advise(fd, offset, len, advice);
#else
return __wasi_fd_advise(fd, offset, len, advice); return __wasi_fd_advise(fd, offset, len, advice);
#endif
} }

View File

@ -9,9 +9,5 @@
int posix_fallocate(int fd, off_t offset, off_t len) { int posix_fallocate(int fd, off_t offset, off_t len) {
if (offset < 0 || len < 0) if (offset < 0 || len < 0)
return EINVAL; return EINVAL;
#ifdef __wasilibc_unmodified_upstream
return __wasi_file_allocate(fd, offset, len);
#else
return __wasi_fd_allocate(fd, offset, len); return __wasi_fd_allocate(fd, offset, len);
#endif
} }

View File

@ -7,11 +7,7 @@
#include <sched.h> #include <sched.h>
int sched_yield(void) { int sched_yield(void) {
#ifdef __wasilibc_unmodified_upstream
__wasi_errno_t error = __wasi_thread_yield();
#else
__wasi_errno_t error = __wasi_sched_yield(); __wasi_errno_t error = __wasi_sched_yield();
#endif
if (error != 0) { if (error != 0) {
errno = error; errno = error;
return -1; return -1;

View File

@ -9,13 +9,8 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
int renameat(int oldfd, const char *old, int newfd, const char *new) { int __wasilibc_nocwd_renameat(int oldfd, const char *old, int newfd, const char *new) {
#ifdef __wasilibc_unmodified_upstream __wasi_errno_t error = __wasi_path_rename(oldfd, old, newfd, new);
__wasi_errno_t error = __wasi_file_rename(oldfd, old, strlen(old),
#else
__wasi_errno_t error = __wasi_path_rename(oldfd, old, strlen(old),
#endif
newfd, new, strlen(new));
if (error != 0) { if (error != 0) {
errno = errno_fixup_directory(oldfd, errno_fixup_directory(newfd, error)); errno = errno_fixup_directory(oldfd, errno_fixup_directory(newfd, error));
return -1; return -1;

View File

@ -24,11 +24,7 @@ int ioctl(int fildes, int request, ...) {
}; };
__wasi_event_t events[__arraycount(subscriptions)]; __wasi_event_t events[__arraycount(subscriptions)];
size_t nevents; size_t nevents;
#ifdef __wasilibc_unmodified_upstream
__wasi_errno_t error = __wasi_poll(
#else
__wasi_errno_t error = __wasi_poll_oneoff( __wasi_errno_t error = __wasi_poll_oneoff(
#endif
subscriptions, events, __arraycount(subscriptions), &nevents); subscriptions, events, __arraycount(subscriptions), &nevents);
if (error != 0) { if (error != 0) {
errno = error; errno = error;
@ -61,11 +57,7 @@ int ioctl(int fildes, int request, ...) {
case FIONBIO: { case FIONBIO: {
// Obtain the current file descriptor flags. // Obtain the current file descriptor flags.
__wasi_fdstat_t fds; __wasi_fdstat_t fds;
#ifdef __wasilibc_unmodified_upstream
__wasi_errno_t error = __wasi_fd_stat_get(fildes, &fds);
#else
__wasi_errno_t error = __wasi_fd_fdstat_get(fildes, &fds); __wasi_errno_t error = __wasi_fd_fdstat_get(fildes, &fds);
#endif
if (error != 0) { if (error != 0) {
errno = error; errno = error;
return -1; return -1;
@ -75,25 +67,13 @@ int ioctl(int fildes, int request, ...) {
va_list ap; va_list ap;
va_start(ap, request); va_start(ap, request);
if (*va_arg(ap, const int *) != 0) if (*va_arg(ap, const int *) != 0)
#ifdef __wasilibc_unmodified_upstream // generated constant names
fds.fs_flags |= __WASI_FDFLAG_NONBLOCK;
#else
fds.fs_flags |= __WASI_FDFLAGS_NONBLOCK; fds.fs_flags |= __WASI_FDFLAGS_NONBLOCK;
#endif
else else
#ifdef __wasilibc_unmodified_upstream // generated constant names
fds.fs_flags &= ~__WASI_FDFLAG_NONBLOCK;
#else
fds.fs_flags &= ~__WASI_FDFLAGS_NONBLOCK; fds.fs_flags &= ~__WASI_FDFLAGS_NONBLOCK;
#endif
va_end(ap); va_end(ap);
// Update the file descriptor flags. // Update the file descriptor flags.
#ifdef __wasilibc_unmodified_upstream // fstat
error = __wasi_fd_stat_put(fildes, &fds, __WASI_FDSTAT_FLAGS);
#else
error = __wasi_fd_fdstat_set_flags(fildes, fds.fs_flags); error = __wasi_fd_fdstat_set_flags(fildes, fds.fs_flags);
#endif
if (error != 0) { if (error != 0) {
errno = error; errno = error;
return -1; return -1;

View File

@ -1,34 +0,0 @@
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
//
// SPDX-License-Identifier: BSD-2-Clause
#include <common/time.h>
#include <sys/resource.h>
#include <wasi/api.h>
#include <errno.h>
int getrusage(int who, struct rusage *r_usage) {
switch (who) {
case RUSAGE_SELF: {
__wasi_timestamp_t usertime = 0;
#ifdef __wasilibc_unmodified_upstream // generated constant names
(void)__wasi_clock_time_get(__WASI_CLOCK_PROCESS_CPUTIME_ID, 1000,
#else
(void)__wasi_clock_time_get(__WASI_CLOCKID_PROCESS_CPUTIME_ID, 1000,
#endif
&usertime);
*r_usage = (struct rusage){
.ru_utime = timestamp_to_timeval(usertime),
};
return 0;
}
case RUSAGE_CHILDREN:
*r_usage = (struct rusage){};
return 0;
default:
errno = EINVAL;
return -1;
}
}

View File

@ -17,17 +17,9 @@ int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds,
} }
struct timespec ts = {.tv_sec = timeout->tv_sec, struct timespec ts = {.tv_sec = timeout->tv_sec,
.tv_nsec = (long)timeout->tv_usec * 1000}; .tv_nsec = (long)timeout->tv_usec * 1000};
#ifdef __wasilibc_unmodified_upstream
return pselect(nfds, readfds, writefds, errorfds, &ts);
#else
return pselect(nfds, readfds, writefds, errorfds, &ts, NULL); return pselect(nfds, readfds, writefds, errorfds, &ts, NULL);
#endif
} else { } else {
// No timeout specified. // No timeout specified.
#ifdef __wasilibc_unmodified_upstream
return pselect(nfds, readfds, writefds, errorfds, NULL);
#else
return pselect(nfds, readfds, writefds, errorfds, NULL, NULL); return pselect(nfds, readfds, writefds, errorfds, NULL, NULL);
#endif
} }
} }

View File

@ -9,11 +9,7 @@
#include <string.h> #include <string.h>
int getsockopt(int socket, int level, int option_name, int getsockopt(int socket, int level, int option_name,
#ifdef __wasilibc_unmodified_upstream
void *restrict option_value, size_t *restrict option_len) {
#else
void *restrict option_value, socklen_t *restrict option_len) { void *restrict option_value, socklen_t *restrict option_len) {
#endif
// Only support SOL_SOCKET options for now. // Only support SOL_SOCKET options for now.
if (level != SOL_SOCKET) { if (level != SOL_SOCKET) {
errno = ENOPROTOOPT; errno = ENOPROTOOPT;
@ -26,11 +22,7 @@ int getsockopt(int socket, int level, int option_name,
// Return the type of the socket. This information can simply be // Return the type of the socket. This information can simply be
// obtained by looking at the file descriptor type. // obtained by looking at the file descriptor type.
__wasi_fdstat_t fsb; __wasi_fdstat_t fsb;
#ifdef __wasilibc_unmodified_upstream
if (__wasi_fd_stat_get(socket, &fsb) != 0) {
#else
if (__wasi_fd_fdstat_get(socket, &fsb) != 0) { if (__wasi_fd_fdstat_get(socket, &fsb) != 0) {
#endif
errno = EBADF; errno = EBADF;
return -1; return -1;
} }

View File

@ -11,13 +11,8 @@
#include <errno.h> #include <errno.h>
#include <stdint.h> #include <stdint.h>
#ifdef __wasilibc_unmodified_upstream
static_assert(MSG_PEEK == __WASI_SOCK_RECV_PEEK, "Value mismatch");
static_assert(MSG_WAITALL == __WASI_SOCK_RECV_WAITALL, "Value mismatch");
#else
static_assert(MSG_PEEK == __WASI_RIFLAGS_RECV_PEEK, "Value mismatch"); static_assert(MSG_PEEK == __WASI_RIFLAGS_RECV_PEEK, "Value mismatch");
static_assert(MSG_WAITALL == __WASI_RIFLAGS_RECV_WAITALL, "Value mismatch"); static_assert(MSG_WAITALL == __WASI_RIFLAGS_RECV_WAITALL, "Value mismatch");
#endif
ssize_t recv(int socket, void *restrict buffer, size_t length, int flags) { ssize_t recv(int socket, void *restrict buffer, size_t length, int flags) {
// Validate flags. // Validate flags.
@ -28,37 +23,20 @@ ssize_t recv(int socket, void *restrict buffer, size_t length, int flags) {
// Prepare input parameters. // Prepare input parameters.
__wasi_iovec_t iov = {.buf = buffer, .buf_len = length}; __wasi_iovec_t iov = {.buf = buffer, .buf_len = length};
#ifdef __wasilibc_unmodified_upstream // send/recv
__wasi_recv_in_t ri = {
.ri_data = &iov,
.ri_data_len = 1,
.ri_flags = flags,
};
#else
__wasi_iovec_t *ri_data = &iov; __wasi_iovec_t *ri_data = &iov;
size_t ri_data_len = 1; size_t ri_data_len = 1;
__wasi_riflags_t ri_flags = flags; __wasi_riflags_t ri_flags = flags;
#endif
// Perform system call. // Perform system call.
#ifdef __wasilibc_unmodified_upstream // send/recv
__wasi_recv_out_t ro;
__wasi_errno_t error = __wasi_sock_recv(socket, &ri, &ro);
#else
size_t ro_datalen; size_t ro_datalen;
__wasi_roflags_t ro_flags; __wasi_roflags_t ro_flags;
__wasi_errno_t error = __wasi_sock_recv(socket, __wasi_errno_t error = __wasi_sock_recv(socket,
ri_data, ri_data_len, ri_flags, ri_data, ri_data_len, ri_flags,
&ro_datalen, &ro_datalen,
&ro_flags); &ro_flags);
#endif
if (error != 0) { if (error != 0) {
errno = errno_fixup_socket(socket, error); errno = errno_fixup_socket(socket, error);
return -1; return -1;
} }
#ifdef __wasilibc_unmodified_upstream // send/recv
return ro.ro_datalen;
#else
return ro_datalen; return ro_datalen;
#endif
} }

View File

@ -19,32 +19,16 @@ ssize_t send(int socket, const void *buffer, size_t length, int flags) {
// Prepare input parameters. // Prepare input parameters.
__wasi_ciovec_t iov = {.buf = buffer, .buf_len = length}; __wasi_ciovec_t iov = {.buf = buffer, .buf_len = length};
#ifdef __wasilibc_unmodified_upstream // send/recv
__wasi_send_in_t si = {
.si_data = &iov,
.si_data_len = 1,
};
#else
__wasi_ciovec_t *si_data = &iov; __wasi_ciovec_t *si_data = &iov;
size_t si_data_len = 1; size_t si_data_len = 1;
__wasi_siflags_t si_flags = 0; __wasi_siflags_t si_flags = 0;
#endif
// Perform system call. // Perform system call.
#ifdef __wasilibc_unmodified_upstream // send/recv
__wasi_send_out_t so;
__wasi_errno_t error = __wasi_sock_send(socket, &si, &so);
#else
size_t so_datalen; size_t so_datalen;
__wasi_errno_t error = __wasi_sock_send(socket, si_data, si_data_len, si_flags, &so_datalen); __wasi_errno_t error = __wasi_sock_send(socket, si_data, si_data_len, si_flags, &so_datalen);
#endif
if (error != 0) { if (error != 0) {
errno = errno_fixup_socket(socket, error); errno = errno_fixup_socket(socket, error);
return -1; return -1;
} }
#ifdef __wasilibc_unmodified_upstream // send/recv
return so.so_datalen;
#else
return so_datalen; return so_datalen;
#endif
} }

View File

@ -10,13 +10,8 @@
#include <wasi/api.h> #include <wasi/api.h>
#include <errno.h> #include <errno.h>
#ifdef __wasilibc_unmodified_upstream // generated constant names
static_assert(SHUT_RD == __WASI_SHUT_RD, "Value mismatch");
static_assert(SHUT_WR == __WASI_SHUT_WR, "Value mismatch");
#else
static_assert(SHUT_RD == __WASI_SDFLAGS_RD, "Value mismatch"); static_assert(SHUT_RD == __WASI_SDFLAGS_RD, "Value mismatch");
static_assert(SHUT_WR == __WASI_SDFLAGS_WR, "Value mismatch"); static_assert(SHUT_WR == __WASI_SDFLAGS_WR, "Value mismatch");
#endif
int shutdown(int socket, int how) { int shutdown(int socket, int how) {
// Validate shutdown flags. // Validate shutdown flags.

View File

@ -11,11 +11,7 @@
int fstat(int fildes, struct stat *buf) { int fstat(int fildes, struct stat *buf) {
__wasi_filestat_t internal_stat; __wasi_filestat_t internal_stat;
#ifdef __wasilibc_unmodified_upstream // fstat
__wasi_errno_t error = __wasi_file_stat_fget(fildes, &internal_stat);
#else
__wasi_errno_t error = __wasi_fd_filestat_get(fildes, &internal_stat); __wasi_errno_t error = __wasi_fd_filestat_get(fildes, &internal_stat);
#endif
if (error != 0) { if (error != 0) {
errno = error; errno = error;
return -1; return -1;

View File

@ -13,29 +13,17 @@
#include "stat_impl.h" #include "stat_impl.h"
int fstatat(int fd, const char *restrict path, struct stat *restrict buf, int __wasilibc_nocwd_fstatat(int fd, const char *restrict path, struct stat *restrict buf,
int flag) { int flag) {
// Create lookup properties. // Create lookup properties.
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
__wasi_lookup_t lookup = {.fd = fd, .flags = 0};
#else
__wasi_lookupflags_t lookup_flags = 0; __wasi_lookupflags_t lookup_flags = 0;
#endif
if ((flag & AT_SYMLINK_NOFOLLOW) == 0) if ((flag & AT_SYMLINK_NOFOLLOW) == 0)
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
lookup.flags |= __WASI_LOOKUP_SYMLINK_FOLLOW;
#else
lookup_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW; lookup_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW;
#endif
// Perform system call. // Perform system call.
__wasi_filestat_t internal_stat; __wasi_filestat_t internal_stat;
__wasi_errno_t error = __wasi_errno_t error =
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t __wasi_path_filestat_get(fd, lookup_flags, path, &internal_stat);
__wasi_file_stat_get(lookup, path, strlen(path), &internal_stat);
#else
__wasi_path_filestat_get(fd, lookup_flags, path, strlen(path), &internal_stat);
#endif
if (error != 0) { if (error != 0) {
errno = errno_fixup_directory(fd, error); errno = errno_fixup_directory(fd, error);
return -1; return -1;

View File

@ -11,26 +11,16 @@
int futimens(int fd, const struct timespec *times) { int futimens(int fd, const struct timespec *times) {
// Convert timestamps and extract NOW/OMIT flags. // Convert timestamps and extract NOW/OMIT flags.
#ifdef __wasilibc_unmodified_upstream // fstat
__wasi_filestat_t fs;
__wasi_fsflags_t flags;
if (!utimens_get_timestamps(times, &fs, &flags)) {
#else
__wasi_timestamp_t st_atim; __wasi_timestamp_t st_atim;
__wasi_timestamp_t st_mtim; __wasi_timestamp_t st_mtim;
__wasi_fstflags_t flags; __wasi_fstflags_t flags;
if (!utimens_get_timestamps(times, &st_atim, &st_mtim, &flags)) { if (!utimens_get_timestamps(times, &st_atim, &st_mtim, &flags)) {
#endif
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
// Perform system call. // Perform system call.
#ifdef __wasilibc_unmodified_upstream // fstat
__wasi_errno_t error = __wasi_file_stat_fput(fd, &fs, flags);
#else
__wasi_errno_t error = __wasi_fd_filestat_set_times(fd, st_atim, st_mtim, flags); __wasi_errno_t error = __wasi_fd_filestat_set_times(fd, st_atim, st_mtim, flags);
#endif
if (error != 0) { if (error != 0) {
errno = error; errno = error;
return -1; return -1;

View File

@ -10,18 +10,8 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#ifdef __wasilibc_unmodified_upstream int __wasilibc_nocwd_mkdirat_nomode(int fd, const char *path) {
int mkdirat(int fd, const char *path, ...) { __wasi_errno_t error = __wasi_path_create_directory(fd, path);
#else
int mkdirat(int fd, const char *path, mode_t mode) {
#endif
#ifdef __wasilibc_unmodified_upstream // __wasi_path_create_directory
__wasi_errno_t error = __wasi_file_create(
fd, path, strlen(path), __WASI_FILETYPE_DIRECTORY);
#else
__wasi_errno_t error = __wasi_path_create_directory(
fd, path, strlen(path));
#endif
if (error != 0) { if (error != 0) {
errno = errno_fixup_directory(fd, error); errno = errno_fixup_directory(fd, error);
return -1; return -1;

View File

@ -24,43 +24,17 @@ static_assert(S_ISSOCK(S_IFSOCK), "Value mismatch");
static inline void to_public_stat(const __wasi_filestat_t *in, static inline void to_public_stat(const __wasi_filestat_t *in,
struct stat *out) { struct stat *out) {
// Ensure that we don't truncate any values. // Ensure that we don't truncate any values.
#ifdef __wasilibc_unmodified_upstream
static_assert(sizeof(in->st_dev) == sizeof(out->st_dev), "Size mismatch");
static_assert(sizeof(in->st_ino) == sizeof(out->st_ino), "Size mismatch");
static_assert(sizeof(in->st_filetype) == sizeof(out->__st_filetype),
"Size mismatch");
#else
static_assert(sizeof(in->dev) == sizeof(out->st_dev), "Size mismatch"); static_assert(sizeof(in->dev) == sizeof(out->st_dev), "Size mismatch");
static_assert(sizeof(in->ino) == sizeof(out->st_ino), "Size mismatch"); static_assert(sizeof(in->ino) == sizeof(out->st_ino), "Size mismatch");
/* /*
* The non-standard __st_filetype field appears to only be used for shared * The non-standard __st_filetype field appears to only be used for shared
* memory, which we don't currently support. * memory, which we don't currently support.
*/ */
#endif
#ifdef __wasilibc_unmodified_upstream
static_assert(sizeof(in->st_nlink) == sizeof(out->st_nlink), "Size mismatch");
static_assert(sizeof(in->st_size) == sizeof(out->st_size), "Size mismatch");
#else
/* nlink_t is 64-bit on wasm32, following the x32 ABI. */ /* nlink_t is 64-bit on wasm32, following the x32 ABI. */
static_assert(sizeof(in->nlink) <= sizeof(out->st_nlink), "Size shortfall"); static_assert(sizeof(in->nlink) <= sizeof(out->st_nlink), "Size shortfall");
static_assert(sizeof(in->size) == sizeof(out->st_size), "Size mismatch"); static_assert(sizeof(in->size) == sizeof(out->st_size), "Size mismatch");
#endif
*out = (struct stat){ *out = (struct stat){
#ifdef __wasilibc_unmodified_upstream
#define COPY_FIELD(field) .field = in->field
COPY_FIELD(st_dev),
COPY_FIELD(st_ino),
.__st_filetype = in->st_filetype,
COPY_FIELD(st_nlink),
COPY_FIELD(st_size),
#undef COPY_FIELD
#define COPY_TIMESPEC(field) .field = timestamp_to_timespec(in->field)
COPY_TIMESPEC(st_atim),
COPY_TIMESPEC(st_mtim),
COPY_TIMESPEC(st_ctim),
#undef COPY_TIMESPEC
#else
.st_dev = in->dev, .st_dev = in->dev,
.st_ino = in->ino, .st_ino = in->ino,
.st_nlink = in->nlink, .st_nlink = in->nlink,
@ -68,15 +42,10 @@ static inline void to_public_stat(const __wasi_filestat_t *in,
.st_atim = timestamp_to_timespec(in->atim), .st_atim = timestamp_to_timespec(in->atim),
.st_mtim = timestamp_to_timespec(in->mtim), .st_mtim = timestamp_to_timespec(in->mtim),
.st_ctim = timestamp_to_timespec(in->ctim), .st_ctim = timestamp_to_timespec(in->ctim),
#endif
}; };
// Convert file type to legacy types encoded in st_mode. // Convert file type to legacy types encoded in st_mode.
#ifdef __wasilibc_unmodified_upstream
switch (in->st_filetype) {
#else
switch (in->filetype) { switch (in->filetype) {
#endif
case __WASI_FILETYPE_BLOCK_DEVICE: case __WASI_FILETYPE_BLOCK_DEVICE:
out->st_mode |= S_IFBLK; out->st_mode |= S_IFBLK;
break; break;
@ -100,64 +69,37 @@ static inline void to_public_stat(const __wasi_filestat_t *in,
} }
static inline bool utimens_get_timestamps(const struct timespec *times, static inline bool utimens_get_timestamps(const struct timespec *times,
#ifdef __wasilibc_unmodified_upstream // fstat
__wasi_filestat_t *fs,
__wasi_fsflags_t *flags) {
#else
__wasi_timestamp_t *st_atim, __wasi_timestamp_t *st_atim,
__wasi_timestamp_t *st_mtim, __wasi_timestamp_t *st_mtim,
__wasi_fstflags_t *flags) { __wasi_fstflags_t *flags) {
#endif
if (times == NULL) { if (times == NULL) {
// Update both timestamps. // Update both timestamps.
#ifdef __wasilibc_unmodified_upstream // fstat
*flags = __WASI_FILESTAT_ATIM_NOW | __WASI_FILESTAT_MTIM_NOW;
#else
*flags = __WASI_FSTFLAGS_ATIM_NOW | __WASI_FSTFLAGS_MTIM_NOW; *flags = __WASI_FSTFLAGS_ATIM_NOW | __WASI_FSTFLAGS_MTIM_NOW;
#endif
} else { } else {
// Set individual timestamps. // Set individual timestamps.
*flags = 0; *flags = 0;
switch (times[0].tv_nsec) { switch (times[0].tv_nsec) {
case UTIME_NOW: case UTIME_NOW:
#ifdef __wasilibc_unmodified_upstream // fstat
*flags |= __WASI_FILESTAT_ATIM_NOW;
#else
*flags |= __WASI_FSTFLAGS_ATIM_NOW; *flags |= __WASI_FSTFLAGS_ATIM_NOW;
#endif
break; break;
case UTIME_OMIT: case UTIME_OMIT:
break; break;
default: default:
#ifdef __wasilibc_unmodified_upstream // fstat
*flags |= __WASI_FILESTAT_ATIM;
if (!timespec_to_timestamp_exact(&times[0], &fs->st_atim))
#else
*flags |= __WASI_FSTFLAGS_ATIM; *flags |= __WASI_FSTFLAGS_ATIM;
if (!timespec_to_timestamp_exact(&times[0], st_atim)) if (!timespec_to_timestamp_exact(&times[0], st_atim))
#endif
return false; return false;
break; break;
} }
switch (times[1].tv_nsec) { switch (times[1].tv_nsec) {
case UTIME_NOW: case UTIME_NOW:
#ifdef __wasilibc_unmodified_upstream // fstat
*flags |= __WASI_FILESTAT_MTIM_NOW;
#else
*flags |= __WASI_FSTFLAGS_MTIM_NOW; *flags |= __WASI_FSTFLAGS_MTIM_NOW;
#endif
break; break;
case UTIME_OMIT: case UTIME_OMIT:
break; break;
default: default:
#ifdef __wasilibc_unmodified_upstream // fstat
*flags |= __WASI_FILESTAT_MTIM;
if (!timespec_to_timestamp_exact(&times[1], &fs->st_mtim))
#else
*flags |= __WASI_FSTFLAGS_MTIM; *flags |= __WASI_FSTFLAGS_MTIM;
if (!timespec_to_timestamp_exact(&times[1], st_mtim)) if (!timespec_to_timestamp_exact(&times[1], st_mtim))
#endif
return false; return false;
break; break;
} }

View File

@ -13,43 +13,25 @@
#include "stat_impl.h" #include "stat_impl.h"
int utimensat(int fd, const char *path, const struct timespec times[2], int __wasilibc_nocwd_utimensat(int fd, const char *path, const struct timespec times[2],
int flag) { int flag) {
// Convert timestamps and extract NOW/OMIT flags. // Convert timestamps and extract NOW/OMIT flags.
#ifdef __wasilibc_unmodified_upstream // fstat
__wasi_filestat_t fs;
__wasi_fsflags_t flags;
if (!utimens_get_timestamps(times, &fs, &flags)) {
#else
__wasi_timestamp_t st_atim; __wasi_timestamp_t st_atim;
__wasi_timestamp_t st_mtim; __wasi_timestamp_t st_mtim;
__wasi_fstflags_t flags; __wasi_fstflags_t flags;
if (!utimens_get_timestamps(times, &st_atim, &st_mtim, &flags)) { if (!utimens_get_timestamps(times, &st_atim, &st_mtim, &flags)) {
#endif
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
// Create lookup properties. // Create lookup properties.
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
__wasi_lookup_t lookup = {.fd = fd, .flags = 0};
#else
__wasi_lookupflags_t lookup_flags = 0; __wasi_lookupflags_t lookup_flags = 0;
#endif
if ((flag & AT_SYMLINK_NOFOLLOW) == 0) if ((flag & AT_SYMLINK_NOFOLLOW) == 0)
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
lookup.flags |= __WASI_LOOKUP_SYMLINK_FOLLOW;
#else
lookup_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW; lookup_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW;
#endif
// Perform system call. // Perform system call.
__wasi_errno_t error = __wasi_errno_t error =
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t, fstat __wasi_path_filestat_set_times(fd, lookup_flags, path, st_atim, st_mtim, flags);
__wasi_file_stat_put(lookup, path, strlen(path), &fs, flags);
#else
__wasi_path_filestat_set_times(fd, lookup_flags, path, strlen(path), st_atim, st_mtim, flags);
#endif
if (error != 0) { if (error != 0) {
errno = errno_fixup_directory(fd, error); errno = errno_fixup_directory(fd, error);
return -1; return -1;

View File

@ -8,17 +8,9 @@
#include <wasi/api.h> #include <wasi/api.h>
#ifdef __wasilibc_unmodified_upstream
int gettimeofday(struct timeval *restrict tp, ...) {
#else
int gettimeofday(struct timeval *restrict tp, void *tz) { int gettimeofday(struct timeval *restrict tp, void *tz) {
#endif
__wasi_timestamp_t ts = 0; __wasi_timestamp_t ts = 0;
#ifdef __wasilibc_unmodified_upstream // generated constant names
(void)__wasi_clock_time_get(__WASI_CLOCK_REALTIME, 1000, &ts);
#else
(void)__wasi_clock_time_get(__WASI_CLOCKID_REALTIME, 1000, &ts); (void)__wasi_clock_time_get(__WASI_CLOCKID_REALTIME, 1000, &ts);
#endif
*tp = timestamp_to_timeval(ts); *tp = timestamp_to_timeval(ts);
return 0; return 0;
} }

View File

@ -1,33 +0,0 @@
// Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/
//
// SPDX-License-Identifier: BSD-2-Clause
#include <common/time.h>
#include <sys/times.h>
#include <assert.h>
#include <wasi/api.h>
static_assert(CLOCKS_PER_SEC == NSEC_PER_SEC,
"Timestamp should need no conversion");
clock_t times(struct tms *buffer) {
// Obtain user time.
__wasi_timestamp_t usertime = 0;
#ifdef __wasilibc_unmodified_upstream // generated constant names
(void)__wasi_clock_time_get(__WASI_CLOCK_PROCESS_CPUTIME_ID, 0, &usertime);
#else
(void)__wasi_clock_time_get(__WASI_CLOCKID_PROCESS_CPUTIME_ID, 0, &usertime);
#endif
*buffer = (struct tms){.tms_utime = usertime};
// Obtain real time.
__wasi_timestamp_t realtime = 0;
#ifdef __wasilibc_unmodified_upstream // generated constant names
(void)__wasi_clock_time_get(__WASI_CLOCK_MONOTONIC, 0, &realtime);
#else
(void)__wasi_clock_time_get(__WASI_CLOCKID_MONOTONIC, 0, &realtime);
#endif
return realtime;
}

View File

@ -8,9 +8,5 @@
#include <time.h> #include <time.h>
const struct __clockid _CLOCK_MONOTONIC = { const struct __clockid _CLOCK_MONOTONIC = {
#ifdef __wasilibc_unmodified_upstream // generated constant names
.id = __WASI_CLOCK_MONOTONIC,
#else
.id = __WASI_CLOCKID_MONOTONIC, .id = __WASI_CLOCKID_MONOTONIC,
#endif
}; };

View File

@ -8,9 +8,5 @@
#include <time.h> #include <time.h>
const struct __clockid _CLOCK_PROCESS_CPUTIME_ID = { const struct __clockid _CLOCK_PROCESS_CPUTIME_ID = {
#ifdef __wasilibc_unmodified_upstream
.id = __WASI_CLOCK_PROCESS_CPUTIME_ID,
#else
.id = __WASI_CLOCKID_PROCESS_CPUTIME_ID, .id = __WASI_CLOCKID_PROCESS_CPUTIME_ID,
#endif
}; };

View File

@ -8,9 +8,5 @@
#include <time.h> #include <time.h>
const struct __clockid _CLOCK_REALTIME = { const struct __clockid _CLOCK_REALTIME = {
#ifdef __wasilibc_unmodified_upstream // generated constant names
.id = __WASI_CLOCK_REALTIME,
#else
.id = __WASI_CLOCKID_REALTIME, .id = __WASI_CLOCKID_REALTIME,
#endif
}; };

View File

@ -8,9 +8,5 @@
#include <time.h> #include <time.h>
const struct __clockid _CLOCK_THREAD_CPUTIME_ID = { const struct __clockid _CLOCK_THREAD_CPUTIME_ID = {
#ifdef __wasilibc_unmodified_upstream // generated constant names
.id = __WASI_CLOCK_THREAD_CPUTIME_ID,
#else
.id = __WASI_CLOCKID_THREAD_CPUTIME_ID, .id = __WASI_CLOCKID_THREAD_CPUTIME_ID,
#endif
}; };

View File

@ -1,22 +0,0 @@
// Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/
//
// SPDX-License-Identifier: BSD-2-Clause
#include <common/time.h>
#include <assert.h>
#include <wasi/api.h>
#include <time.h>
static_assert(CLOCKS_PER_SEC == NSEC_PER_SEC,
"Timestamp should need no conversion");
clock_t clock(void) {
__wasi_timestamp_t ts = 0;
#ifdef __wasilibc_unmodified_upstream // generated constant names
(void)__wasi_clock_time_get(__WASI_CLOCK_PROCESS_CPUTIME_ID, 0, &ts);
#else
(void)__wasi_clock_time_get(__WASI_CLOCKID_PROCESS_CPUTIME_ID, 0, &ts);
#endif
return ts;
}

View File

@ -9,11 +9,7 @@
#include <errno.h> #include <errno.h>
#include <time.h> #include <time.h>
#ifdef __wasilibc_unmodified_upstream
int clock_gettime(clockid_t clock_id, struct timespec *tp) {
#else
int __clock_gettime(clockid_t clock_id, struct timespec *tp) { int __clock_gettime(clockid_t clock_id, struct timespec *tp) {
#endif
__wasi_timestamp_t ts; __wasi_timestamp_t ts;
__wasi_errno_t error = __wasi_clock_time_get(clock_id->id, 1, &ts); __wasi_errno_t error = __wasi_clock_time_get(clock_id->id, 1, &ts);
if (error != 0) { if (error != 0) {
@ -23,7 +19,4 @@ int __clock_gettime(clockid_t clock_id, struct timespec *tp) {
*tp = timestamp_to_timespec(ts); *tp = timestamp_to_timespec(ts);
return 0; return 0;
} }
#ifdef __wasilibc_unmodified_upstream
#else
extern __typeof(__clock_gettime) clock_gettime __attribute__((weak, alias("__clock_gettime"))); extern __typeof(__clock_gettime) clock_gettime __attribute__((weak, alias("__clock_gettime")));
#endif

View File

@ -10,20 +10,11 @@
#include <errno.h> #include <errno.h>
#include <time.h> #include <time.h>
#ifdef __wasilibc_unmodified_upstream // generated constant names
static_assert(TIMER_ABSTIME == __WASI_SUBSCRIPTION_CLOCK_ABSTIME,
#else
static_assert(TIMER_ABSTIME == __WASI_SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME, static_assert(TIMER_ABSTIME == __WASI_SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME,
#endif
"Value mismatch"); "Value mismatch");
#ifdef __wasilibc_unmodified_upstream
int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp,
...) {
#else
int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp,
struct timespec *rmtp) { struct timespec *rmtp) {
#endif
if ((flags & ~TIMER_ABSTIME) != 0) if ((flags & ~TIMER_ABSTIME) != 0)
return EINVAL; return EINVAL;
@ -39,10 +30,6 @@ int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp,
// Block until polling event is triggered. // Block until polling event is triggered.
size_t nevents; size_t nevents;
__wasi_event_t ev; __wasi_event_t ev;
#ifdef __wasilibc_unmodified_upstream
__wasi_errno_t error = __wasi_poll(&sub, &ev, 1, &nevents);
#else
__wasi_errno_t error = __wasi_poll_oneoff(&sub, &ev, 1, &nevents); __wasi_errno_t error = __wasi_poll_oneoff(&sub, &ev, 1, &nevents);
#endif
return error == 0 && ev.error == 0 ? 0 : ENOTSUP; return error == 0 && ev.error == 0 ? 0 : ENOTSUP;
} }

View File

@ -6,16 +6,8 @@
#include <threads.h> #include <threads.h>
#include <time.h> #include <time.h>
#ifdef __wasilibc_unmodified_upstream
int nanosleep(const struct timespec *rqtp, ...) {
#else
int nanosleep(const struct timespec *rqtp, struct timespec *rem) { int nanosleep(const struct timespec *rqtp, struct timespec *rem) {
#endif
#ifdef __wasilibc_unmodified_upstream
int error = clock_nanosleep(CLOCK_REALTIME, 0, rqtp);
#else
int error = clock_nanosleep(CLOCK_REALTIME, 0, rqtp, rem); int error = clock_nanosleep(CLOCK_REALTIME, 0, rqtp, rem);
#endif
if (error != 0) { if (error != 0) {
errno = error; errno = error;
return -1; return -1;
@ -23,7 +15,6 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rem) {
return 0; return 0;
} }
#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) #if defined(_REENTRANT)
__strong_reference(nanosleep, thrd_sleep); __strong_reference(nanosleep, thrd_sleep);
#else
#endif #endif

View File

@ -9,11 +9,7 @@
time_t time(time_t *tloc) { time_t time(time_t *tloc) {
__wasi_timestamp_t ts = 0; __wasi_timestamp_t ts = 0;
#ifdef __wasilibc_unmodified_upstream
(void)__wasi_clock_time_get(__WASI_CLOCK_REALTIME, NSEC_PER_SEC, &ts);
#else
(void)__wasi_clock_time_get(__WASI_CLOCKID_REALTIME, NSEC_PER_SEC, &ts); (void)__wasi_clock_time_get(__WASI_CLOCKID_REALTIME, NSEC_PER_SEC, &ts);
#endif
if (tloc != NULL) if (tloc != NULL)
*tloc = ts / NSEC_PER_SEC; *tloc = ts / NSEC_PER_SEC;
return ts / NSEC_PER_SEC; return ts / NSEC_PER_SEC;

View File

@ -10,7 +10,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
int faccessat(int fd, const char *path, int amode, int flag) { int __wasilibc_nocwd_faccessat(int fd, const char *path, int amode, int flag) {
// Validate function parameters. // Validate function parameters.
if ((amode & ~(F_OK | R_OK | W_OK | X_OK)) != 0 || if ((amode & ~(F_OK | R_OK | W_OK | X_OK)) != 0 ||
(flag & ~AT_EACCESS) != 0) { (flag & ~AT_EACCESS) != 0) {
@ -19,21 +19,10 @@ int faccessat(int fd, const char *path, int amode, int flag) {
} }
// Check for target file existence and obtain the file type. // Check for target file existence and obtain the file type.
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
__wasi_lookup_t lookup = {
.fd = fd,
.flags = __WASI_LOOKUP_SYMLINK_FOLLOW,
};
#else
__wasi_lookupflags_t lookup_flags = __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW; __wasi_lookupflags_t lookup_flags = __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW;
#endif
__wasi_filestat_t file; __wasi_filestat_t file;
__wasi_errno_t error = __wasi_errno_t error =
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t __wasi_path_filestat_get(fd, lookup_flags, path, &file);
__wasi_file_stat_get(lookup, path, strlen(path), &file);
#else
__wasi_path_filestat_get(fd, lookup_flags, path, strlen(path), &file);
#endif
if (error != 0) { if (error != 0) {
errno = errno_fixup_directory(fd, error); errno = errno_fixup_directory(fd, error);
return -1; return -1;
@ -43,11 +32,7 @@ int faccessat(int fd, const char *path, int amode, int flag) {
// directory file descriptor. // directory file descriptor.
if (amode != 0) { if (amode != 0) {
__wasi_fdstat_t directory; __wasi_fdstat_t directory;
#ifdef __wasilibc_unmodified_upstream
error = __wasi_fd_stat_get(fd, &directory);
#else
error = __wasi_fd_fdstat_get(fd, &directory); error = __wasi_fd_fdstat_get(fd, &directory);
#endif
if (error != 0) { if (error != 0) {
errno = error; errno = error;
return -1; return -1;
@ -55,25 +40,11 @@ int faccessat(int fd, const char *path, int amode, int flag) {
__wasi_rights_t min = 0; __wasi_rights_t min = 0;
if ((amode & R_OK) != 0) if ((amode & R_OK) != 0)
#ifdef __wasilibc_unmodified_upstream
min |= file.st_filetype == __WASI_FILETYPE_DIRECTORY
? __WASI_RIGHT_FILE_READDIR
: __WASI_RIGHT_FD_READ;
#else
min |= file.filetype == __WASI_FILETYPE_DIRECTORY min |= file.filetype == __WASI_FILETYPE_DIRECTORY
? __WASI_RIGHTS_FD_READDIR ? __WASI_RIGHTS_FD_READDIR
: __WASI_RIGHTS_FD_READ; : __WASI_RIGHTS_FD_READ;
#endif
if ((amode & W_OK) != 0) if ((amode & W_OK) != 0)
#ifdef __wasilibc_unmodified_upstream // generated constant names
min |= __WASI_RIGHT_FD_WRITE;
#else
min |= __WASI_RIGHTS_FD_WRITE; min |= __WASI_RIGHTS_FD_WRITE;
#endif
#ifdef __wasilibc_unmodified_upstream // RIGHT_PROC_EXEC
if ((amode & X_OK) != 0 && file.st_filetype != __WASI_FILETYPE_DIRECTORY)
min |= __WASI_RIGHT_PROC_EXEC;
#endif
if ((min & directory.fs_rights_inheriting) != min) { if ((min & directory.fs_rights_inheriting) != min) {
errno = EACCES; errno = EACCES;

View File

@ -11,19 +11,9 @@ int ftruncate(int fildes, off_t length) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
#ifdef __wasilibc_unmodified_upstream // fstat
__wasi_filestat_t fs = {
.st_size = length,
};
#else
__wasi_filesize_t st_size = length; __wasi_filesize_t st_size = length;
#endif
__wasi_errno_t error = __wasi_errno_t error =
#ifdef __wasilibc_unmodified_upstream // fstat
__wasi_file_stat_fput(fildes, &fs, __WASI_FILESTAT_SIZE);
#else
__wasi_fd_filestat_set_size(fildes, st_size); __wasi_fd_filestat_set_size(fildes, st_size);
#endif
if (error != 0) { if (error != 0) {
errno = error; errno = error;
return -1; return -1;

View File

@ -10,27 +10,14 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
int linkat(int fd1, const char *path1, int fd2, const char *path2, int flag) { int __wasilibc_nocwd_linkat(int fd1, const char *path1, int fd2, const char *path2, int flag) {
// Create lookup properties. // Create lookup properties.
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
__wasi_lookup_t lookup1 = {.fd = fd1, .flags = 0};
#else
__wasi_lookupflags_t lookup1_flags = 0; __wasi_lookupflags_t lookup1_flags = 0;
#endif
if ((flag & AT_SYMLINK_FOLLOW) != 0) if ((flag & AT_SYMLINK_FOLLOW) != 0)
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t
lookup1.flags |= __WASI_LOOKUP_SYMLINK_FOLLOW;
#else
lookup1_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW; lookup1_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW;
#endif
// Perform system call. // Perform system call.
#ifdef __wasilibc_unmodified_upstream // split out __wasi_lookup_t __wasi_errno_t error = __wasi_path_link(fd1, lookup1_flags, path1, fd2, path2);
__wasi_errno_t error = __wasi_file_link(lookup1, path1, strlen(path1),
#else
__wasi_errno_t error = __wasi_path_link(fd1, lookup1_flags, path1, strlen(path1),
#endif
fd2, path2, strlen(path2));
if (error != 0) { if (error != 0) {
errno = errno_fixup_directory(fd1, errno_fixup_directory(fd2, error)); errno = errno_fixup_directory(fd1, errno_fixup_directory(fd2, error));
return -1; return -1;

View File

@ -11,11 +11,7 @@ static_assert(SEEK_CUR == __WASI_WHENCE_CUR, "Value mismatch");
static_assert(SEEK_END == __WASI_WHENCE_END, "Value mismatch"); static_assert(SEEK_END == __WASI_WHENCE_END, "Value mismatch");
static_assert(SEEK_SET == __WASI_WHENCE_SET, "Value mismatch"); static_assert(SEEK_SET == __WASI_WHENCE_SET, "Value mismatch");
#ifdef __wasilibc_unmodified_upstream // Provide an __lseek entry point
off_t lseek(int fildes, off_t offset, int whence) {
#else
off_t __lseek(int fildes, off_t offset, int whence) { off_t __lseek(int fildes, off_t offset, int whence) {
#endif
__wasi_filesize_t new_offset; __wasi_filesize_t new_offset;
__wasi_errno_t error = __wasi_errno_t error =
__wasi_fd_seek(fildes, offset, whence, &new_offset); __wasi_fd_seek(fildes, offset, whence, &new_offset);
@ -26,7 +22,4 @@ off_t __lseek(int fildes, off_t offset, int whence) {
return new_offset; return new_offset;
} }
#ifdef __wasilibc_unmodified_upstream // Provide an __lseek entry point
#else
extern __typeof(__lseek) lseek __attribute__((weak, alias("__lseek"))); extern __typeof(__lseek) lseek __attribute__((weak, alias("__lseek")));
#endif

View File

@ -17,17 +17,9 @@ ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset) {
__wasi_fd_pread(fildes, &iov, 1, offset, &bytes_read); __wasi_fd_pread(fildes, &iov, 1, offset, &bytes_read);
if (error != 0) { if (error != 0) {
__wasi_fdstat_t fds; __wasi_fdstat_t fds;
#ifdef __wasilibc_unmodified_upstream
if (error == ENOTCAPABLE && __wasi_fd_stat_get(fildes, &fds) == 0) {
#else
if (error == ENOTCAPABLE && __wasi_fd_fdstat_get(fildes, &fds) == 0) { if (error == ENOTCAPABLE && __wasi_fd_fdstat_get(fildes, &fds) == 0) {
#endif
// Determine why we got ENOTCAPABLE. // Determine why we got ENOTCAPABLE.
#ifdef __wasilibc_unmodified_upstream // generated constant names
if ((fds.fs_rights_base & __WASI_RIGHT_FD_READ) == 0)
#else
if ((fds.fs_rights_base & __WASI_RIGHTS_FD_READ) == 0) if ((fds.fs_rights_base & __WASI_RIGHTS_FD_READ) == 0)
#endif
error = EBADF; error = EBADF;
else else
error = ESPIPE; error = ESPIPE;

View File

@ -17,17 +17,9 @@ ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset) {
__wasi_fd_pwrite(fildes, &iov, 1, offset, &bytes_written); __wasi_fd_pwrite(fildes, &iov, 1, offset, &bytes_written);
if (error != 0) { if (error != 0) {
__wasi_fdstat_t fds; __wasi_fdstat_t fds;
#ifdef __wasilibc_unmodified_upstream
if (error == ENOTCAPABLE && __wasi_fd_stat_get(fildes, &fds) == 0) {
#else
if (error == ENOTCAPABLE && __wasi_fd_fdstat_get(fildes, &fds) == 0) { if (error == ENOTCAPABLE && __wasi_fd_fdstat_get(fildes, &fds) == 0) {
#endif
// Determine why we got ENOTCAPABLE. // Determine why we got ENOTCAPABLE.
#ifdef __wasilibc_unmodified_upstream // generated constant names
if ((fds.fs_rights_base & __WASI_RIGHT_FD_WRITE) == 0)
#else
if ((fds.fs_rights_base & __WASI_RIGHTS_FD_WRITE) == 0) if ((fds.fs_rights_base & __WASI_RIGHTS_FD_WRITE) == 0)
#endif
error = EBADF; error = EBADF;
else else
error = ESPIPE; error = ESPIPE;

View File

@ -9,17 +9,12 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf, ssize_t __wasilibc_nocwd_readlinkat(int fd, const char *restrict path, char *restrict buf,
size_t bufsize) { size_t bufsize) {
size_t bufused; size_t bufused;
#ifdef __wasilibc_unmodified_upstream
__wasi_errno_t error = __wasi_file_readlink(fd, path, strlen(path),
buf, bufsize, &bufused);
#else
// TODO: Remove the cast on `buf` once the witx is updated with char8 support. // TODO: Remove the cast on `buf` once the witx is updated with char8 support.
__wasi_errno_t error = __wasi_path_readlink(fd, path, strlen(path), __wasi_errno_t error = __wasi_path_readlink(fd, path,
(uint8_t*)buf, bufsize, &bufused); (uint8_t*)buf, bufsize, &bufused);
#endif
if (error != 0) { if (error != 0) {
errno = errno_fixup_directory(fd, error); errno = errno_fixup_directory(fd, error);
return -1; return -1;

View File

@ -7,11 +7,7 @@
unsigned int sleep(unsigned int seconds) { unsigned int sleep(unsigned int seconds) {
struct timespec ts = {.tv_sec = seconds, .tv_nsec = 0}; struct timespec ts = {.tv_sec = seconds, .tv_nsec = 0};
#ifdef __wasilibc_unmodified_upstream
if (clock_nanosleep(CLOCK_REALTIME, 0, &ts) != 0)
#else
if (clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL) != 0) if (clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL) != 0)
#endif
return seconds; return seconds;
return 0; return 0;
} }

View File

@ -9,13 +9,8 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
int symlinkat(const char *path1, int fd, const char *path2) { int __wasilibc_nocwd_symlinkat(const char *path1, int fd, const char *path2) {
__wasi_errno_t error = __wasi_errno_t error = __wasi_path_symlink(path1, fd, path2);
#ifdef __wasilibc_unmodified_upstream
__wasi_file_symlink(path1, strlen(path1), fd, path2, strlen(path2));
#else
__wasi_path_symlink(path1, strlen(path1), fd, path2, strlen(path2));
#endif
if (error != 0) { if (error != 0) {
errno = errno_fixup_directory(fd, error); errno = errno_fixup_directory(fd, error);
return -1; return -1;

View File

@ -5,31 +5,15 @@
#include <common/errno.h> #include <common/errno.h>
#include <wasi/api.h> #include <wasi/api.h>
#ifdef __wasilibc_unmodified_upstream // unlink
#else
#include <wasi/libc.h> #include <wasi/libc.h>
#endif
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
int unlinkat(int fd, const char *path, int flag) { int unlinkat(int fd, const char *path, int flag) {
#ifdef __wasilibc_unmodified_upstream // unlink
__wasi_ulflags_t ulflags = 0;
if ((flag & AT_REMOVEDIR) != 0)
ulflags |= __WASI_UNLINK_REMOVEDIR;
__wasi_errno_t error =
__wasi_file_unlink(fd, path, strlen(path), ulflags);
if (error != 0) {
errno = errno_fixup_directory(fd, error);
return -1;
}
return 0;
#else
if ((flag & AT_REMOVEDIR) != 0) { if ((flag & AT_REMOVEDIR) != 0) {
return __wasilibc_rmdirat(fd, path); return __wasilibc_rmdirat(fd, path);
} }
return __wasilibc_unlinkat(fd, path); return __wasilibc_unlinkat(fd, path);
#endif
} }

View File

@ -9,11 +9,7 @@
int usleep(useconds_t useconds) { int usleep(useconds_t useconds) {
struct timespec ts = {.tv_sec = useconds / 1000000, struct timespec ts = {.tv_sec = useconds / 1000000,
.tv_nsec = useconds % 1000000 * 1000}; .tv_nsec = useconds % 1000000 * 1000};
#ifdef __wasilibc_unmodified_upstream
int error = clock_nanosleep(CLOCK_REALTIME, 0, &ts);
#else
int error = clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL); int error = clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL);
#endif
if (error != 0) { if (error != 0) {
errno = error; errno = error;
return -1; return -1;

View File

@ -0,0 +1,6 @@
#include <unistd.h>
pid_t getpid(void) {
// Return an arbitrary value, greater than 1 which is special.
return 42;
}

View File

@ -1,2 +1,3 @@
#include <_/cdefs.h> #include <_/cdefs.h>
int snprintf(char *str, size_t size, const char *format, ...); int snprintf(char *str, size_t size, const char *format, ...);
int rename(const char *oldpath, const char *newpath);

View File

@ -4,3 +4,5 @@
#include <stddef.h> #include <stddef.h>
#include_next <stdlib.h> #include_next <stdlib.h>
int clearenv(void);

View File

@ -56,4 +56,6 @@
#define AT_SYMLINK_FOLLOW (0x2) #define AT_SYMLINK_FOLLOW (0x2)
#define AT_REMOVEDIR (0x4) #define AT_REMOVEDIR (0x4)
#define AT_FDCWD (-2)
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,10 @@
#ifndef __wasi_libc_environ_h #ifndef __wasi_libc_environ_h
#define __wasi_libc_environ_h #define __wasi_libc_environ_h
/// This header file is a WASI-libc-specific interface, and is not needed by
/// most programs. Most programs should just use the standard `getenv` and
/// related APIs, which take care of all of the details automatically.
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -12,6 +16,19 @@ void __wasilibc_initialize_environ(void);
/// If `__wasilibc_initialize_environ` has not yet been called, call it. /// If `__wasilibc_initialize_environ` has not yet been called, call it.
void __wasilibc_ensure_environ(void); void __wasilibc_ensure_environ(void);
/// De-initialize the global environment variable state, so that subsequent
/// calls to `__wasilibc_ensure_environ` call `__wasilibc_initialize_environ`.
void __wasilibc_deinitialize_environ(void);
/// Call `__wasilibc_initialize_environ` only if `environ` and `_environ` are
/// referenced in the program.
void __wasilibc_maybe_reinitialize_environ_eagerly(void);
/// Return the value of the `environ` variable. Using `environ` directly
/// requires eager initialization of the environment variables. Using this
/// function instead of `environ` allows initialization to happen lazily.
char **__wasilibc_get_environ(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -0,0 +1,58 @@
#ifndef __wasi_libc_nocwd_h
#define __wasi_libc_nocwd_h
/*
* In order to support AT_FDCWD, we need to wrap the *at functions to handle
* it by calling back into the non-at versions which perform libpreopen
* queries. These __wasilibc_nocwd_* forms are the underlying calls which
* assume AT_FDCWD has already been resolved.
*/
#define __need_size_t
#include <stddef.h>
#include <__typedef_ssize_t.h>
#include <__typedef_mode_t.h>
#include <__typedef_DIR.h>
#ifdef __cplusplus
extern "C" {
#endif
struct timespec;
struct stat;
struct dirent;
int __wasilibc_nocwd___wasilibc_unlinkat(int, const char *)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd___wasilibc_rmdirat(int, const char *)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_linkat(int, const char *, int, const char *, int)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_symlinkat(const char *, int, const char *)
__attribute__((__warn_unused_result__));
ssize_t __wasilibc_nocwd_readlinkat(int, const char *__restrict, char *__restrict, size_t)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_faccessat(int, const char *, int, int)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_renameat(int, const char *, int, const char *)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_openat_nomode(int, const char *, int)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_fstatat(int, const char *__restrict, struct stat *__restrict, int)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_mkdirat_nomode(int, const char *)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_utimensat(int, const char *, const struct timespec [2], int)
__attribute__((__warn_unused_result__));
DIR *__wasilibc_nocwd_opendirat(int, const char *)
__attribute__((__warn_unused_result__));
int __wasilibc_nocwd_scandirat(int, const char *, struct dirent ***,
int (*)(const struct dirent *),
int (*)(const struct dirent **, const struct dirent **))
__attribute__((__warn_unused_result__));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -2,11 +2,15 @@
#define __wasi_libc_h #define __wasi_libc_h
#include <__typedef_off_t.h> #include <__typedef_off_t.h>
#include <__struct_timespec.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
struct stat;
struct timespec;
/// Register the given pre-opened file descriptor under the given path. /// Register the given pre-opened file descriptor under the given path.
/// ///
/// This function does not take ownership of `prefix` (it makes its own copy). /// This function does not take ownership of `prefix` (it makes its own copy).
@ -14,13 +18,16 @@ int __wasilibc_register_preopened_fd(int fd, const char *prefix);
/// Renumber `fd` to `newfd`; similar to `dup2` but does a move rather than a /// Renumber `fd` to `newfd`; similar to `dup2` but does a move rather than a
/// copy. /// copy.
int __wasilibc_fd_renumber(int fd, int newfd); int __wasilibc_fd_renumber(int fd, int newfd)
__attribute__((__warn_unused_result__));
/// Like `unlinkat`, but without depending on `__wasi_path_remove_directory`. /// Like `unlinkat`, but without depending on `__wasi_path_remove_directory`.
int __wasilibc_unlinkat(int fd, const char *path); int __wasilibc_unlinkat(int fd, const char *path)
__attribute__((__warn_unused_result__));
/// An `*at` version of rmdir. /// An `*at` version of rmdir.
int __wasilibc_rmdirat(int fd, const char *path); int __wasilibc_rmdirat(int fd, const char *path)
__attribute__((__warn_unused_result__));
/// Like `open`, but without the varargs in the signature. /// Like `open`, but without the varargs in the signature.
int __wasilibc_open_nomode(const char *path, int oflag); int __wasilibc_open_nomode(const char *path, int oflag);
@ -30,7 +37,26 @@ int __wasilibc_openat_nomode(int fd, const char *path, int oflag);
/// Return the current file offset. Like `lseek(fd, 0, SEEK_CUR)`, but without /// Return the current file offset. Like `lseek(fd, 0, SEEK_CUR)`, but without
/// depending on `lseek`. /// depending on `lseek`.
off_t __wasilibc_tell(int fd); off_t __wasilibc_tell(int fd)
__attribute__((__warn_unused_result__));
/* Non-`at` forms of various `*at` functions. */
int __wasilibc_access(const char *pathname, int mode, int flags)
__attribute__((__warn_unused_result__));
int __wasilibc_stat(const char *__restrict pathname, struct stat *__restrict statbuf, int flags)
__attribute__((__warn_unused_result__));
int __wasilibc_utimens(const char *pathname, const struct timespec times[2], int flags)
__attribute__((__warn_unused_result__));
int __wasilibc_link(const char *oldpath, const char *newpath, int flags)
__attribute__((__warn_unused_result__));
int __wasilibc_link_oldat(int olddirfd, const char *oldpath, const char *newpath, int flags)
__attribute__((__warn_unused_result__));
int __wasilibc_link_newat(const char *oldpath, int newdirfd, const char *newpath, int flags)
__attribute__((__warn_unused_result__));
int __wasilibc_rename_oldat(int olddirfd, const char *oldpath, const char *newpath)
__attribute__((__warn_unused_result__));
int __wasilibc_rename_newat(const char *oldpath, int newdirfd, const char *newpath)
__attribute__((__warn_unused_result__));
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -0,0 +1,14 @@
#include <wasi/libc-environ.h>
extern char **__wasilibc_environ;
// See the comments in libc-environ.h.
char **__wasilibc_get_environ(void) {
// Perform lazy initialization if needed.
__wasilibc_ensure_environ();
// Return `environ`. Use the `__wasilibc_`-prefixed name so that we don't
// pull in the `environ` symbol directly, which would lead to eager
// initialization being done instead.
return __wasilibc_environ;
}

View File

@ -75,3 +75,20 @@ oserr:
software: software:
_Exit(EX_SOFTWARE); _Exit(EX_SOFTWARE);
} }
// See the comments in libc-environ.h.
void __wasilibc_deinitialize_environ(void) {
if (__wasilibc_environ != (char **)-1) {
// Let libc-top-half clear the old environment-variable strings.
clearenv();
// Set the pointer to the special init value.
__wasilibc_environ = (char **)-1;
}
}
// See the comments in libc-environ.h.
__attribute__((weak))
void __wasilibc_maybe_reinitialize_environ_eagerly(void) {
// This version does nothing. It may be overridden by a version which does
// something if `environ` is used.
}

View File

@ -0,0 +1,659 @@
/**
* THIS FILE IS AUTO-GENERATED from the following files:
* wasi_snapshot_preview1.witx
*
* To regenerate this file execute:
*
* cargo run --manifest-path tools/wasi-headers/Cargo.toml generate-libc
*
* Modifications to this file will cause CI to fail, the code generator tool
* must be modified to change this file.
*/
#include <wasi/api.h>
#include <string.h>
int32_t __imported_wasi_snapshot_preview1_args_get(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("args_get")
));
__wasi_errno_t __wasi_args_get(
uint8_t * * argv,
uint8_t * argv_buf
){
int32_t ret = __imported_wasi_snapshot_preview1_args_get((int32_t) argv, (int32_t) argv_buf);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_args_sizes_get(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("args_sizes_get")
));
__wasi_errno_t __wasi_args_sizes_get(
__wasi_size_t *retptr0,
__wasi_size_t *retptr1
){
int32_t ret = __imported_wasi_snapshot_preview1_args_sizes_get((int32_t) retptr0, (int32_t) retptr1);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_environ_get(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("environ_get")
));
__wasi_errno_t __wasi_environ_get(
uint8_t * * environ,
uint8_t * environ_buf
){
int32_t ret = __imported_wasi_snapshot_preview1_environ_get((int32_t) environ, (int32_t) environ_buf);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_environ_sizes_get(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("environ_sizes_get")
));
__wasi_errno_t __wasi_environ_sizes_get(
__wasi_size_t *retptr0,
__wasi_size_t *retptr1
){
int32_t ret = __imported_wasi_snapshot_preview1_environ_sizes_get((int32_t) retptr0, (int32_t) retptr1);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_clock_res_get(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("clock_res_get")
));
__wasi_errno_t __wasi_clock_res_get(
__wasi_clockid_t id,
__wasi_timestamp_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_clock_res_get((int32_t) id, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_clock_time_get(int32_t arg0, int64_t arg1, int32_t arg2) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("clock_time_get")
));
__wasi_errno_t __wasi_clock_time_get(
__wasi_clockid_t id,
__wasi_timestamp_t precision,
__wasi_timestamp_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_clock_time_get((int32_t) id, (int64_t) precision, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_advise(int32_t arg0, int64_t arg1, int64_t arg2, int32_t arg3) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_advise")
));
__wasi_errno_t __wasi_fd_advise(
__wasi_fd_t fd,
__wasi_filesize_t offset,
__wasi_filesize_t len,
__wasi_advice_t advice
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_advise((int32_t) fd, (int64_t) offset, (int64_t) len, (int32_t) advice);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_allocate(int32_t arg0, int64_t arg1, int64_t arg2) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_allocate")
));
__wasi_errno_t __wasi_fd_allocate(
__wasi_fd_t fd,
__wasi_filesize_t offset,
__wasi_filesize_t len
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_allocate((int32_t) fd, (int64_t) offset, (int64_t) len);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_close(int32_t arg0) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_close")
));
__wasi_errno_t __wasi_fd_close(
__wasi_fd_t fd
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_close((int32_t) fd);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_datasync(int32_t arg0) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_datasync")
));
__wasi_errno_t __wasi_fd_datasync(
__wasi_fd_t fd
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_datasync((int32_t) fd);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_fdstat_get(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_fdstat_get")
));
__wasi_errno_t __wasi_fd_fdstat_get(
__wasi_fd_t fd,
__wasi_fdstat_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_fdstat_get((int32_t) fd, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_fdstat_set_flags(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_fdstat_set_flags")
));
__wasi_errno_t __wasi_fd_fdstat_set_flags(
__wasi_fd_t fd,
__wasi_fdflags_t flags
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_fdstat_set_flags((int32_t) fd, flags);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_fdstat_set_rights(int32_t arg0, int64_t arg1, int64_t arg2) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_fdstat_set_rights")
));
__wasi_errno_t __wasi_fd_fdstat_set_rights(
__wasi_fd_t fd,
__wasi_rights_t fs_rights_base,
__wasi_rights_t fs_rights_inheriting
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_fdstat_set_rights((int32_t) fd, fs_rights_base, fs_rights_inheriting);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_filestat_get(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_filestat_get")
));
__wasi_errno_t __wasi_fd_filestat_get(
__wasi_fd_t fd,
__wasi_filestat_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_filestat_get((int32_t) fd, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_filestat_set_size(int32_t arg0, int64_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_filestat_set_size")
));
__wasi_errno_t __wasi_fd_filestat_set_size(
__wasi_fd_t fd,
__wasi_filesize_t size
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_filestat_set_size((int32_t) fd, (int64_t) size);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_filestat_set_times(int32_t arg0, int64_t arg1, int64_t arg2, int32_t arg3) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_filestat_set_times")
));
__wasi_errno_t __wasi_fd_filestat_set_times(
__wasi_fd_t fd,
__wasi_timestamp_t atim,
__wasi_timestamp_t mtim,
__wasi_fstflags_t fst_flags
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_filestat_set_times((int32_t) fd, (int64_t) atim, (int64_t) mtim, fst_flags);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_pread(int32_t arg0, int32_t arg1, int32_t arg2, int64_t arg3, int32_t arg4) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_pread")
));
__wasi_errno_t __wasi_fd_pread(
__wasi_fd_t fd,
const __wasi_iovec_t *iovs,
size_t iovs_len,
__wasi_filesize_t offset,
__wasi_size_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_pread((int32_t) fd, (int32_t) iovs, (int32_t) iovs_len, (int64_t) offset, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_prestat_get(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_prestat_get")
));
__wasi_errno_t __wasi_fd_prestat_get(
__wasi_fd_t fd,
__wasi_prestat_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_prestat_get((int32_t) fd, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_prestat_dir_name(int32_t arg0, int32_t arg1, int32_t arg2) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_prestat_dir_name")
));
__wasi_errno_t __wasi_fd_prestat_dir_name(
__wasi_fd_t fd,
uint8_t * path,
__wasi_size_t path_len
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_prestat_dir_name((int32_t) fd, (int32_t) path, (int32_t) path_len);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_pwrite(int32_t arg0, int32_t arg1, int32_t arg2, int64_t arg3, int32_t arg4) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_pwrite")
));
__wasi_errno_t __wasi_fd_pwrite(
__wasi_fd_t fd,
const __wasi_ciovec_t *iovs,
size_t iovs_len,
__wasi_filesize_t offset,
__wasi_size_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_pwrite((int32_t) fd, (int32_t) iovs, (int32_t) iovs_len, (int64_t) offset, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_read(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_read")
));
__wasi_errno_t __wasi_fd_read(
__wasi_fd_t fd,
const __wasi_iovec_t *iovs,
size_t iovs_len,
__wasi_size_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_read((int32_t) fd, (int32_t) iovs, (int32_t) iovs_len, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_readdir(int32_t arg0, int32_t arg1, int32_t arg2, int64_t arg3, int32_t arg4) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_readdir")
));
__wasi_errno_t __wasi_fd_readdir(
__wasi_fd_t fd,
uint8_t * buf,
__wasi_size_t buf_len,
__wasi_dircookie_t cookie,
__wasi_size_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_readdir((int32_t) fd, (int32_t) buf, (int32_t) buf_len, (int64_t) cookie, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_renumber(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_renumber")
));
__wasi_errno_t __wasi_fd_renumber(
__wasi_fd_t fd,
__wasi_fd_t to
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_renumber((int32_t) fd, (int32_t) to);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_seek(int32_t arg0, int64_t arg1, int32_t arg2, int32_t arg3) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_seek")
));
__wasi_errno_t __wasi_fd_seek(
__wasi_fd_t fd,
__wasi_filedelta_t offset,
__wasi_whence_t whence,
__wasi_filesize_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_seek((int32_t) fd, offset, (int32_t) whence, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_sync(int32_t arg0) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_sync")
));
__wasi_errno_t __wasi_fd_sync(
__wasi_fd_t fd
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_sync((int32_t) fd);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_tell(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_tell")
));
__wasi_errno_t __wasi_fd_tell(
__wasi_fd_t fd,
__wasi_filesize_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_tell((int32_t) fd, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_fd_write(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_write")
));
__wasi_errno_t __wasi_fd_write(
__wasi_fd_t fd,
const __wasi_ciovec_t *iovs,
size_t iovs_len,
__wasi_size_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_fd_write((int32_t) fd, (int32_t) iovs, (int32_t) iovs_len, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_path_create_directory(int32_t arg0, int32_t arg1, int32_t arg2) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("path_create_directory")
));
__wasi_errno_t __wasi_path_create_directory(
__wasi_fd_t fd,
const char *path
){
size_t path_len = strlen(path);
int32_t ret = __imported_wasi_snapshot_preview1_path_create_directory((int32_t) fd, (int32_t) path, (int32_t) path_len);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_path_filestat_get(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("path_filestat_get")
));
__wasi_errno_t __wasi_path_filestat_get(
__wasi_fd_t fd,
__wasi_lookupflags_t flags,
const char *path,
__wasi_filestat_t *retptr0
){
size_t path_len = strlen(path);
int32_t ret = __imported_wasi_snapshot_preview1_path_filestat_get((int32_t) fd, flags, (int32_t) path, (int32_t) path_len, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_path_filestat_set_times(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int64_t arg4, int64_t arg5, int32_t arg6) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("path_filestat_set_times")
));
__wasi_errno_t __wasi_path_filestat_set_times(
__wasi_fd_t fd,
__wasi_lookupflags_t flags,
const char *path,
__wasi_timestamp_t atim,
__wasi_timestamp_t mtim,
__wasi_fstflags_t fst_flags
){
size_t path_len = strlen(path);
int32_t ret = __imported_wasi_snapshot_preview1_path_filestat_set_times((int32_t) fd, flags, (int32_t) path, (int32_t) path_len, (int64_t) atim, (int64_t) mtim, fst_flags);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_path_link(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4, int32_t arg5, int32_t arg6) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("path_link")
));
__wasi_errno_t __wasi_path_link(
__wasi_fd_t old_fd,
__wasi_lookupflags_t old_flags,
const char *old_path,
__wasi_fd_t new_fd,
const char *new_path
){
size_t old_path_len = strlen(old_path);
size_t new_path_len = strlen(new_path);
int32_t ret = __imported_wasi_snapshot_preview1_path_link((int32_t) old_fd, old_flags, (int32_t) old_path, (int32_t) old_path_len, (int32_t) new_fd, (int32_t) new_path, (int32_t) new_path_len);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_path_open(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4, int64_t arg5, int64_t arg6, int32_t arg7, int32_t arg8) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("path_open")
));
__wasi_errno_t __wasi_path_open(
__wasi_fd_t fd,
__wasi_lookupflags_t dirflags,
const char *path,
__wasi_oflags_t oflags,
__wasi_rights_t fs_rights_base,
__wasi_rights_t fs_rights_inheriting,
__wasi_fdflags_t fdflags,
__wasi_fd_t *retptr0
){
size_t path_len = strlen(path);
int32_t ret = __imported_wasi_snapshot_preview1_path_open((int32_t) fd, dirflags, (int32_t) path, (int32_t) path_len, oflags, fs_rights_base, fs_rights_inheriting, fdflags, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_path_readlink(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4, int32_t arg5) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("path_readlink")
));
__wasi_errno_t __wasi_path_readlink(
__wasi_fd_t fd,
const char *path,
uint8_t * buf,
__wasi_size_t buf_len,
__wasi_size_t *retptr0
){
size_t path_len = strlen(path);
int32_t ret = __imported_wasi_snapshot_preview1_path_readlink((int32_t) fd, (int32_t) path, (int32_t) path_len, (int32_t) buf, (int32_t) buf_len, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_path_remove_directory(int32_t arg0, int32_t arg1, int32_t arg2) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("path_remove_directory")
));
__wasi_errno_t __wasi_path_remove_directory(
__wasi_fd_t fd,
const char *path
){
size_t path_len = strlen(path);
int32_t ret = __imported_wasi_snapshot_preview1_path_remove_directory((int32_t) fd, (int32_t) path, (int32_t) path_len);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_path_rename(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4, int32_t arg5) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("path_rename")
));
__wasi_errno_t __wasi_path_rename(
__wasi_fd_t fd,
const char *old_path,
__wasi_fd_t new_fd,
const char *new_path
){
size_t old_path_len = strlen(old_path);
size_t new_path_len = strlen(new_path);
int32_t ret = __imported_wasi_snapshot_preview1_path_rename((int32_t) fd, (int32_t) old_path, (int32_t) old_path_len, (int32_t) new_fd, (int32_t) new_path, (int32_t) new_path_len);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_path_symlink(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("path_symlink")
));
__wasi_errno_t __wasi_path_symlink(
const char *old_path,
__wasi_fd_t fd,
const char *new_path
){
size_t old_path_len = strlen(old_path);
size_t new_path_len = strlen(new_path);
int32_t ret = __imported_wasi_snapshot_preview1_path_symlink((int32_t) old_path, (int32_t) old_path_len, (int32_t) fd, (int32_t) new_path, (int32_t) new_path_len);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_path_unlink_file(int32_t arg0, int32_t arg1, int32_t arg2) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("path_unlink_file")
));
__wasi_errno_t __wasi_path_unlink_file(
__wasi_fd_t fd,
const char *path
){
size_t path_len = strlen(path);
int32_t ret = __imported_wasi_snapshot_preview1_path_unlink_file((int32_t) fd, (int32_t) path, (int32_t) path_len);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_poll_oneoff(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("poll_oneoff")
));
__wasi_errno_t __wasi_poll_oneoff(
const __wasi_subscription_t * in,
__wasi_event_t * out,
__wasi_size_t nsubscriptions,
__wasi_size_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_poll_oneoff((int32_t) in, (int32_t) out, (int32_t) nsubscriptions, (int32_t) retptr0);
return (uint16_t) ret;
}
_Noreturn void __imported_wasi_snapshot_preview1_proc_exit(int32_t arg0) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("proc_exit")
));
_Noreturn void __wasi_proc_exit(
__wasi_exitcode_t rval
){
__imported_wasi_snapshot_preview1_proc_exit((int32_t) rval);
}
int32_t __imported_wasi_snapshot_preview1_proc_raise(int32_t arg0) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("proc_raise")
));
__wasi_errno_t __wasi_proc_raise(
__wasi_signal_t sig
){
int32_t ret = __imported_wasi_snapshot_preview1_proc_raise((int32_t) sig);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_sched_yield() __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("sched_yield")
));
__wasi_errno_t __wasi_sched_yield(
void
){
int32_t ret = __imported_wasi_snapshot_preview1_sched_yield();
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_random_get(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("random_get")
));
__wasi_errno_t __wasi_random_get(
uint8_t * buf,
__wasi_size_t buf_len
){
int32_t ret = __imported_wasi_snapshot_preview1_random_get((int32_t) buf, (int32_t) buf_len);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_sock_recv(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4, int32_t arg5) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("sock_recv")
));
__wasi_errno_t __wasi_sock_recv(
__wasi_fd_t fd,
const __wasi_iovec_t *ri_data,
size_t ri_data_len,
__wasi_riflags_t ri_flags,
__wasi_size_t *retptr0,
__wasi_roflags_t *retptr1
){
int32_t ret = __imported_wasi_snapshot_preview1_sock_recv((int32_t) fd, (int32_t) ri_data, (int32_t) ri_data_len, ri_flags, (int32_t) retptr0, (int32_t) retptr1);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_sock_send(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("sock_send")
));
__wasi_errno_t __wasi_sock_send(
__wasi_fd_t fd,
const __wasi_ciovec_t *si_data,
size_t si_data_len,
__wasi_siflags_t si_flags,
__wasi_size_t *retptr0
){
int32_t ret = __imported_wasi_snapshot_preview1_sock_send((int32_t) fd, (int32_t) si_data, (int32_t) si_data_len, (int32_t) si_flags, (int32_t) retptr0);
return (uint16_t) ret;
}
int32_t __imported_wasi_snapshot_preview1_sock_shutdown(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("sock_shutdown")
));
__wasi_errno_t __wasi_sock_shutdown(
__wasi_fd_t fd,
__wasi_sdflags_t how
){
int32_t ret = __imported_wasi_snapshot_preview1_sock_shutdown((int32_t) fd, how);
return (uint16_t) ret;
}

View File

@ -2,11 +2,9 @@
#include <wasi/api.h> #include <wasi/api.h>
#include <wasi/libc.h> #include <wasi/libc.h>
#include <errno.h> #include <errno.h>
#include <string.h>
int __wasilibc_rmdirat(int fd, const char *path) { int __wasilibc_nocwd___wasilibc_rmdirat(int fd, const char *path) {
size_t path_len = strlen(path); __wasi_errno_t error = __wasi_path_remove_directory(fd, path);
__wasi_errno_t error = __wasi_path_remove_directory(fd, path, path_len);
if (error != 0) { if (error != 0) {
errno = errno_fixup_directory(fd, error); errno = errno_fixup_directory(fd, error);
return -1; return -1;

View File

@ -2,11 +2,9 @@
#include <wasi/api.h> #include <wasi/api.h>
#include <wasi/libc.h> #include <wasi/libc.h>
#include <errno.h> #include <errno.h>
#include <string.h>
int __wasilibc_unlinkat(int fd, const char *path) { int __wasilibc_nocwd___wasilibc_unlinkat(int fd, const char *path) {
size_t path_len = strlen(path); __wasi_errno_t error = __wasi_path_unlink_file(fd, path);
__wasi_errno_t error = __wasi_path_unlink_file(fd, path, path_len);
if (error != 0) { if (error != 0) {
errno = error; errno = error;
return -1; return -1;

View File

@ -0,0 +1,141 @@
// Handle AT_FDCWD and absolute paths for the *at functions.
//
// In the case of an AT_FDCWD file descriptor or an absolute path, call the
// corresponding non-`at` function. This will send it through the libpreopen
// wrappers to convert the path into a directory file descriptor and relative
// path before translating it into the corresponding `__wasilibc_nocwd_*at`
// function, which then calls the appropriate WASI function.
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <wasi/libc.h>
#include <wasi/libc-nocwd.h>
// If the platform doesn't define O_TMPFILE, we don't need to worry about it.
#ifndef O_TMPFILE
#define O_TMPFILE 0
#endif
int openat(int dirfd, const char *pathname, int flags, ...) {
if (dirfd == AT_FDCWD || pathname[0] == '/') {
return open(pathname, flags);
}
return __wasilibc_nocwd_openat_nomode(dirfd, pathname, flags);
}
int symlinkat(const char *target, int dirfd, const char *linkpath) {
if (dirfd == AT_FDCWD || linkpath[0] == '/') {
return symlink(target, linkpath);
}
return __wasilibc_nocwd_symlinkat(target, dirfd, linkpath);
}
ssize_t readlinkat(int dirfd, const char *__restrict pathname, char *__restrict buf, size_t bufsiz) {
if (dirfd == AT_FDCWD || pathname[0] == '/') {
return readlink(pathname, buf, bufsiz);
}
return __wasilibc_nocwd_readlinkat(dirfd, pathname, buf, bufsiz);
}
int mkdirat(int dirfd, const char *pathname, mode_t mode) {
if (dirfd == AT_FDCWD || pathname[0] == '/') {
return mkdir(pathname, mode);
}
return __wasilibc_nocwd_mkdirat_nomode(dirfd, pathname);
}
DIR *opendirat(int dirfd, const char *path) {
if (dirfd == AT_FDCWD || path[0] == '/') {
return opendir(path);
}
return __wasilibc_nocwd_opendirat(dirfd, path);
}
int scandirat(int dirfd, const char *dirp, struct dirent ***namelist,
int (*filter)(const struct dirent *),
int (*compar)(const struct dirent **, const struct dirent **)) {
if (dirfd == AT_FDCWD || dirp[0] == '/') {
return scandir(dirp, namelist, filter, compar);
}
return __wasilibc_nocwd_scandirat(dirfd, dirp, namelist, filter, compar);
}
int faccessat(int dirfd, const char *pathname, int mode, int flags) {
if (dirfd == AT_FDCWD || pathname[0] == '/') {
return __wasilibc_access(pathname, mode, flags);
}
return __wasilibc_nocwd_faccessat(dirfd, pathname, mode, flags);
}
int fstatat(int dirfd, const char *__restrict pathname, struct stat *__restrict statbuf, int flags) {
if (dirfd == AT_FDCWD || pathname[0] == '/') {
return __wasilibc_stat(pathname, statbuf, flags);
}
return __wasilibc_nocwd_fstatat(dirfd, pathname, statbuf, flags);
}
int utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags) {
if (dirfd == AT_FDCWD || pathname[0] == '/') {
return __wasilibc_utimens(pathname, times, flags);
}
return __wasilibc_nocwd_utimensat(dirfd, pathname, times, flags);
}
int linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags) {
if ((olddirfd == AT_FDCWD || oldpath[0] == '/') &&
(newdirfd == AT_FDCWD || newpath[0] == '/')) {
return __wasilibc_link(oldpath, newpath, flags);
}
if (olddirfd == AT_FDCWD || oldpath[0] == '/') {
return __wasilibc_link_newat(oldpath, newdirfd, newpath, flags);
}
if (newdirfd == AT_FDCWD || newpath[0] == '/') {
return __wasilibc_link_oldat(olddirfd, oldpath, newpath, flags);
}
return __wasilibc_nocwd_linkat(olddirfd, oldpath, newdirfd, newpath, flags);
}
int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
if ((olddirfd == AT_FDCWD || oldpath[0] == '/') &&
(newdirfd == AT_FDCWD || newpath[0] == '/')) {
return rename(oldpath, newpath);
}
if (olddirfd == AT_FDCWD || oldpath[0] == '/') {
return __wasilibc_rename_newat(oldpath, newdirfd, newpath);
}
if (newdirfd == AT_FDCWD || newpath[0] == '/') {
return __wasilibc_rename_oldat(olddirfd, oldpath, newpath);
}
return __wasilibc_nocwd_renameat(olddirfd, oldpath, newdirfd, newpath);
}
int __wasilibc_unlinkat(int dirfd, const char *path) {
if (dirfd == AT_FDCWD || path[0] == '/') {
return unlink(path);
}
return __wasilibc_nocwd___wasilibc_unlinkat(dirfd, path);
}
int __wasilibc_rmdirat(int dirfd, const char *path) {
if (dirfd == AT_FDCWD || path[0] == '/') {
return rmdir(path);
}
return __wasilibc_nocwd___wasilibc_rmdirat(dirfd, path);
}

View File

@ -4,18 +4,26 @@
#include <complex.h> #include <complex.h>
float crealf(float _Complex x) { float (crealf)(float _Complex x) {
return __real__ x; return __builtin_crealf(x);
} }
double creal(double _Complex x) { double (creal)(double _Complex x) {
return __real__ x; return __builtin_creal(x);
} }
float cimagf(float _Complex x) { long double (creall)(long double _Complex x) {
return __imag__ x; return __builtin_creall(x);
} }
double cimag(double _Complex x) { float (cimagf)(float _Complex x) {
return __imag__ x; return __builtin_cimagf(x);
}
double (cimag)(double _Complex x) {
return __builtin_cimag(x);
}
long double (cimagl)(long double _Complex x) {
return __builtin_cimagl(x);
} }

View File

@ -24,3 +24,10 @@ __attribute__((constructor(50)))
static void __wasilibc_initialize_environ_eagerly(void) { static void __wasilibc_initialize_environ_eagerly(void) {
__wasilibc_initialize_environ(); __wasilibc_initialize_environ();
} }
// See the comments in libc-environ.h.
void __wasilibc_maybe_reinitialize_environ_eagerly(void) {
// This translation unit is linked in if `environ` is used, meaning we need
// to eagerly reinitialize the environment variables.
__wasilibc_initialize_environ();
}

View File

@ -19,7 +19,7 @@ char *getcwd(char *buf, size_t size)
} }
} else { } else {
size_t len = strlen(__wasilibc_cwd); size_t len = strlen(__wasilibc_cwd);
if (size < strlen(__wasilibc_cwd) + 1) { if (size < len + 1) {
errno = ERANGE; errno = ERANGE;
return NULL; return NULL;
} }

View File

@ -10,6 +10,7 @@
#include <utime.h> #include <utime.h>
#include <wasi/libc.h> #include <wasi/libc.h>
#include <wasi/libc-find-relpath.h> #include <wasi/libc-find-relpath.h>
#include <wasi/libc-nocwd.h>
static int find_relpath2( static int find_relpath2(
const char *path, const char *path,
@ -59,7 +60,7 @@ int __wasilibc_open_nomode(const char *path, int oflag) {
return -1; return -1;
} }
return __wasilibc_openat_nomode(dirfd, relative_path, oflag); return __wasilibc_nocwd_openat_nomode(dirfd, relative_path, oflag);
} }
int access(const char *path, int amode) { int access(const char *path, int amode) {
@ -72,7 +73,7 @@ int access(const char *path, int amode) {
return -1; return -1;
} }
return faccessat(dirfd, relative_path, amode, 0); return __wasilibc_nocwd_faccessat(dirfd, relative_path, amode, 0);
} }
ssize_t readlink( ssize_t readlink(
@ -89,7 +90,7 @@ ssize_t readlink(
return -1; return -1;
} }
return readlinkat(dirfd, relative_path, buf, bufsize); return __wasilibc_nocwd_readlinkat(dirfd, relative_path, buf, bufsize);
} }
int stat(const char *restrict path, struct stat *restrict buf) { int stat(const char *restrict path, struct stat *restrict buf) {
@ -102,7 +103,7 @@ int stat(const char *restrict path, struct stat *restrict buf) {
return -1; return -1;
} }
return fstatat(dirfd, relative_path, buf, 0); return __wasilibc_nocwd_fstatat(dirfd, relative_path, buf, 0);
} }
int lstat(const char *restrict path, struct stat *restrict buf) { int lstat(const char *restrict path, struct stat *restrict buf) {
@ -115,7 +116,7 @@ int lstat(const char *restrict path, struct stat *restrict buf) {
return -1; return -1;
} }
return fstatat(dirfd, relative_path, buf, AT_SYMLINK_NOFOLLOW); return __wasilibc_nocwd_fstatat(dirfd, relative_path, buf, AT_SYMLINK_NOFOLLOW);
} }
int utime(const char *path, const struct utimbuf *times) { int utime(const char *path, const struct utimbuf *times) {
@ -128,7 +129,8 @@ int utime(const char *path, const struct utimbuf *times) {
return -1; return -1;
} }
return utimensat(dirfd, relative_path, return __wasilibc_nocwd_utimensat(
dirfd, relative_path,
times ? ((struct timespec [2]) { times ? ((struct timespec [2]) {
{ .tv_sec = times->actime }, { .tv_sec = times->actime },
{ .tv_sec = times->modtime } { .tv_sec = times->modtime }
@ -150,7 +152,7 @@ int unlink(const char *path) {
// `unlinkat` imports `__wasi_path_remove_directory` even when // `unlinkat` imports `__wasi_path_remove_directory` even when
// `AT_REMOVEDIR` isn't passed. Instead, use a specialized function which // `AT_REMOVEDIR` isn't passed. Instead, use a specialized function which
// just imports `__wasi_path_unlink_file`. // just imports `__wasi_path_unlink_file`.
return __wasilibc_unlinkat(dirfd, relative_path); return __wasilibc_nocwd___wasilibc_unlinkat(dirfd, relative_path);
} }
int rmdir(const char *path) { int rmdir(const char *path) {
@ -163,7 +165,7 @@ int rmdir(const char *path) {
return -1; return -1;
} }
return __wasilibc_rmdirat(dirfd, relative_path); return __wasilibc_nocwd___wasilibc_rmdirat(dirfd, relative_path);
} }
int remove(const char *path) { int remove(const char *path) {
@ -177,10 +179,10 @@ int remove(const char *path) {
} }
// First try to remove it as a file. // First try to remove it as a file.
int r = __wasilibc_unlinkat(dirfd, relative_path); int r = __wasilibc_nocwd___wasilibc_unlinkat(dirfd, relative_path);
if (r != 0 && (errno == EISDIR || errno == ENOTCAPABLE)) { if (r != 0 && (errno == EISDIR || errno == ENOTCAPABLE)) {
// That failed, but it might be a directory. // That failed, but it might be a directory.
r = __wasilibc_rmdirat(dirfd, relative_path); r = __wasilibc_nocwd___wasilibc_rmdirat(dirfd, relative_path);
// If it isn't a directory, we lack capabilities to remove it as a file. // If it isn't a directory, we lack capabilities to remove it as a file.
if (errno == ENOTDIR) if (errno == ENOTDIR)
@ -199,7 +201,7 @@ int mkdir(const char *path, mode_t mode) {
return -1; return -1;
} }
return mkdirat(dirfd, relative_path, mode); return __wasilibc_nocwd_mkdirat_nomode(dirfd, relative_path);
} }
DIR *opendir(const char *dirname) { DIR *opendir(const char *dirname) {
@ -212,7 +214,7 @@ DIR *opendir(const char *dirname) {
return NULL; return NULL;
} }
return opendirat(dirfd, relative_path); return __wasilibc_nocwd_opendirat(dirfd, relative_path);
} }
int scandir( int scandir(
@ -230,7 +232,7 @@ int scandir(
return -1; return -1;
} }
return scandirat(dirfd, relative_path, namelist, filter, compar); return __wasilibc_nocwd_scandirat(dirfd, relative_path, namelist, filter, compar);
} }
int symlink(const char *target, const char *linkpath) { int symlink(const char *target, const char *linkpath) {
@ -243,7 +245,7 @@ int symlink(const char *target, const char *linkpath) {
return -1; return -1;
} }
return symlinkat(target, dirfd, relative_path); return __wasilibc_nocwd_symlinkat(target, dirfd, relative_path);
} }
int link(const char *old, const char *new) { int link(const char *old, const char *new) {
@ -255,8 +257,8 @@ int link(const char *old, const char *new) {
int new_dirfd = find_relpath(new, &new_relative_path); int new_dirfd = find_relpath(new, &new_relative_path);
if (new_dirfd != -1) if (new_dirfd != -1)
return linkat(old_dirfd, old_relative_path, return __wasilibc_nocwd_linkat(old_dirfd, old_relative_path,
new_dirfd, new_relative_path, 0); new_dirfd, new_relative_path, 0);
} }
// We couldn't find a preopen for it; indicate that we lack capabilities. // We couldn't find a preopen for it; indicate that we lack capabilities.
@ -273,11 +275,149 @@ int rename(const char *old, const char *new) {
int new_dirfd = find_relpath(new, &new_relative_path); int new_dirfd = find_relpath(new, &new_relative_path);
if (new_dirfd != -1) if (new_dirfd != -1)
return renameat(old_dirfd, old_relative_path, return __wasilibc_nocwd_renameat(old_dirfd, old_relative_path,
new_dirfd, new_relative_path); new_dirfd, new_relative_path);
} }
// We couldn't find a preopen for it; indicate that we lack capabilities. // We couldn't find a preopen for it; indicate that we lack capabilities.
errno = ENOTCAPABLE; errno = ENOTCAPABLE;
return -1; return -1;
} }
// Like `access`, but with `faccessat`'s flags argument.
int
__wasilibc_access(const char *path, int mode, int flags)
{
char *relative_path;
int dirfd = find_relpath(path, &relative_path);
// If we can't find a preopen for it, indicate that we lack capabilities.
if (dirfd == -1) {
errno = ENOTCAPABLE;
return -1;
}
return __wasilibc_nocwd_faccessat(dirfd, relative_path,
mode, flags);
}
// Like `utimensat`, but without the `at` part.
int
__wasilibc_utimens(const char *path, const struct timespec times[2], int flags)
{
char *relative_path;
int dirfd = find_relpath(path, &relative_path);
// If we can't find a preopen for it, indicate that we lack capabilities.
if (dirfd == -1) {
errno = ENOTCAPABLE;
return -1;
}
return __wasilibc_nocwd_utimensat(dirfd, relative_path,
times, flags);
}
// Like `stat`, but with `fstatat`'s flags argument.
int
__wasilibc_stat(const char *__restrict path, struct stat *__restrict st, int flags)
{
char *relative_path;
int dirfd = find_relpath(path, &relative_path);
// If we can't find a preopen for it, indicate that we lack capabilities.
if (dirfd == -1) {
errno = ENOTCAPABLE;
return -1;
}
return __wasilibc_nocwd_fstatat(dirfd, relative_path, st, flags);
}
// Like `link`, but with `linkat`'s flags argument.
int
__wasilibc_link(const char *oldpath, const char *newpath, int flags)
{
char *old_relative_path;
char *new_relative_path;
int old_dirfd = find_relpath(oldpath, &old_relative_path);
int new_dirfd = find_relpath(newpath, &new_relative_path);
// If we can't find a preopen for it, indicate that we lack capabilities.
if (old_dirfd == -1 || new_dirfd == -1) {
errno = ENOTCAPABLE;
return -1;
}
return __wasilibc_nocwd_linkat(old_dirfd, old_relative_path,
new_dirfd, new_relative_path,
flags);
}
// Like `__wasilibc_link`, but oldpath is relative to olddirfd.
int
__wasilibc_link_oldat(int olddirfd, const char *oldpath, const char *newpath, int flags)
{
char *new_relative_path;
int new_dirfd = find_relpath(newpath, &new_relative_path);
// If we can't find a preopen for it, indicate that we lack capabilities.
if (new_dirfd == -1) {
errno = ENOTCAPABLE;
return -1;
}
return __wasilibc_nocwd_linkat(olddirfd, oldpath,
new_dirfd, new_relative_path,
flags);
}
// Like `__wasilibc_link`, but newpath is relative to newdirfd.
int
__wasilibc_link_newat(const char *oldpath, int newdirfd, const char *newpath, int flags)
{
char *old_relative_path;
int old_dirfd = find_relpath(oldpath, &old_relative_path);
// If we can't find a preopen for it, indicate that we lack capabilities.
if (old_dirfd == -1) {
errno = ENOTCAPABLE;
return -1;
}
return __wasilibc_nocwd_linkat(old_dirfd, old_relative_path,
newdirfd, newpath,
flags);
}
// Like `rename`, but from is relative to fromdirfd.
int
__wasilibc_rename_oldat(int fromdirfd, const char *from, const char *to)
{
char *to_relative_path;
int to_dirfd = find_relpath(to, &to_relative_path);
// If we can't find a preopen for it, indicate that we lack capabilities.
if (to_dirfd == -1) {
errno = ENOTCAPABLE;
return -1;
}
return __wasilibc_nocwd_renameat(fromdirfd, from, to_dirfd, to_relative_path);
}
// Like `rename`, but to is relative to todirfd.
int
__wasilibc_rename_newat(const char *from, int todirfd, const char *to)
{
char *from_relative_path;
int from_dirfd = find_relpath(from, &from_relative_path);
// If we can't find a preopen for it, indicate that we lack capabilities.
if (from_dirfd == -1) {
errno = ENOTCAPABLE;
return -1;
}
return __wasilibc_nocwd_renameat(from_dirfd, from_relative_path, todirfd, to);
}

View File

@ -8,6 +8,7 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <limits.h> #include <limits.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
@ -96,7 +97,11 @@ static const char *strip_prefixes(const char *path) {
/// ///
/// This function takes ownership of `prefix`. /// This function takes ownership of `prefix`.
static int internal_register_preopened_fd(__wasi_fd_t fd, const char *relprefix) { static int internal_register_preopened_fd(__wasi_fd_t fd, const char *relprefix) {
// Check preconditions.
assert_invariants(); assert_invariants();
assert(fd != AT_FDCWD);
assert(fd != -1);
assert(relprefix != NULL);
if (num_preopens == preopen_capacity && resize() != 0) if (num_preopens == preopen_capacity && resize() != 0)
return -1; return -1;

View File

@ -86,7 +86,7 @@ and ABI combinations:
* SuperH (SH) * SuperH (SH)
* Standard ELF ABI or FDPIC ABI (shared-text without MMU) * Standard ELF ABI or FDPIC ABI (shared-text without MMU)
* Little-endian by default; big-engian variant also supported * Little-endian by default; big-endian variant also supported
* Full FPU ABI or soft-float ABI is supported, but the * Full FPU ABI or soft-float ABI is supported, but the
single-precision-only FPU ABI is not single-precision-only FPU ABI is not

View File

@ -1 +1 @@
1.2.1 1.2.2

View File

@ -2236,3 +2236,54 @@ arch-specific bugs fixed:
- mips* had negated error codes for some syscalls (kernel bug) - mips* had negated error codes for some syscalls (kernel bug)
- mips* SIGEMT was wrongly called SIGSTKFLT - mips* SIGEMT was wrongly called SIGSTKFLT
- sh fesetround didn't work correctly on sh - sh fesetround didn't work correctly on sh
1.2.2 release notes
major changes:
- child restrictions lifted after fork of multithreaded parent
new features:
- _Fork function (POSIX-future)
- reallocarray function (extension from OpenBSD, now widespread)
- gettid function (kernel tid as supported concept)
- SIGEV_THREAD_ID sigevent API (Linux extension)
- tcgetwinsize and tcsetwinsize functions (POSIX-future)
performance:
- faster software sqrt on archs without native sqrt instruction
compatibility:
- realpath no longer depends on procfs availability & accuracy
- time zone parser now always prefers 64-bit tables if present
- crypt_blowfish now supports $2b$ prefix
- res_query now reports errors via h_errno
- set*id and setrlimit are now safe in vforked/cloned child
- setgroups now applies to all threads
- dlopen debugger notification is improved, should work with lldb
- setrlimit no longer needs __synccall broadcast on linux 2.6.36+
- faccessat with AT_EACCESS no longer needs child process on linux 5.8+
bugs fixed:
- buffer overflow and infinite loop errors in wcsnrtombs (CVE-2020-28928)
- sem_close unmapped still-referenced semaphores
- fork of process with active aio could deadlock or crash paren
- pthread_cond_wait was broken with priority-inheritance mutex
- getgrouplist wrongly failed when nscd reported an empty list
- abort could leak modified SIGABRT disposition to fork or posix_spawn child
- regression with mallocng: malloc_usable_size(0) crashed
- readlink wrongly gave EINVAL on zero length dest buffer
- sqrtl was severely inaccurate (not correctly rounded) on ldquad archs
- assert failure wrongly flushed stdio (possible deadlock)
- MUSL_LOCPATH search was broken with multiple components
- missing newline in herror output
- possible deadlock in pthread_exit with pshared mutex or barrier usage
- pthread_mutexattr_getprotocol didn't read back protocol
- v4l2 ioctl translation for pre-time64 kernels didn't work
arch-specific bugs fixed:
- x86_64 longjmp failed to handle 0 argument reliably
- i386 __set_thread_area fallback for pre-2.6 kernels didn't work
- missing O_LARGEFILE macro value on x86_64, x32, mips64
- unpredictable s390x breakage from failure to preserve call-saved registers

View File

@ -38,3 +38,13 @@
#define HWCAP2_SVEBITPERM (1 << 4) #define HWCAP2_SVEBITPERM (1 << 4)
#define HWCAP2_SVESHA3 (1 << 5) #define HWCAP2_SVESHA3 (1 << 5)
#define HWCAP2_SVESM4 (1 << 6) #define HWCAP2_SVESM4 (1 << 6)
#define HWCAP2_FLAGM2 (1 << 7)
#define HWCAP2_FRINT (1 << 8)
#define HWCAP2_SVEI8MM (1 << 9)
#define HWCAP2_SVEF32MM (1 << 10)
#define HWCAP2_SVEF64MM (1 << 11)
#define HWCAP2_SVEBF16 (1 << 12)
#define HWCAP2_I8MM (1 << 13)
#define HWCAP2_BF16 (1 << 14)
#define HWCAP2_DGH (1 << 15)
#define HWCAP2_RNG (1 << 16)

View File

@ -11,7 +11,7 @@ typedef unsigned long greg_t;
typedef unsigned long gregset_t[34]; typedef unsigned long gregset_t[34];
typedef struct { typedef struct {
long double vregs[32]; __uint128_t vregs[32];
unsigned int fpsr; unsigned int fpsr;
unsigned int fpcr; unsigned int fpcr;
} fpregset_t; } fpregset_t;
@ -34,7 +34,7 @@ struct fpsimd_context {
struct _aarch64_ctx head; struct _aarch64_ctx head;
unsigned int fpsr; unsigned int fpsr;
unsigned int fpcr; unsigned int fpcr;
long double vregs[32]; __uint128_t vregs[32];
}; };
struct esr_context { struct esr_context {
struct _aarch64_ctx head; struct _aarch64_ctx head;

View File

@ -289,4 +289,8 @@
#define __NR_fspick 433 #define __NR_fspick 433
#define __NR_pidfd_open 434 #define __NR_pidfd_open 434
#define __NR_clone3 435 #define __NR_clone3 435
#define __NR_close_range 436
#define __NR_openat2 437
#define __NR_pidfd_getfd 438
#define __NR_faccessat2 439

View File

@ -6,7 +6,7 @@ struct user_regs_struct {
}; };
struct user_fpsimd_struct { struct user_fpsimd_struct {
long double vregs[32]; __uint128_t vregs[32];
unsigned int fpsr; unsigned int fpsr;
unsigned int fpcr; unsigned int fpcr;
}; };

View File

@ -1,12 +1,11 @@
static inline struct pthread *__pthread_self() static inline uintptr_t __get_tp()
{ {
char *self; uintptr_t tp;
__asm__ ("mrs %0,tpidr_el0" : "=r"(self)); __asm__ ("mrs %0,tpidr_el0" : "=r"(tp));
return (void*)(self - sizeof(struct pthread)); return tp;
} }
#define TLS_ABOVE_TP #define TLS_ABOVE_TP
#define GAP_ABOVE_TP 16 #define GAP_ABOVE_TP 16
#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread))
#define MC_PC pc #define MC_PC pc

View File

@ -389,6 +389,10 @@
#define __NR_fspick 433 #define __NR_fspick 433
#define __NR_pidfd_open 434 #define __NR_pidfd_open 434
#define __NR_clone3 435 #define __NR_clone3 435
#define __NR_close_range 436
#define __NR_openat2 437
#define __NR_pidfd_getfd 438
#define __NR_faccessat2 439
#define __ARM_NR_breakpoint 0x0f0001 #define __ARM_NR_breakpoint 0x0f0001
#define __ARM_NR_cacheflush 0x0f0002 #define __ARM_NR_cacheflush 0x0f0002

View File

@ -1,11 +1,11 @@
#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \ #if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
|| __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7 || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
static inline pthread_t __pthread_self() static inline uintptr_t __get_tp()
{ {
char *p; uintptr_t tp;
__asm__ ( "mrc p15,0,%0,c13,c0,3" : "=r"(p) ); __asm__ ( "mrc p15,0,%0,c13,c0,3" : "=r"(tp) );
return (void *)(p-sizeof(struct pthread)); return tp;
} }
#else #else
@ -16,18 +16,17 @@ static inline pthread_t __pthread_self()
#define BLX "blx" #define BLX "blx"
#endif #endif
static inline pthread_t __pthread_self() static inline uintptr_t __get_tp()
{ {
extern hidden uintptr_t __a_gettp_ptr; extern hidden uintptr_t __a_gettp_ptr;
register uintptr_t p __asm__("r0"); register uintptr_t tp __asm__("r0");
__asm__ ( BLX " %1" : "=r"(p) : "r"(__a_gettp_ptr) : "cc", "lr" ); __asm__ ( BLX " %1" : "=r"(tp) : "r"(__a_gettp_ptr) : "cc", "lr" );
return (void *)(p-sizeof(struct pthread)); return tp;
} }
#endif #endif
#define TLS_ABOVE_TP #define TLS_ABOVE_TP
#define GAP_ABOVE_TP 8 #define GAP_ABOVE_TP 8
#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread))
#define MC_PC arm_pc #define MC_PC arm_pc

View File

@ -30,9 +30,15 @@
#define F_SETSIG 10 #define F_SETSIG 10
#define F_GETSIG 11 #define F_GETSIG 11
#if __LONG_MAX == 0x7fffffffL
#define F_GETLK 12 #define F_GETLK 12
#define F_SETLK 13 #define F_SETLK 13
#define F_SETLKW 14 #define F_SETLKW 14
#else
#define F_GETLK 5
#define F_SETLK 6
#define F_SETLKW 7
#endif
#define F_SETOWN_EX 15 #define F_SETOWN_EX 15
#define F_GETOWN_EX 16 #define F_GETOWN_EX 16

View File

@ -426,4 +426,8 @@
#define __NR_fspick 433 #define __NR_fspick 433
#define __NR_pidfd_open 434 #define __NR_pidfd_open 434
#define __NR_clone3 435 #define __NR_clone3 435
#define __NR_close_range 436
#define __NR_openat2 437
#define __NR_pidfd_getfd 438
#define __NR_faccessat2 439

View File

@ -1,10 +1,8 @@
static inline struct pthread *__pthread_self() static inline uintptr_t __get_tp()
{ {
struct pthread *self; uintptr_t tp;
__asm__ ("movl %%gs:0,%0" : "=r" (self) ); __asm__ ("movl %%gs:0,%0" : "=r" (tp) );
return self; return tp;
} }
#define TP_ADJ(p) (p)
#define MC_PC gregs[REG_EIP] #define MC_PC gregs[REG_EIP]

View File

@ -87,5 +87,3 @@ static inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a
#define VDSO_CGT32_VER "LINUX_2.6" #define VDSO_CGT32_VER "LINUX_2.6"
#define VDSO_CGT_SYM "__vdso_clock_gettime64" #define VDSO_CGT_SYM "__vdso_clock_gettime64"
#define VDSO_CGT_VER "LINUX_2.6" #define VDSO_CGT_VER "LINUX_2.6"
#define SYSCALL_USE_SOCKETCALL

View File

@ -405,3 +405,8 @@
#define __NR_fsmount 432 #define __NR_fsmount 432
#define __NR_fspick 433 #define __NR_fspick 433
#define __NR_pidfd_open 434 #define __NR_pidfd_open 434
#define __NR_clone3 435
#define __NR_close_range 436
#define __NR_openat2 437
#define __NR_pidfd_getfd 438
#define __NR_faccessat2 439

View File

@ -1,13 +1,12 @@
static inline struct pthread *__pthread_self() static inline uintptr_t __get_tp()
{ {
uintptr_t tp = __syscall(SYS_get_thread_area); return __syscall(SYS_get_thread_area);
return (pthread_t)(tp - 0x7000 - sizeof(struct pthread));
} }
#define TLS_ABOVE_TP #define TLS_ABOVE_TP
#define GAP_ABOVE_TP 0 #define GAP_ABOVE_TP 0
#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
#define TP_OFFSET 0x7000
#define DTP_OFFSET 0x8000 #define DTP_OFFSET 0x8000
#define MC_PC gregs[R_PC] #define MC_PC gregs[R_PC]

View File

@ -87,5 +87,4 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo
return d0; return d0;
} }
#define SYSCALL_USE_SOCKETCALL
#define SYSCALL_IPC_BROKEN_MODE #define SYSCALL_IPC_BROKEN_MODE

View File

@ -427,4 +427,8 @@
#define __NR_fspick 433 #define __NR_fspick 433
#define __NR_pidfd_open 434 #define __NR_pidfd_open 434
#define __NR_clone3 435 #define __NR_clone3 435
#define __NR_close_range 436
#define __NR_openat2 437
#define __NR_pidfd_getfd 438
#define __NR_faccessat2 439

View File

@ -1,10 +1,8 @@
static inline struct pthread *__pthread_self() static inline uintptr_t __get_tp()
{ {
struct pthread *self; uintptr_t tp;
__asm__ ("ori %0, r21, 0" : "=r" (self) ); __asm__ ("ori %0, r21, 0" : "=r" (tp) );
return self; return tp;
} }
#define TP_ADJ(p) (p)
#define MC_PC regs.pc #define MC_PC regs.pc

View File

@ -95,3 +95,5 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo
} }
#define SYSCALL_IPC_BROKEN_MODE #define SYSCALL_IPC_BROKEN_MODE
#undef SYS_socketcall

View File

@ -408,4 +408,8 @@
#define __NR_fspick 4433 #define __NR_fspick 4433
#define __NR_pidfd_open 4434 #define __NR_pidfd_open 4434
#define __NR_clone3 4435 #define __NR_clone3 4435
#define __NR_close_range 4436
#define __NR_openat2 4437
#define __NR_pidfd_getfd 4438
#define __NR_faccessat2 4439

View File

@ -1,19 +1,19 @@
static inline struct pthread *__pthread_self() static inline uintptr_t __get_tp()
{ {
#if __mips_isa_rev < 2 #if __mips_isa_rev < 2
register char *tp __asm__("$3"); register uintptr_t tp __asm__("$3");
__asm__ (".word 0x7c03e83b" : "=r" (tp) ); __asm__ (".word 0x7c03e83b" : "=r" (tp) );
#else #else
char *tp; uintptr_t tp;
__asm__ ("rdhwr %0, $29" : "=r" (tp) ); __asm__ ("rdhwr %0, $29" : "=r" (tp) );
#endif #endif
return (pthread_t)(tp - 0x7000 - sizeof(struct pthread)); return tp;
} }
#define TLS_ABOVE_TP #define TLS_ABOVE_TP
#define GAP_ABOVE_TP 0 #define GAP_ABOVE_TP 0
#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
#define TP_OFFSET 0x7000
#define DTP_OFFSET 0x8000 #define DTP_OFFSET 0x8000
#define MC_PC pc #define MC_PC pc

View File

@ -149,3 +149,5 @@ static inline long __syscall7(long n, long a, long b, long c, long d, long e, lo
#define SO_SNDTIMEO_OLD 0x1005 #define SO_SNDTIMEO_OLD 0x1005
#define SO_RCVTIMEO_OLD 0x1006 #define SO_RCVTIMEO_OLD 0x1006
#undef SYS_socketcall

Some files were not shown because too many files have changed in this diff Show More