diff --git a/.github/actions/apt-wasi/action.yml b/.github/actions/apt-wasi/action.yml new file mode 100644 index 0000000000000..1e664d6cfd53e --- /dev/null +++ b/.github/actions/apt-wasi/action.yml @@ -0,0 +1,48 @@ +name: apt +inputs: + wasi_sdk_version: + default: 19 + wasmtime_version: + default: 5.0.0 + binaryen_version: + default: 111 +runs: + using: composite + steps: + - shell: bash + run: | + set -x + + sudo apt-get update + sudo apt-get install \ + php \ + libtool-bin \ + bison \ + re2c \ + tcl + - shell: bash + run: | + set -x + + wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${{ inputs.wasi_sdk_version }}/wasi-sdk_${{ inputs.wasi_sdk_version }}.0_amd64.deb + sudo dpkg -i wasi-sdk_${{ inputs.wasi_sdk_version }}.0_amd64.deb + - shell: bash + run: | + echo /opt/wasi-sdk/bin >> $GITHUB_PATH + - shell: bash + run: | + set -x + + mkdir -p /opt/bin + + wget https://github.com/bytecodealliance/wasmtime/releases/download/v${{ inputs.wasmtime_version }}/wasmtime-v${{ inputs.wasmtime_version }}-x86_64-linux.tar.xz + tar -xvf wasmtime-v${{ inputs.wasmtime_version }}-x86_64-linux.tar.xz + mv wasmtime-v${{ inputs.wasmtime_version }}-x86_64-linux/wasmtime /opt/bin/ + - shell: bash + run: | + set -x + + mkdir -p /opt/bin + + wget https://github.com/WebAssembly/binaryen/releases/download/version_${{ inputs.binaryen_version }}/binaryen-version_${{ inputs.binaryen_version }}-x86_64-linux.tar.gz + tar -xvf binaryen-version_${{ inputs.binaryen_version }}-x86_64-linux.tar.gz --strip-components=2 -C /opt/bin binaryen-version_${{ inputs.binaryen_version }}/bin/wasm-opt diff --git a/.github/actions/configure-wasi/action.yml b/.github/actions/configure-wasi/action.yml new file mode 100644 index 0000000000000..8b450f4b5f34c --- /dev/null +++ b/.github/actions/configure-wasi/action.yml @@ -0,0 +1,48 @@ +name: ./configure +inputs: + configurationParameters: + default: '' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + + ./buildconf --force + ./configure \ + --host=wasm32-wasi host_alias=wasm32-musl-wasi \ + --target=wasm32-wasi target_alias=wasm32-musl-wasi \ + --disable-all \ + --disable-ctype \ + --disable-dom \ + --disable-fiber-asm \ + --disable-fileinfo \ + --disable-filter \ + --disable-flatfile \ + --disable-huge-code-pages \ + --disable-inifile \ + --disable-mbregex \ + --disable-mysqlnd-compression-support \ + --disable-opcache \ + --disable-opcache-jit \ + --disable-pdo \ + --disable-phar \ + --disable-posix \ + --disable-session \ + --disable-simplexml \ + --disable-tokenizer \ + --disable-xml \ + --disable-xmlreader \ + --disable-xmlwriter \ + --disable-zend-signals \ + --without-cdb \ + --without-libxml \ + --without-openssl \ + --without-pcre-jit \ + --without-pear \ + --without-sqlite3 \ + CFLAGS="-D_WASI_EMULATED_GETPID -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_PROCESS_CLOCKS" \ + LDFLAGS="-lwasi-emulated-getpid -lwasi-emulated-signal -lwasi-emulated-process-clocks" \ + ${{ inputs.configurationParameters }} diff --git a/.github/actions/optimize-wasi/action.yml b/.github/actions/optimize-wasi/action.yml new file mode 100644 index 0000000000000..30e7ad2ac2bd0 --- /dev/null +++ b/.github/actions/optimize-wasi/action.yml @@ -0,0 +1,14 @@ +name: Optimize +runs: + using: composite + steps: + - shell: bash + run: | + set -x + + /opt/bin/wasm-opt -O sapi/cli/php -o sapi/cli/php.optimized + - shell: bash + run: | + set -x + + /opt/bin/wasm-opt -O sapi/cgi/php-cgi -o sapi/cgi/php-cgi.optimized diff --git a/.github/actions/test-wasi/action.yml b/.github/actions/test-wasi/action.yml new file mode 100644 index 0000000000000..7882fecceaa99 --- /dev/null +++ b/.github/actions/test-wasi/action.yml @@ -0,0 +1,46 @@ +name: Test +inputs: + testArtifacts: + default: null + required: false + runTestsParameters: + default: '' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + cat <<-'EOF' > /opt/bin/wasmtime-run-cli.sh + #!/bin/bash + WASMTIME_BACKTRACE_DETAILS=1 /opt/bin/wasmtime run --mapdir /::/ "$PWD/sapi/cli/php.optimized" 2> /dev/null -- "$@" + EOF + chmod +x /opt/bin/wasmtime-run-cli.sh + cat <<-'EOF' > /opt/bin/wasmtime-run-cgi.sh + #!/bin/bash + WASMTIME_BACKTRACE_DETAILS=1 /opt/bin/wasmtime run --mapdir /::/ "$PWD/sapi/cgi/php-cgi.optimized" 2> /dev/null -- "$@" + EOF + chmod +x /opt/bin/wasmtime-run-cgi.sh + - shell: bash + run: | + set -x + export SKIP_IO_CAPTURE_TESTS=1 + export TEST_PHP_JUNIT=junit.out.xml + export STACK_LIMIT_DEFAULTS_CHECK=1 + export TEST_PHP_EXECUTABLE=/opt/bin/wasmtime-run-cli.sh + export TEST_PHP_CGI_EXECUTABLE=/opt/bin/wasmtime-run-cgi.sh + export TEST_PHPDBG_EXECUTABLE="" + php run-tests.php -q ${{ inputs.runTestsParameters }} \ + -j$(/usr/bin/nproc) \ + -g FAIL,BORK,LEAK,XLEAK \ + --no-progress \ + --offline \ + --show-diff \ + --show-slow 1000 \ + --set-timeout 120 + - uses: actions/upload-artifact@v3 + if: always() && inputs.testArtifacts != null + with: + name: ${{ github.job }}_${{ inputs.testArtifacts }} + path: ${{ github.workspace }}/junit.out.xml + retention-days: 5 diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 35519428a166e..d8134d1b27140 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -312,3 +312,37 @@ jobs: ${{ github.sha }} \ $(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.sha }}) \ > $GITHUB_STEP_SUMMARY + WASM32_WASI: + name: "WASM32_WASI_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" + runs-on: ubuntu-20.04 + env: + CC: clang + CXX: clang++ + LD: wasm-ld + AR: llvm-ar + RANLIB: llvm-ranlib + steps: + - name: git checkout + uses: actions/checkout@v3 + - name: apt + uses: ./.github/actions/apt-wasi + - name: ./configure + uses: ./.github/actions/configure-wasi + with: + configurationParameters: >- + --${{ matrix.debug && 'enable' || 'disable' }}-debug + --${{ matrix.zts && 'enable' || 'disable' }}-zts + - name: make + env: + CFLAGS: "-D_WASI_EMULATED_GETPID -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_PROCESS_CLOCKS" + LDFLAGS: "-lwasi-emulated-getpid -lwasi-emulated-signal -lwasi-emulated-process-clocks" + run: make -j$(/usr/bin/nproc) cgi cli + - name: Optimize + uses: ./.github/actions/optimize-wasi + # To be defined how to approach test coverage on this platform. + # - name: Test + # uses: ./.github/actions/test-wasi + # with: + # testArtifacts: ${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }} + # - name: Verify generated files are up to date + # uses: ./.github/actions/verify-generated-files diff --git a/Zend/Optimizer/zend_func_infos.h b/Zend/Optimizer/zend_func_infos.h index a77ec0a49f7bb..7c785a9902f4d 100644 --- a/Zend/Optimizer/zend_func_infos.h +++ b/Zend/Optimizer/zend_func_infos.h @@ -512,13 +512,19 @@ static const func_info_t func_infos[] = { #if defined(HAVE_STRPTIME) F1("strptime", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE), #endif -#if defined(HAVE_GETHOSTNAME) +#if !defined(PHP_WASI) && defined(HAVE_GETHOSTNAME) F1("gethostname", MAY_BE_STRING|MAY_BE_FALSE), #endif +#if !defined(PHP_WASI) F1("gethostbyaddr", MAY_BE_STRING|MAY_BE_FALSE), +#endif +#if !defined(PHP_WASI) F1("gethostbyname", MAY_BE_STRING), +#endif +#if !defined(PHP_WASI) F1("gethostbynamel", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE), -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#endif +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) F1("dns_get_record", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE), #endif F1("md5", MAY_BE_STRING), diff --git a/Zend/zend.c b/Zend/zend.c index ee3f5272c9640..b8259623a35d5 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -788,7 +788,9 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{ #endif executor_globals->saved_fpu_cw_ptr = NULL; executor_globals->active = 0; +#ifndef PHP_WASI executor_globals->bailout = NULL; +#endif // PHP_WASI executor_globals->error_handling = EH_NORMAL; executor_globals->exception_class = NULL; executor_globals->exception = NULL; @@ -1179,6 +1181,7 @@ ZEND_COLD void zenderror(const char *error) /* {{{ */ } /* }}} */ +#ifndef PHP_WASI ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32_t lineno) /* {{{ */ { @@ -1195,6 +1198,7 @@ ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32 LONGJMP(*EG(bailout), FAILURE); } /* }}} */ +#endif // PHP_WASI ZEND_API size_t zend_get_page_size(void) { diff --git a/Zend/zend.h b/Zend/zend.h index 94440530f3b36..12c33e3d76ebf 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -76,6 +76,11 @@ TSRMLS_MAIN_CACHE_EXTERN() ZEND_TSRMLS_CACHE_EXTERN() #endif +#undef PHP_WASI +#ifdef __wasi__ +#define PHP_WASI __wasi__ +#endif + struct _zend_serialize_data; struct _zend_unserialize_data; @@ -257,6 +262,7 @@ typedef size_t (*zend_write_func_t)(const char *str, size_t str_length); #define zend_bailout() _zend_bailout(__FILE__, __LINE__) +#ifndef PHP_WASI #define zend_try \ { \ JMP_BUF *__orig_bailout = EG(bailout); \ @@ -273,6 +279,19 @@ typedef size_t (*zend_write_func_t)(const char *str, size_t str_length); } #define zend_first_try EG(bailout)=NULL; zend_try +#else // PHP_WASI +#define zend_try \ + { \ + if (1) { +#define zend_catch \ + } else { +#define zend_end_try() \ + } \ + } +#define zend_first_try zend_try +#endif // PHP_WASI + + BEGIN_EXTERN_C() void zend_startup(zend_utility_functions *utility_functions); void zend_shutdown(void); diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 7335baf849d5e..118897c90708a 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -80,7 +80,7 @@ #include #include -#ifndef _WIN32 +#if !defined(_WIN32) && defined(HAVE_MMAP) # include # ifndef MAP_ANON # ifdef MAP_ANONYMOUS @@ -444,6 +444,8 @@ static void zend_mm_munmap(void *addr, size_t size) #endif } } +#elif !defined(_WIN32) && !defined(HAVE_MMAP) + free(addr); #else if (munmap(addr, size) != 0) { #if ZEND_MM_ERROR @@ -471,7 +473,7 @@ static void *zend_mm_mmap_fixed(void *addr, size_t size) } ZEND_ASSERT(ptr == addr); return ptr; -#else +#elif defined(HAVE_MMAP) int flags = MAP_PRIVATE | MAP_ANON; #if defined(MAP_EXCL) flags |= MAP_FIXED | MAP_EXCL; @@ -491,6 +493,8 @@ static void *zend_mm_mmap_fixed(void *addr, size_t size) return NULL; } return ptr; +#else + return NULL; #endif } #endif @@ -507,6 +511,10 @@ static void *zend_mm_mmap(size_t size) return NULL; } return ptr; +#elif !defined(HAVE_MMAP) + void* ptr = malloc(size); + memset(ptr, 0, size); + return ptr; #else void *ptr; @@ -716,6 +724,7 @@ static zend_always_inline void zend_mm_hugepage(void* ptr, size_t size) static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment) { +#if defined(_WIN32) || defined(HAVE_MMAP) // defined(_WIN32) || defined(HAVE_MMAP) void *ptr = zend_mm_mmap(size); if (ptr == NULL) { @@ -766,6 +775,11 @@ static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment) #endif return ptr; } +#else // defined(_WIN32) || defined(HAVE_MMAP) + void* ptr = aligned_alloc(alignment, size); + memset(ptr, 0, size); + return ptr; +#endif // defined(_WIN32) || defined(HAVE_MMAP) } static void *zend_mm_chunk_alloc(zend_mm_heap *heap, size_t size, size_t alignment) @@ -2934,7 +2948,7 @@ ZEND_API void start_memory_manager(void) #else alloc_globals_ctor(&alloc_globals); #endif -#ifndef _WIN32 +#if !defined(_WIN32) && defined(HAVE_MMAP) # if defined(_SC_PAGESIZE) REAL_PAGE_SIZE = sysconf(_SC_PAGESIZE); # elif defined(_SC_PAGE_SIZE) diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c index a43ed60dcd9b8..5d9602cd49c0b 100644 --- a/Zend/zend_fibers.c +++ b/Zend/zend_fibers.c @@ -39,7 +39,7 @@ # include #endif -#ifndef ZEND_WIN32 +#if !defined(ZEND_WIN32) && defined(HAVE_MMAP) # include # include # include @@ -108,7 +108,9 @@ typedef struct _zend_fiber_vm_state { zend_execute_data *current_execute_data; int error_reporting; uint32_t jit_trace_num; +#ifndef PHP_WASI JMP_BUF *bailout; +#endif // PHP_WASI zend_fiber *active_fiber; #ifdef ZEND_CHECK_STACK_LIMIT void *stack_base; @@ -125,7 +127,9 @@ static zend_always_inline void zend_fiber_capture_vm_state(zend_fiber_vm_state * state->current_execute_data = EG(current_execute_data); state->error_reporting = EG(error_reporting); state->jit_trace_num = EG(jit_trace_num); +#ifndef PHP_WASI state->bailout = EG(bailout); +#endif // PHP_WASI state->active_fiber = EG(active_fiber); #ifdef ZEND_CHECK_STACK_LIMIT state->stack_base = EG(stack_base); @@ -142,7 +146,9 @@ static zend_always_inline void zend_fiber_restore_vm_state(zend_fiber_vm_state * EG(current_execute_data) = state->current_execute_data; EG(error_reporting) = state->error_reporting; EG(jit_trace_num) = state->jit_trace_num; +#ifndef PHP_WASI EG(bailout) = state->bailout; +#endif // PHP_WASI EG(active_fiber) = state->active_fiber; #ifdef ZEND_CHECK_STACK_LIMIT EG(stack_base) = state->stack_base; @@ -236,6 +242,8 @@ static zend_fiber_stack *zend_fiber_stack_allocate(size_t size) return NULL; } # endif +#elif defined(PHP_WASI) + pointer = malloc(alloc_size); #else pointer = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); @@ -302,6 +310,8 @@ static void zend_fiber_stack_free(zend_fiber_stack *stack) #ifdef ZEND_WIN32 VirtualFree(pointer, 0, MEM_RELEASE); +#elif defined(PHP_WASI) + free(pointer); #else munmap(pointer, stack->size + ZEND_FIBER_GUARD_PAGES * page_size); #endif @@ -394,6 +404,7 @@ ZEND_API bool zend_fiber_switch_blocked(void) return zend_fiber_switch_blocking; } +#ifndef PHP_WASI ZEND_API zend_result zend_fiber_init_context(zend_fiber_context *context, void *kind, zend_fiber_coroutine coroutine, size_t stack_size) { context->stack = zend_fiber_stack_allocate(stack_size); @@ -440,6 +451,7 @@ ZEND_API zend_result zend_fiber_init_context(zend_fiber_context *context, void * return SUCCESS; } +#endif // PHP_WASI ZEND_API void zend_fiber_destroy_context(zend_fiber_context *context) { @@ -502,16 +514,18 @@ ZEND_API void zend_fiber_switch_context(zend_fiber_transfer *transfer) /* Copy transfer struct because it might live on the other fiber's stack that will eventually be destroyed. */ *transfer = *transfer_data; -#else +#elif !defined(PHP_WASI) boost_context_data data = jump_fcontext(to->handle, transfer); /* Copy transfer struct because it might live on the other fiber's stack that will eventually be destroyed. */ *transfer = *data.transfer; +#else + return; #endif to = transfer->context; -#ifndef ZEND_FIBER_UCONTEXT +#if !defined(ZEND_FIBER_UCONTEXT) && !defined(PHP_WASI) /* Get the context that resumed us and update its handle to allow for symmetric coroutines. */ to->handle = data.handle; #endif diff --git a/Zend/zend_fibers_wasi.c b/Zend/zend_fibers_wasi.c new file mode 100644 index 0000000000000..30942633aac70 --- /dev/null +++ b/Zend/zend_fibers_wasi.c @@ -0,0 +1,24 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "zend_fibers.h" + +ZEND_API zend_result zend_fiber_init_context(zend_fiber_context *context, void *kind, zend_fiber_coroutine coroutine, size_t stack_size) +{ + zend_throw_exception(NULL, "Fibers are not supported yet on this platform (wasm32-wasi)", 0); + return FAILURE; +} diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 8900a5f416f53..69a7397c2a14f 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -21,7 +21,10 @@ #define ZEND_GLOBALS_H +#ifndef PHP_WASI #include +#endif + #include #include @@ -174,7 +177,9 @@ struct _zend_executor_globals { HashTable included_files; /* files already included */ +#ifndef PHP_WASI JMP_BUF *bailout; +#endif int error_reporting; int exit_status; diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index 6bff2ad984d02..e152e8527d0db 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -1378,6 +1378,7 @@ CWD_API int virtual_utime(const char *filename, struct utimbuf *buf) /* {{{ */ /* }}} */ #endif +#ifndef PHP_WASI CWD_API int virtual_chmod(const char *filename, mode_t mode) /* {{{ */ { cwd_state new_state; @@ -1411,8 +1412,9 @@ CWD_API int virtual_chmod(const char *filename, mode_t mode) /* {{{ */ return ret; } /* }}} */ +#endif -#if !defined(ZEND_WIN32) +#if !defined(ZEND_WIN32) && !defined(PHP_WASI) CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link) /* {{{ */ { cwd_state new_state; @@ -1659,7 +1661,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type) /* {{{ */ return popen_ex(command, type, CWDG(cwd).cwd, NULL); } /* }}} */ -#else /* Unix */ +#elif !defined(PHP_WASI) /* Unix */ CWD_API FILE *virtual_popen(const char *command, const char *type) /* {{{ */ { size_t command_length; diff --git a/Zend/zend_virtual_cwd_wasi.c b/Zend/zend_virtual_cwd_wasi.c new file mode 100644 index 0000000000000..576b9aadf5698 --- /dev/null +++ b/Zend/zend_virtual_cwd_wasi.c @@ -0,0 +1,34 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "zend_virtual_cwd.h" + +CWD_API int virtual_chmod(const char *filename, mode_t mode) /* {{{ */ +{ + return -1; +} +/* }}} */ + +CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link) /* {{{ */ +{ + return -1; +} +/* }}} */ + +CWD_API FILE *virtual_popen(const char *command, const char *type) /* {{{ */ +{ + return NULL; +} +/* }}} */ diff --git a/Zend/zend_wasi.c b/Zend/zend_wasi.c new file mode 100644 index 0000000000000..ec5c6f901bc5a --- /dev/null +++ b/Zend/zend_wasi.c @@ -0,0 +1,26 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" + +ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, + uint32_t lineno) /* {{{ */ +{ + // Not implemented yet, as WebAssembly has no stack switching + // feature implementation at this point. + zend_throw_exception(NULL, "Exception bailout is not supported yet on this platform (wasm32-wasi)", 0); +} +/* }}} */ diff --git a/build/ax_check_define.m4 b/build/ax_check_define.m4 new file mode 100644 index 0000000000000..c10d1137aee49 --- /dev/null +++ b/build/ax_check_define.m4 @@ -0,0 +1,73 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_define.html +# =========================================================================== +# +# SYNOPSIS +# +# AC_CHECK_DEFINE([symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT]) +# AX_CHECK_DEFINE([includes],[symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT]) +# +# DESCRIPTION +# +# Complements AC_CHECK_FUNC but it does not check for a function but for a +# define to exist. Consider a usage like: +# +# AC_CHECK_DEFINE(__STRICT_ANSI__, CFLAGS="$CFLAGS -D_XOPEN_SOURCE=500") +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 11 + +AU_ALIAS([AC_CHECK_DEFINED], [AC_CHECK_DEFINE]) +AC_DEFUN([AC_CHECK_DEFINE],[ +AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$1])dnl +AC_CACHE_CHECK([for $1 defined], ac_var, +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ + #ifdef $1 + int ok; + (void)ok; + #else + choke me + #endif +]])],[AS_VAR_SET(ac_var, yes)],[AS_VAR_SET(ac_var, no)])) +AS_IF([test AS_VAR_GET(ac_var) != "no"], [$2], [$3])dnl +AS_VAR_POPDEF([ac_var])dnl +]) + +AU_ALIAS([AX_CHECK_DEFINED], [AX_CHECK_DEFINE]) +AC_DEFUN([AX_CHECK_DEFINE],[ +AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$2_$1])dnl +AC_CACHE_CHECK([for $2 defined in $1], ac_var, +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <$1>]], [[ + #ifdef $2 + int ok; + (void)ok; + #else + choke me + #endif +]])],[AS_VAR_SET(ac_var, yes)],[AS_VAR_SET(ac_var, no)])) +AS_IF([test AS_VAR_GET(ac_var) != "no"], [$3], [$4])dnl +AS_VAR_POPDEF([ac_var])dnl +]) + +AC_DEFUN([AX_CHECK_FUNC], +[AS_VAR_PUSHDEF([ac_var], [ac_cv_func_$2])dnl +AC_CACHE_CHECK([for $2], ac_var, +dnl AC_LANG_FUNC_LINK_TRY +[AC_LINK_IFELSE([AC_LANG_PROGRAM([$1 + #undef $2 + char $2 ();],[ + char (*f) () = $2; + return f != $2; ])], + [AS_VAR_SET(ac_var, yes)], + [AS_VAR_SET(ac_var, no)])]) +AS_IF([test AS_VAR_GET(ac_var) = yes], [$3], [$4])dnl +AS_VAR_POPDEF([ac_var])dnl +])# AC_CHECK_FUNC diff --git a/configure.ac b/configure.ac index 7445f930d6023..1c4e1b412c24e 100644 --- a/configure.ac +++ b/configure.ac @@ -4,6 +4,7 @@ dnl Include external macro definitions before the AC_INIT to also remove dnl comments starting with # and empty newlines from the included files. dnl ---------------------------------------------------------------------------- m4_include([build/ax_check_compile_flag.m4]) +m4_include([build/ax_check_define.m4]) m4_include([build/ax_func_which_gethostbyname_r.m4]) m4_include([build/ax_gcc_func_attribute.m4]) m4_include([build/libtool.m4]) @@ -274,6 +275,11 @@ if test "$ac_cv_safe_to_define___extensions__" = yes ; then AC_MSG_RESULT(yes) fi +dnl wasm32-wasi builds with a specific execution model named "command" +if test "$WASI" = "yes"; then + CPPFLAGS="$CPPFLAGS -mexec-model=command -Wl,--gc-sections" +fi + dnl Include Zend configurations. dnl ---------------------------------------------------------------------------- @@ -477,6 +483,8 @@ PHP_MISSING_TIME_R_DECL PHP_MISSING_FCLOSE_DECL PHP_STRUCT_FLOCK +AC_CHECK_DEFINE([__wasi__], [WASI="yes"], []) + AC_CHECK_TYPES(socklen_t, [], [], [ #ifdef HAVE_SYS_TYPES_H # include @@ -1351,11 +1359,13 @@ else if test "$fiber_os" = 'mac'; then AC_DEFINE([_XOPEN_SOURCE], 1, [ ]) fi - AC_CHECK_HEADER(ucontext.h, [ - AC_DEFINE([ZEND_FIBER_UCONTEXT], 1, [ ]) - ], [ - AC_MSG_ERROR([fibers not available on this platform]) - ]) + if test "$WASI" != "yes"; then + AC_CHECK_HEADER(ucontext.h, [ + AC_DEFINE([ZEND_FIBER_UCONTEXT], 1, [ ]) + ], [ + AC_MSG_ERROR([fibers not available on this platform]) + ]) + fi fi LIBZEND_BASIC_CHECKS @@ -1707,15 +1717,24 @@ PHP_ADD_SOURCES(main, main.c snprintf.c spprintf.c \ php_ini_builder.c \ php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ strlcat.c explicit_bzero.c reentrancy.c php_variables.c php_ticks.c \ - network.c php_open_temporary_file.c php_odbc_utils.c safe_bcmp.c \ - output.c getopt.c php_syslog.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) + php_open_temporary_file.c php_odbc_utils.c safe_bcmp.c \ + output.c getopt.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) -PHP_ADD_SOURCES_X(main, fastcgi.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, PHP_FASTCGI_OBJS, no) +if test "$WASI" = "yes"; then + PHP_ADD_SOURCES(main, fastcgi_wasi.c network_wasi.c php_open_temporary_file_wasi.c unistd_wasi.c,) +else + PHP_ADD_SOURCES(main, php_syslog.c network.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) + PHP_ADD_SOURCES_X(main, fastcgi.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, PHP_FASTCGI_OBJS, no) +fi PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \ - plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c \ + plain_wrapper.c userspace.c transports.c mmap.c \ glob_wrapper.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) +if test "$WASI" != "yes"; then + PHP_ADD_SOURCES(main/streams, xp_socket.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) +fi + PHP_ADD_SOURCES(/main, internal_functions.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, sapi) PHP_ADD_SOURCES_X(/main, internal_functions_cli.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, PHP_BINARY_OBJS) @@ -1757,6 +1776,10 @@ PHP_ADD_SOURCES(Zend, \ Optimizer/zend_dump.c \ , -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) +if test "$WASI" = "yes"; then + PHP_ADD_SOURCES(Zend, zend_wasi.c zend_fibers_wasi.c zend_virtual_cwd_wasi.c,) +fi + PHP_ADD_BUILD_DIR(main main/streams) PHP_ADD_BUILD_DIR(TSRM) PHP_ADD_BUILD_DIR(Zend Zend/asm Zend/Optimizer) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 1c84ddcc98947..97b0ee87eeaa4 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -66,9 +66,9 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; #include #endif -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) # include -#else +#elif defined(PHP_WIN32) #include "win32/inet.h" #endif @@ -349,8 +349,10 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ php_register_url_stream_wrapper("glob", &php_glob_stream_wrapper); #endif php_register_url_stream_wrapper("data", &php_stream_rfc2397_wrapper); +#ifndef PHP_WASI php_register_url_stream_wrapper("http", &php_stream_http_wrapper); php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper); +#endif // PHP_WASI BASIC_MINIT_SUBMODULE(hrtime) @@ -1427,7 +1429,11 @@ PHPAPI int _php_error_log_ex(int opt_err, const char *message, size_t message_le break; default: +#ifdef HAVE_SYSLOG_H php_log_err_with_severity(message, LOG_NOTICE); +#else + php_log_err_with_severity(message, 5); +#endif break; } return SUCCESS; @@ -2382,7 +2388,7 @@ PHP_FUNCTION(move_uploaded_file) size_t path_len, new_path_len; bool successful = 0; -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) int oldmask; int ret; #endif @@ -2405,7 +2411,7 @@ PHP_FUNCTION(move_uploaded_file) if (VCWD_RENAME(path, new_path) == 0) { successful = 1; -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) oldmask = umask(077); umask(oldmask); diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 9ce2224a78292..3497aa8261921 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -739,6 +739,7 @@ /* error levels */ +#ifndef PHP_WASI /** * system unusable * @var int @@ -933,6 +934,7 @@ */ const LOG_PERROR = UNKNOWN; #endif +#endif /* string.c */ @@ -2103,6 +2105,8 @@ function strptime(string $timestamp, string $format): array|false {} /* dns.c */ +#ifndef PHP_WASI + #ifdef HAVE_GETHOSTNAME /** @refcount 1 */ function gethostname(): string|false {} @@ -2148,6 +2152,8 @@ function dns_get_mx(string $hostname, &$hosts, &$weights = null): bool {} function getmxrr(string $hostname, &$hosts, &$weights = null): bool {} #endif +#endif + /* net.c */ #if (defined(PHP_WIN32) || HAVE_GETIFADDRS || defined(__PASE__)) diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 1fb54cd02d8ef..6aed40956b39d 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: b0767630614e040866bd7ffdaf50dd31298a64f3 */ + * Stub hash: 3ac35fd4af803d1fd3796c2c36ea61f2bff040ae */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -610,35 +610,41 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strptime, 0, 2, MAY_BE_ARRAY|MAY ZEND_END_ARG_INFO() #endif -#if defined(HAVE_GETHOSTNAME) +#if !defined(PHP_WASI) && defined(HAVE_GETHOSTNAME) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_gethostname, 0, 0, MAY_BE_STRING|MAY_BE_FALSE) ZEND_END_ARG_INFO() #endif +#if !defined(PHP_WASI) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_gethostbyaddr, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, ip, IS_STRING, 0) ZEND_END_ARG_INFO() +#endif +#if !defined(PHP_WASI) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gethostbyname, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0) ZEND_END_ARG_INFO() +#endif +#if !defined(PHP_WASI) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_gethostbynamel, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0) ZEND_END_ARG_INFO() +#endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dns_check_record, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_STRING, 0, "\"MX\"") ZEND_END_ARG_INFO() #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) #define arginfo_checkdnsrr arginfo_dns_check_record #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_dns_get_record, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_LONG, 0, "DNS_ANY") @@ -648,7 +654,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_dns_get_record, 0, 1, MAY_BE_ARR ZEND_END_ARG_INFO() #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dns_get_mx, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0) ZEND_ARG_INFO(1, hosts) @@ -656,7 +662,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dns_get_mx, 0, 2, _IS_BOOL, 0) ZEND_END_ARG_INFO() #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) #define arginfo_getmxrr arginfo_dns_get_mx #endif @@ -2369,19 +2375,25 @@ ZEND_FUNCTION(crypt); #if defined(HAVE_STRPTIME) ZEND_FUNCTION(strptime); #endif -#if defined(HAVE_GETHOSTNAME) +#if !defined(PHP_WASI) && defined(HAVE_GETHOSTNAME) ZEND_FUNCTION(gethostname); #endif +#if !defined(PHP_WASI) ZEND_FUNCTION(gethostbyaddr); +#endif +#if !defined(PHP_WASI) ZEND_FUNCTION(gethostbyname); +#endif +#if !defined(PHP_WASI) ZEND_FUNCTION(gethostbynamel); -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#endif +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FUNCTION(dns_check_record); #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FUNCTION(dns_get_record); #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FUNCTION(dns_get_mx); #endif #if (defined(PHP_WIN32) || HAVE_GETIFADDRS || defined(__PASE__)) @@ -2995,25 +3007,31 @@ static const zend_function_entry ext_functions[] = { #if defined(HAVE_STRPTIME) ZEND_DEP_FE(strptime, arginfo_strptime) #endif -#if defined(HAVE_GETHOSTNAME) +#if !defined(PHP_WASI) && defined(HAVE_GETHOSTNAME) ZEND_FE(gethostname, arginfo_gethostname) #endif +#if !defined(PHP_WASI) ZEND_FE(gethostbyaddr, arginfo_gethostbyaddr) +#endif +#if !defined(PHP_WASI) ZEND_FE(gethostbyname, arginfo_gethostbyname) +#endif +#if !defined(PHP_WASI) ZEND_FE(gethostbynamel, arginfo_gethostbynamel) -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#endif +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FE(dns_check_record, arginfo_dns_check_record) #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FALIAS(checkdnsrr, dns_check_record, arginfo_checkdnsrr) #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FE(dns_get_record, arginfo_dns_get_record) #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FE(dns_get_mx, arginfo_dns_get_mx) #endif -#if (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) +#if !defined(PHP_WASI) && (defined(PHP_WIN32) || defined(HAVE_DNS_SEARCH_FUNC)) ZEND_FALIAS(getmxrr, dns_get_mx, arginfo_getmxrr) #endif #if (defined(PHP_WIN32) || HAVE_GETIFADDRS || defined(__PASE__)) @@ -3669,65 +3687,103 @@ static void register_basic_functions_symbols(int module_number) REGISTER_LONG_CONSTANT("CREDITS_FULLPAGE", PHP_CREDITS_FULLPAGE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CREDITS_QA", PHP_CREDITS_QA, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CREDITS_ALL", PHP_CREDITS_ALL, CONST_PERSISTENT); +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_PERSISTENT); -#if defined(LOG_NEWS) +#endif +#if !defined(PHP_WASI) && defined(LOG_NEWS) REGISTER_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_PERSISTENT); #endif -#if defined(LOG_UUCP) +#if !defined(PHP_WASI) && defined(LOG_UUCP) REGISTER_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_PERSISTENT); #endif -#if defined(LOG_CRON) +#if !defined(PHP_WASI) && defined(LOG_CRON) REGISTER_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_PERSISTENT); #endif -#if defined(LOG_AUTHPRIV) +#if !defined(PHP_WASI) && defined(LOG_AUTHPRIV) REGISTER_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_PERSISTENT); #endif -#if !defined(PHP_WIN32) +#if !defined(PHP_WASI) && !defined(PHP_WIN32) REGISTER_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_PERSISTENT); #endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_PERSISTENT); +#endif +#if !defined(PHP_WASI) REGISTER_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_PERSISTENT); -#if defined(LOG_NOWAIT) +#endif +#if !defined(PHP_WASI) && defined(LOG_NOWAIT) REGISTER_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_PERSISTENT); #endif -#if defined(LOG_PERROR) +#if !defined(PHP_WASI) && defined(LOG_PERROR) REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_PERSISTENT); #endif REGISTER_LONG_CONSTANT("STR_PAD_LEFT", PHP_STR_PAD_LEFT, CONST_PERSISTENT); diff --git a/ext/standard/basic_functions_wasi.c b/ext/standard/basic_functions_wasi.c new file mode 100644 index 0000000000000..e8bf65232996e --- /dev/null +++ b/ext/standard/basic_functions_wasi.c @@ -0,0 +1,19 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + */ + +#include + +mode_t umask(mode_t mask) { + return 0; +} diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 index 984dfcd8a256e..637cab9b665cd 100644 --- a/ext/standard/config.m4 +++ b/ext/standard/config.m4 @@ -445,20 +445,26 @@ dnl dnl Setup extension sources dnl PHP_NEW_EXTENSION(standard, array.c base64.c basic_functions.c browscap.c crc32.c crypt.c \ - datetime.c dir.c dl.c dns.c exec.c file.c filestat.c \ - flock_compat.c formatted_print.c fsock.c head.c html.c image.c \ + datetime.c dir.c dl.c exec.c file.c filestat.c \ + formatted_print.c fsock.c head.c html.c image.c \ info.c iptc.c link.c mail.c math.c md5.c metaphone.c \ microtime.c pack.c pageinfo.c quot_print.c \ soundex.c string.c scanf.c syslog.c type.c uniqid.c url.c \ var.c versioning.c assert.c strnatcmp.c levenshtein.c \ - incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ - http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ + incomplete_class.c url_scanner_ex.c credits.c css.c \ var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ - filters.c proc_open.c streamsfuncs.c http.c password.c \ - net.c hrtime.c crc32_x86.c libavifinfo/avifinfo.c,,, + filters.c php_fopen_wrapper.c proc_open.c streamsfuncs.c http.c \ + password.c net.c hrtime.c crc32_x86.c libavifinfo/avifinfo.c \ + $stdlib_extra_sources,,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) PHP_ADD_BUILD_DIR($ext_builddir/libavifinfo) +if test "$WASI" = "yes"; then + PHP_ADD_SOURCES(ext/standard, basic_functions_wasi.c exec_wasi.c file_wasi.c filestat_wasi.c flock_wasi.c mail_wasi.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) +else + PHP_ADD_SOURCES(ext/standard, dns.c flock_compat.c ftp_fopen_wrapper.c http_fopen_wrapper.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) +fi + PHP_ADD_MAKEFILE_FRAGMENT PHP_INSTALL_HEADERS([ext/standard/]) diff --git a/ext/standard/exec.c b/ext/standard/exec.c index 1b1b0ab9e9ce1..d4a7552fb7039 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -104,6 +104,8 @@ static size_t handle_line(int type, zval *array, char *buf, size_t bufl) { return bufl; } +#ifndef PHP_WASI + /* {{{ php_exec * If type==0, only last line of output is returned (exec) * If type==1, all lines will be printed and last lined returned (system) @@ -203,6 +205,12 @@ PHPAPI int php_exec(int type, const char *cmd, zval *array, zval *return_value) } /* }}} */ +#else + +int php_exec(int type, const char *cmd, zval *array, zval *return_value); + +#endif // PHP_WASI + static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ { char *cmd; @@ -509,8 +517,9 @@ PHP_FUNCTION(escapeshellarg) } /* }}} */ -/* {{{ Execute command via shell and return complete output as string */ -PHP_FUNCTION(shell_exec) +#ifndef PHP_WASI + +static void php_shell_exec_ex(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { FILE *in; char *command; @@ -547,6 +556,19 @@ PHP_FUNCTION(shell_exec) if (ret && ZSTR_LEN(ret) > 0) { RETVAL_STR(ret); } + } +/* }}} */ + +#else + +void php_shell_exec_ex(INTERNAL_FUNCTION_PARAMETERS); + +#endif // PHP_WASI + +/* {{{ Execute command via shell and return complete output as string */ +PHP_FUNCTION(shell_exec) /* {{{ */ +{ + php_shell_exec_ex(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ diff --git a/ext/standard/exec_wasi.c b/ext/standard/exec_wasi.c new file mode 100644 index 0000000000000..ac3c0a5cf0ad9 --- /dev/null +++ b/ext/standard/exec_wasi.c @@ -0,0 +1,27 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + */ + +#include "php.h" + +PHPAPI int php_exec(int type, const char *cmd, zval *array, zval *return_value) /* {{{ */ +{ + return -1; +} +/* }}} */ + +PHPAPI void php_shell_exec_ex(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ +{ + RETURN_FALSE; +} +/* }}} */ diff --git a/ext/standard/file.c b/ext/standard/file.c index f6076438f69d6..bdc39ab869a05 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -55,7 +55,9 @@ # endif # include # include -# include +# ifndef PHP_WASI +# include +# endif // PHP_WASI # if HAVE_ARPA_INET_H # include # endif @@ -790,8 +792,9 @@ PHPAPI PHP_FUNCTION(fclose) } /* }}} */ -/* {{{ Execute a command and open either a read or a write pipe to it */ -PHP_FUNCTION(popen) +#ifndef PHP_WASI + +static void php_popen(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { char *command, *mode; size_t command_len, mode_len; @@ -845,6 +848,19 @@ PHP_FUNCTION(popen) } /* }}} */ +#else + +void php_popen(INTERNAL_FUNCTION_PARAMETERS); + +#endif // PHP_WASI + +/* {{{ Execute a command and open either a read or a write pipe to it */ +PHP_FUNCTION(popen) /* {{{ */ +{ + php_popen(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + /* {{{ Close a file pointer opened by popen() */ PHP_FUNCTION(pclose) { @@ -1220,8 +1236,9 @@ PHP_FUNCTION(readfile) } /* }}} */ -/* {{{ Return or change the umask */ -PHP_FUNCTION(umask) +#ifndef PHP_WASI + +static void php_umask(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { zend_long mask = 0; bool mask_is_null = 1; @@ -1248,6 +1265,19 @@ PHP_FUNCTION(umask) } /* }}} */ +#else + +void php_umask(INTERNAL_FUNCTION_PARAMETERS); + +#endif // PHP_WASI + +/* {{{ Return or change the umask */ +PHP_FUNCTION(umask) /* {{{ */ +{ + php_umask(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + /* {{{ Output all remaining data from a file pointer */ PHPAPI PHP_FUNCTION(fpassthru) { diff --git a/ext/standard/file_wasi.c b/ext/standard/file_wasi.c new file mode 100644 index 0000000000000..961d47e77e789 --- /dev/null +++ b/ext/standard/file_wasi.c @@ -0,0 +1,27 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#include "php.h" + +PHPAPI void php_popen(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ +{ + RETURN_FALSE; +} +/* }}} */ + +PHPAPI void php_umask(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ +{ + RETURN_LONG(0); +} +/* }}} */ diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 131011715be78..20e203b2b151a 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -271,7 +271,7 @@ PHP_FUNCTION(disk_free_space) } /* }}} */ -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) PHPAPI zend_result php_get_gid_by_name(const char *name, gid_t *gid) { #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX) @@ -303,6 +303,7 @@ PHPAPI zend_result php_get_gid_by_name(const char *name, gid_t *gid) } #endif +#ifndef PHP_WASI static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) /* {{{ */ { char *filename; @@ -380,6 +381,11 @@ static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) /* {{{ */ #endif } /* }}} */ +#else + +void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp); + +#endif // PHP_WASI /* {{{ Change file group */ PHP_FUNCTION(chgrp) @@ -397,8 +403,14 @@ PHP_FUNCTION(lchgrp) #endif /* }}} */ -#ifndef PHP_WIN32 -PHPAPI zend_result php_get_uid_by_name(const char *name, uid_t *uid) +#ifdef PHP_WASI +PHPAPI zend_result php_get_uid_by_name(const char *name, uid_t *uid) /* {{{ */ +{ + return FAILURE; +} +/* }}} */ +#elif !defined(PHP_WIN32) +PHPAPI zend_result php_get_uid_by_name(const char *name, uid_t *uid) /* {{{ */ { #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R) struct passwd pw; @@ -427,8 +439,10 @@ PHPAPI zend_result php_get_uid_by_name(const char *name, uid_t *uid) #endif return SUCCESS; } -#endif +/* }}} */ +#endif // PHP_WASI +#ifndef PHP_WASI static void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown) /* {{{ */ { char *filename; @@ -508,6 +522,11 @@ static void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown) /* {{{ */ } /* }}} */ +#else + +void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown); + +#endif // PHP_WASI /* {{{ Change file owner */ PHP_FUNCTION(chown) @@ -526,8 +545,8 @@ PHP_FUNCTION(lchown) #endif /* }}} */ -/* {{{ Change file mode */ -PHP_FUNCTION(chmod) +#ifndef PHP_WASI +static void php_do_chmod(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { char *filename; size_t filename_len; @@ -569,6 +588,17 @@ PHP_FUNCTION(chmod) } RETURN_TRUE; } +#else + +void php_do_chmod(INTERNAL_FUNCTION_PARAMETERS); + +#endif // PHP_WASI + +/* {{{ Change file mode */ +PHP_FUNCTION(chmod) +{ + php_do_chmod(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} /* }}} */ #ifdef HAVE_UTIME @@ -819,6 +849,8 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) } } while (0); + +#ifndef PHP_WASI if (type >= FS_IS_W && type <= FS_IS_X) { if(stat_sb->st_uid==getuid()) { rmask=S_IRUSR; @@ -859,6 +891,7 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) } } } +#endif // PHP_WASI switch (type) { case FS_PERMS: @@ -883,7 +916,9 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) RETURN_STRING("link"); } switch(stat_sb->st_mode & S_IFMT) { +#ifndef PHP_WASI case S_IFIFO: RETURN_STRING("fifo"); +#endif // PHP_WASI case S_IFCHR: RETURN_STRING("char"); case S_IFDIR: RETURN_STRING("dir"); case S_IFBLK: RETURN_STRING("block"); diff --git a/ext/standard/filestat_wasi.c b/ext/standard/filestat_wasi.c new file mode 100644 index 0000000000000..6dda57781999e --- /dev/null +++ b/ext/standard/filestat_wasi.c @@ -0,0 +1,33 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + */ + +#include "php.h" + +PHPAPI void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) /* {{{ */ +{ + RETURN_FALSE; +} +/* }}} */ + +PHPAPI void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown) /* {{{ */ +{ + RETURN_FALSE; +} +/* }}} */ + +PHPAPI void php_do_chmod(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ +{ + RETURN_FALSE; +} +/* }}} */ diff --git a/ext/standard/flock_wasi.c b/ext/standard/flock_wasi.c new file mode 100644 index 0000000000000..49df6d222cb51 --- /dev/null +++ b/ext/standard/flock_wasi.c @@ -0,0 +1,22 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Sascha Schumann | + +----------------------------------------------------------------------+ +*/ + +#include "php.h" + +PHPAPI int flock(int fd, int operation) +{ + return -1; +} diff --git a/ext/standard/mail.c b/ext/standard/mail.c index b1e0f14b8d5e2..90197925df4b6 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -371,6 +371,8 @@ static int php_mail_detect_multiple_crlf(const char *hdr) { } +#ifndef PHP_WASI + /* {{{ php_mail */ PHPAPI int php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd) { @@ -558,6 +560,8 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co } /* }}} */ +#endif // PHP_WASI + /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(mail) { diff --git a/ext/standard/mail_wasi.c b/ext/standard/mail_wasi.c new file mode 100644 index 0000000000000..1da5d64afbac5 --- /dev/null +++ b/ext/standard/mail_wasi.c @@ -0,0 +1,22 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Sascha Schumann | + +----------------------------------------------------------------------+ +*/ + +#include "php.h" + +PHPAPI int php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd) +{ + return 0; +} diff --git a/ext/standard/microtime.c b/ext/standard/microtime.c index ca8643eb5196f..fad841aa78b54 100644 --- a/ext/standard/microtime.c +++ b/ext/standard/microtime.c @@ -125,7 +125,7 @@ PHP_FUNCTION(getrusage) #ifdef PHP_WIN32 /* Windows only implements a limited amount of fields from the rusage struct */ PHP_RUSAGE_PARA(ru_majflt); PHP_RUSAGE_PARA(ru_maxrss); -#elif !defined(_OSD_POSIX) && !defined(__HAIKU__) +#elif !defined(_OSD_POSIX) && !defined(__HAIKU__) && !defined(PHP_WASI) PHP_RUSAGE_PARA(ru_oublock); PHP_RUSAGE_PARA(ru_inblock); PHP_RUSAGE_PARA(ru_msgsnd); @@ -139,7 +139,7 @@ PHP_FUNCTION(getrusage) PHP_RUSAGE_PARA(ru_nvcsw); PHP_RUSAGE_PARA(ru_nivcsw); PHP_RUSAGE_PARA(ru_nswap); -#endif /*_OSD_POSIX*/ +#endif /* !defined(_OSD_POSIX) && !defined(__HAIKU__) && !defined(PHP_WASI) */ PHP_RUSAGE_PARA(ru_utime.tv_usec); PHP_RUSAGE_PARA(ru_utime.tv_sec); PHP_RUSAGE_PARA(ru_stime.tv_usec); diff --git a/ext/standard/net.c b/ext/standard/net.c index b22f304c8eb33..aeec02004aa34 100644 --- a/ext/standard/net.c +++ b/ext/standard/net.c @@ -43,10 +43,11 @@ # include # include # include -#else +#elif !defined(PHP_WASI) # include #endif +#ifndef PHP_WASI PHPAPI zend_string* php_inet_ntop(const struct sockaddr *addr) { socklen_t addrlen = sizeof(struct sockaddr_in); @@ -101,6 +102,7 @@ PHPAPI zend_string* php_inet_ntop(const struct sockaddr *addr) { return NULL; } +#endif // PHP_WASI #if defined(PHP_WIN32) || defined(HAVE_GETIFADDRS) || defined(__PASE__) static void iface_append_unicast(zval *unicast, zend_long flags, @@ -151,6 +153,7 @@ array( ), // etc... ) */ +#ifndef PHP_WASI PHP_FUNCTION(net_get_interfaces) { #ifdef PHP_WIN32 # define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) @@ -311,3 +314,4 @@ PHP_FUNCTION(net_get_interfaces) { } #endif /* }}} */ +#endif // PHP_WASI diff --git a/ext/standard/pageinfo.c b/ext/standard/pageinfo.c index f24659a95e048..a9ebf4a3d244e 100644 --- a/ext/standard/pageinfo.c +++ b/ext/standard/pageinfo.c @@ -35,6 +35,9 @@ #define getgroups(a, b) 0 #define getgid() 1 #define getuid() 1 +#elif defined(PHP_WASI) +#define getgid() 1 +#define getuid() 1 #endif #ifdef HAVE_UNISTD_H #include diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index 8926485025a3b..5c424fa9a83fe 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -317,7 +317,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa return NULL; } -#ifdef HAVE_UNISTD_H +#if defined(HAVE_UNISTD_H) && !defined(PHP_WASI) dtablesize = getdtablesize(); #else dtablesize = INT_MAX; @@ -390,7 +390,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa return NULL; } -#if defined(S_IFSOCK) && !defined(PHP_WIN32) +#if defined(S_IFSOCK) && !defined(PHP_WIN32) && !defined(PHP_WASI) do { zend_stat_t st = {0}; memset(&st, 0, sizeof(st)); diff --git a/main/fastcgi_wasi.c b/main/fastcgi_wasi.c new file mode 100644 index 0000000000000..0e350db30f911 --- /dev/null +++ b/main/fastcgi_wasi.c @@ -0,0 +1,81 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + */ + +#include "php.h" + +int fcgi_is_fastcgi(void) { + return 0; +} + +struct _fcgi_request {}; +typedef struct _fcgi_request fcgi_request; + +enum _fcgi_request_type { FCGI_NONE = 1 }; +typedef enum _fcgi_request_type fcgi_request_type; + +typedef void (*fcgi_apply_func)(const char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg); + +void fcgi_terminate(void) {} + +void fcgi_loadenv(fcgi_request *req, fcgi_apply_func func, zval *array) {} + +int fcgi_listen(const char *path, int backlog) { + return -1; +} + +fcgi_request *fcgi_init_request(int listen_socket, void(*on_accept)(void), void(*on_read)(void), void(*on_close)(void)) { + return NULL; +} + +void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len) {} + +void fcgi_destroy_request(fcgi_request *req) {} + +void fcgi_shutdown(void) {} + +int fcgi_accept_request(fcgi_request *req) { + return 0; +} + +int fcgi_has_env(fcgi_request *req) { + return 0; +} + +char* fcgi_quick_getenv(fcgi_request *req, const char* var, int var_len, unsigned int hash_value) { + return NULL; +} + +char* fcgi_quick_putenv(fcgi_request *req, char* var, int var_len, unsigned int hash_value, char* val) { + return NULL; +} + +int fcgi_finish_request(fcgi_request *req, int force_close) { + return 0; +} + +char* fcgi_getenv(fcgi_request *req, const char* var, int var_len) { + return NULL; +} + +int fcgi_read(fcgi_request *req, char *str, int len) { + return 0; +} + +int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int len) { + return 0; +} + +int fcgi_flush(fcgi_request *req, int end) { + return 0; +} diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index ead11a958b32a..e97712754b340 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -52,7 +52,9 @@ #include #else #include +#ifndef PHP_WASI #include +#endif // PHP_WASI #if HAVE_ARPA_INET_H #include #endif diff --git a/main/main.c b/main/main.c index d918e0b73ae78..d85ca959b1a3e 100644 --- a/main/main.c +++ b/main/main.c @@ -1191,7 +1191,7 @@ static void clear_last_error(void) { } } -#if ZEND_DEBUG +#if ZEND_DEBUG && !defined(PHP_WASI) /* {{{ report_zend_debug_error_notify_cb */ static void report_zend_debug_error_notify_cb(int type, zend_string *error_filename, uint32_t error_lineno, zend_string *message) { @@ -1461,11 +1461,14 @@ PHPAPI char *php_get_current_user(void) return ""; } pwd = &_pw; +#elif defined(PHP_WASI) + return ""; #else if ((pwd=getpwuid(pstat->st_uid))==NULL) { return ""; } #endif +#ifndef PHP_WASI SG(request_info).current_user_length = strlen(pwd->pw_name); SG(request_info).current_user = estrndup(pwd->pw_name, SG(request_info).current_user_length); #if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX) @@ -1473,6 +1476,7 @@ PHPAPI char *php_get_current_user(void) #endif return SG(request_info).current_user; #endif +#endif // PHP_WASI } } /* }}} */ diff --git a/main/network_wasi.c b/main/network_wasi.c new file mode 100644 index 0000000000000..4fc6a45bc68d6 --- /dev/null +++ b/main/network_wasi.c @@ -0,0 +1,34 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + */ + +#include "php.h" + +PHPAPI int php_network_parse_network_address_with_port(const char *addr, zend_long addrlen, struct sockaddr *sa, socklen_t *sl) +{ + return FAILURE; +} + +PHPAPI int php_set_sock_blocking(int socketd, int block) +{ + return FAILURE; +} + +PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize) +{ + return NULL; +} + +PHPAPI void _php_emit_fd_setsize_warning(int max_fd) +{ +} diff --git a/main/php.h b/main/php.h index 3385fb799927e..9fc31ae020479 100644 --- a/main/php.h +++ b/main/php.h @@ -51,6 +51,10 @@ # define PHP_OS_FAMILY "Unknown" #endif +#ifdef __wasi__ +#define PHP_WASI __wasi__ +#endif + /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ #undef PHP_DEBUG #define PHP_DEBUG ZEND_DEBUG diff --git a/main/php_open_temporary_file.c b/main/php_open_temporary_file.c index dcea78358486d..3b73f414891e4 100644 --- a/main/php_open_temporary_file.c +++ b/main/php_open_temporary_file.c @@ -30,7 +30,9 @@ #include #include #include +#ifndef PHP_WASI #include +#endif // PHP_WASI #if HAVE_ARPA_INET_H #include #endif @@ -84,6 +86,7 @@ * SUCH DAMAGE. */ +#ifndef PHP_WASI static int php_do_open_temporary_file(const char *path, const char *pfx, zend_string **opened_path_p) { #ifdef PHP_WIN32 @@ -196,11 +199,13 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, zend_st efree(new_state.cwd); return fd; } +#endif // PHP_WASI /* }}} */ /* * Determine where to place temporary files. */ +#ifndef PHP_WASI PHPAPI const char* php_get_temporary_directory(void) { /* Did we determine the temporary directory already? */ @@ -275,6 +280,7 @@ PHPAPI const char* php_get_temporary_directory(void) return PG(php_sys_temp_dir); #endif } +#endif // PHP_WASI /* {{{ php_open_temporary_file * diff --git a/main/php_open_temporary_file_wasi.c b/main/php_open_temporary_file_wasi.c new file mode 100644 index 0000000000000..793c254401a5b --- /dev/null +++ b/main/php_open_temporary_file_wasi.c @@ -0,0 +1,25 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + */ + +#include "php.h" + +PHPAPI const char* php_get_temporary_directory(void) +{ + return NULL; +} + +PHPAPI int php_do_open_temporary_file(const char *path, const char *pfx, zend_string **opened_path_p) +{ + return -1; +} diff --git a/main/php_syslog.h b/main/php_syslog.h index f2682d74f2382..2563786e2c215 100644 --- a/main/php_syslog.h +++ b/main/php_syslog.h @@ -21,6 +21,8 @@ #ifdef PHP_WIN32 #include "win32/syslog.h" +#elif defined(PHP_WASI) +#include "wasi/syslog.h" #else #include #ifdef HAVE_SYSLOG_H diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 86c517132482e..b9f76b53b7c1f 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -47,7 +47,7 @@ #define php_stream_fopen_from_file_int(file, mode) _php_stream_fopen_from_file_int((file), (mode) STREAMS_CC) #define php_stream_fopen_from_file_int_rel(file, mode) _php_stream_fopen_from_file_int((file), (mode) STREAMS_REL_CC) -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) extern int php_get_uid_by_name(const char *name, uid_t *uid); extern int php_get_gid_by_name(const char *name, gid_t *gid); #endif @@ -491,6 +491,7 @@ static int php_stdiop_close(php_stream *stream, int close_handle) if (close_handle) { if (data->file) { +#ifndef PHP_WASI if (data->is_process_pipe) { errno = 0; ret = pclose(data->file); @@ -504,6 +505,10 @@ static int php_stdiop_close(php_stream *stream, int close_handle) ret = fclose(data->file); data->file = NULL; } +#else // PHP_WASI + ret = fclose(data->file); + data->file = NULL; +#endif // PHP_WASI } else if (data->fd != -1) { ret = close(data->fd); data->fd = -1; @@ -1307,7 +1312,7 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f # ifdef EXDEV if (errno == EXDEV) { zend_stat_t sb; -# if !defined(ZTS) && !defined(TSRM_WIN32) +# if !defined(ZTS) && !defined(TSRM_WIN32) && !defined(PHP_WASI) /* not sure what to do in ZTS case, umask is not thread-safe */ int oldmask = umask(077); # endif @@ -1315,7 +1320,7 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f if (php_copy_file(url_from, url_to) == SUCCESS) { if (VCWD_STAT(url_from, &sb) == 0) { success = 1; -# ifndef TSRM_WIN32 +# if !defined(TSRM_WIN32) && !defined(PHP_WASI) /* * Try to set user and permission info on the target. * If we're not root, then some of these may fail. @@ -1348,7 +1353,7 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f } else { php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); } -# if !defined(ZTS) && !defined(TSRM_WIN32) +# if !defined(ZTS) && !defined(TSRM_WIN32) && !defined(PHP_WASI) umask(oldmask); # endif return success; @@ -1529,7 +1534,7 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url ret = VCWD_UTIME(url, newtime); break; -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) case PHP_STREAM_META_OWNER_NAME: case PHP_STREAM_META_OWNER: if(option == PHP_STREAM_META_OWNER_NAME) { @@ -1555,10 +1560,12 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url ret = VCWD_CHOWN(url, -1, gid); break; #endif +#ifndef PHP_WASI case PHP_STREAM_META_ACCESS: mode = (mode_t)*(zend_long *)value; ret = VCWD_CHMOD(url, mode); break; +#endif default: zend_value_error("Unknown option %d for stream_metadata", option); return 0; diff --git a/main/streams/streams.c b/main/streams/streams.c index 06589e649c2ec..bad8df2940af6 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1839,6 +1839,9 @@ int php_init_stream_wrappers(int module_number) zend_hash_init(php_get_stream_filters_hash_global(), 8, NULL, NULL, 1); zend_hash_init(php_stream_xport_get_hash(), 8, NULL, NULL, 1); +#ifdef PHP_WASI + return SUCCESS; +#else return (php_stream_xport_register("tcp", php_stream_generic_socket_factory) == SUCCESS && php_stream_xport_register("udp", php_stream_generic_socket_factory) == SUCCESS @@ -1849,6 +1852,7 @@ int php_init_stream_wrappers(int module_number) php_stream_xport_register("udg", php_stream_generic_socket_factory) == SUCCESS #endif ) ? SUCCESS : FAILURE; +#endif // PHP_WASI } void php_shutdown_stream_wrappers(int module_number) diff --git a/main/unistd_wasi.c b/main/unistd_wasi.c new file mode 100644 index 0000000000000..dab39c0beee4f --- /dev/null +++ b/main/unistd_wasi.c @@ -0,0 +1,21 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#include + +int dup(int fildes) +{ + errno = ENOTSUP; + return -1; +} diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 156599f6f9d4d..af1c477303ca9 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -95,7 +95,7 @@ int __riscosify_control = __RISCOSIFY_STRICT_UNIX_SPECS; # include "valgrind/callgrind.h" #endif -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) /* XXX this will need to change later when threaded fastcgi is implemented. shane */ struct sigaction act, old_term, old_quit, old_int; #endif @@ -1450,7 +1450,7 @@ static void init_request_info(fcgi_request *request) } /* }}} */ -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) /** * Clean up child processes upon exit */ @@ -1471,7 +1471,7 @@ void fastcgi_cleanup(int signal) exit(0); } } -#else +#elif defined(PHP_WIN32) BOOL WINAPI fastcgi_cleanup(DWORD sig) { int i = kids; @@ -1982,7 +1982,7 @@ consult the installation file that came with this distribution, or visit \n\ fcgi_set_mgmt_var("FCGI_MAX_REQS", sizeof("FCGI_MAX_REQS")-1, "1", sizeof("1")-1); } -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(PHP_WASI) if (children) { int running = 0; pid_t pid; @@ -2070,7 +2070,7 @@ consult the installation file that came with this distribution, or visit \n\ zend_signal_init(); } -#else +#elif defined(PHP_WIN32) if (children) { wchar_t *cmd_line_tmp, cmd_line[PHP_WIN32_IOUTIL_MAXPATHLEN]; size_t cmd_line_len; diff --git a/sapi/cgi/config9.m4 b/sapi/cgi/config9.m4 index 04bd70b269ee6..6aa31ea39a8c4 100644 --- a/sapi/cgi/config9.m4 +++ b/sapi/cgi/config9.m4 @@ -54,6 +54,9 @@ if test "$PHP_CGI" != "no"; then *darwin*) BUILD_CGI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" ;; + *wasi*) + BUILD_CGI="\$(LIBTOOL) --mode=link \$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" + ;; *) BUILD_CGI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" ;; diff --git a/sapi/cli/config.m4 b/sapi/cli/config.m4 index d17d531683605..9b3518332ca91 100644 --- a/sapi/cli/config.m4 +++ b/sapi/cli/config.m4 @@ -4,6 +4,7 @@ PHP_ARG_ENABLE([cli],, [yes], [no]) +AC_CHECK_DEFINE([__wasi__], [WASI="yes"], []) AC_CHECK_FUNCS(setproctitle) AC_CHECK_HEADERS([sys/pstat.h]) @@ -28,7 +29,10 @@ if test "$PHP_CLI" != "no"; then SAPI_CLI_PATH=sapi/cli/php dnl Select SAPI. - PHP_SELECT_SAPI(cli, program, php_cli.c php_http_parser.c php_cli_server.c ps_title.c php_cli_process_title.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, '$(SAPI_CLI_PATH)') + if test "$WASI" != "yes"; then + cli_extra_sources="php_cli_server.c" + fi + PHP_SELECT_SAPI(cli, program, php_cli.c php_http_parser.c ps_title.c php_cli_process_title.c $cli_extra_sources, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, '$(SAPI_CLI_PATH)') case $host_alias in *aix*) @@ -41,6 +45,9 @@ if test "$PHP_CLI" != "no"; then *darwin*) BUILD_CLI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" ;; + *wasi*) + BUILD_CLI="\$(LIBTOOL) --mode=link \$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" + ;; *) BUILD_CLI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" ;; diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index 546c4ba997dc3..2db2959c40cb4 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -1259,7 +1259,7 @@ int main(int argc, char *argv[]) /* define ini entries on command line */ php_ini_builder_define(&ini_builder, php_optarg); break; -#ifndef PHP_CLI_WIN32_NO_CONSOLE +#if !defined(PHP_CLI_WIN32_NO_CONSOLE) && !defined(PHP_WASI) case 'S': sapi_module = &cli_server_sapi_module; cli_server_sapi_module.additional_functions = server_additional_functions; @@ -1331,11 +1331,11 @@ int main(int argc, char *argv[]) } zend_first_try { -#ifndef PHP_CLI_WIN32_NO_CONSOLE +#if !defined(PHP_CLI_WIN32_NO_CONSOLE) && !defined(PHP_WASI) if (sapi_module == &cli_sapi_module) { #endif exit_status = do_cli(argc, argv); -#ifndef PHP_CLI_WIN32_NO_CONSOLE +#if !defined(PHP_CLI_WIN32_NO_CONSOLE) && !defined(PHP_WASI) } else { exit_status = do_cli_server(argc, argv); } diff --git a/wasi/syslog.h b/wasi/syslog.h new file mode 100644 index 0000000000000..39768a093b7e8 --- /dev/null +++ b/wasi/syslog.h @@ -0,0 +1,27 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#ifndef SYSLOG_H +#define SYSLOG_H + +#define LOG_EMERG 0 /* system is unusable */ +#define LOG_ALERT 1 /* action must be taken immediately */ +#define LOG_CRIT 2 /* critical conditions */ +#define LOG_ERR 3 /* error conditions */ +#define LOG_WARNING 4 /* warning conditions */ +#define LOG_NOTICE 5 /* normal but significant condition */ +#define LOG_INFO 6 /* informational */ +#define LOG_DEBUG 7 /* debug-level messages */ + +#endif // SYSLOG_H