From 23a4a59d484ab18847f1848d29f1287551958c9e Mon Sep 17 00:00:00 2001 From: pmp-p Date: Mon, 15 Apr 2024 09:34:26 +0200 Subject: [PATCH 1/3] https://github.com/pmp-p/postgres/issues/1 --- .gitignore | 3 + src/backend/port/sysv_shmem.c | 3 + src/include/port/emscripten.h | 97 +++++++++++++++++++++++++++++++ src/makefiles/Makefile.emscripten | 8 +++ src/template/emscripten | 14 +++++ 5 files changed, 125 insertions(+) create mode 100644 src/include/port/emscripten.h create mode 100644 src/makefiles/Makefile.emscripten create mode 100644 src/template/emscripten diff --git a/.gitignore b/.gitignore index 4e911395fe3ba..ecd6ab04aa482 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ lib*.pc /Release/ /tmp_install/ /portlock/ + +*.wasm +*.map diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c index 1a6d8fa0fbcb4..d93ec796e0406 100644 --- a/src/backend/port/sysv_shmem.c +++ b/src/backend/port/sysv_shmem.c @@ -17,6 +17,9 @@ * *------------------------------------------------------------------------- */ + +#define PG_SHMEM + #include "postgres.h" #include diff --git a/src/include/port/emscripten.h b/src/include/port/emscripten.h new file mode 100644 index 0000000000000..b3732ee78a487 --- /dev/null +++ b/src/include/port/emscripten.h @@ -0,0 +1,97 @@ +/* src/include/port/emscripten.h */ + +#ifndef I_EMSCRIPTEN +#define I_EMSCRIPTEN + + +#define HAVE_LINUX_EIDRM_BUG +/* + * Set the default wal_sync_method to fdatasync. With recent Linux versions, + * xlogdefs.h's normal rules will prefer open_datasync, which (a) doesn't + * perform better and (b) causes outright failures on ext4 data=journal + * filesystems, because those don't support O_DIRECT. + */ +#define PLATFORM_DEFAULT_WAL_SYNC_METHOD WAL_SYNC_METHOD_FDATASYNC + +// force the name used with --single +#define WASM_USERNAME "postgres" + + +// we want client and server in the same lib for now. + +extern int pg_char_to_encoding_private(const char *name); +extern const char *pg_encoding_to_char_private(int encoding); +extern int pg_valid_server_encoding_id_private(int encoding); +#define pg_char_to_encoding(encoding) pg_char_to_encoding_private(encoding) +#define pg_encoding_to_char(encoding) pg_encoding_to_char_private(encoding) +#define pg_valid_server_encoding_id(encoding) pg_valid_server_encoding_id_private(encoding) + + +// this one is a wasi system call, so change its name everywhere. +#define proc_exit(arg) pg_proc_exit(arg) + + +/* ************************************************ */ +/* popen / pclose for initdb is routed to stderr */ + +#if defined(PG_EXEC) +// exec.c +#define pclose(stream) pg_pclose(stream) +#include // FILE +int pg_pclose(FILE *stream) { + puts("FIXME: pclose->pg_pclose: " __FILE__); + return 0; +} +#endif // PG_EXEC + + +/* ******************************* */ +/* handle pg_shmem.c special case */ + +#if defined(PG_SHMEM) +#include // print +#include // malloc +// #include +#include +#include + +/* Shared memory control operation. */ +//extern int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf); + +int +shmctl (int __shmid, int __cmd, struct shmid_ds *__buf) { + printf("FIXME: int shmctl (int __shmid=%d, int __cmd=%d, struct shmid_ds *__buf=%p)\n", __shmid, __cmd, __buf); + return 0; +} + + +void *FAKE_SHM ; + +/* Get shared memory segment. */ +// extern int shmget (key_t __key, size_t __size, int __shmflg); +int +shmget (key_t __key, size_t __size, int __shmflg) { + printf("FIXING: int shmget (key_t __key=%d, size_t __size=%d, int __shmflg=%d)\n", __key, __size, __shmflg); + FAKE_SHM = malloc(__size); + return 666; +} + +/* Attach shared memory segment. */ +// extern void *shmat (int __shmid, const void *__shmaddr, int __shmflg); +void *shmat (int __shmid, const void *__shmaddr, int __shmflg) { + printf("FIXING: void *shmat (int __shmid=%d, const void *__shmaddr=%p, int __shmflg=%d)\n", __shmid, __shmaddr, __shmflg); + if (__shmid==666) + return FAKE_SHM; + return NULL; +} + +/* Detach shared memory segment. */ +// extern int shmdt (const void *__shmaddr); +int +shmdt (const void *__shmaddr) { + puts("FIXME: int shmdt (const void *__shmaddr)"); + return 0; +} + +#endif // PG_SHMEM +#endif // I_EMSCRIPTEN diff --git a/src/makefiles/Makefile.emscripten b/src/makefiles/Makefile.emscripten new file mode 100644 index 0000000000000..76c3249e5633c --- /dev/null +++ b/src/makefiles/Makefile.emscripten @@ -0,0 +1,8 @@ +# Use --enable-new-dtags to generate DT_RUNPATH instead of DT_RPATH. +# This allows LD_LIBRARY_PATH to still work when needed. +rpath = + + +# Rule for building a shared library from a single .o file +%.so: %.o + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ diff --git a/src/template/emscripten b/src/template/emscripten new file mode 100644 index 0000000000000..f3edf627a24e0 --- /dev/null +++ b/src/template/emscripten @@ -0,0 +1,14 @@ +# src/template/emscripten + +# Prefer unnamed POSIX semaphores if available, unless user overrides choice +if test x"$PREFERRED_SEMAPHORES" = x"" ; then + PREFERRED_SEMAPHORES=UNNAMED_POSIX +fi + +# Force _GNU_SOURCE on; plperl is broken with Perl 5.8.0 otherwise +# This is also required for ppoll(2), and perhaps other things +CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" + +# Extra CFLAGS for code that will go into a shared library +CFLAGS_SL="-fPIC" + From 7509c297f689201c1e61eb9bc547a38150176772 Mon Sep 17 00:00:00 2001 From: "Paul m. p. Peny" Date: Tue, 16 Apr 2024 08:45:59 +0200 Subject: [PATCH 2/3] popen/pclose redir support for initdb popen will return stderr for that case --- src/include/port/emscripten.h | 45 +++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/src/include/port/emscripten.h b/src/include/port/emscripten.h index b3732ee78a487..078e35e0d69b7 100644 --- a/src/include/port/emscripten.h +++ b/src/include/port/emscripten.h @@ -22,31 +22,59 @@ extern int pg_char_to_encoding_private(const char *name); extern const char *pg_encoding_to_char_private(int encoding); extern int pg_valid_server_encoding_id_private(int encoding); + +#if defined(pg_char_to_encoding) +#undef pg_char_to_encoding +#endif #define pg_char_to_encoding(encoding) pg_char_to_encoding_private(encoding) + +#if defined(pg_encoding_to_char) +#undef pg_encoding_to_char +#endif #define pg_encoding_to_char(encoding) pg_encoding_to_char_private(encoding) + +#if defined(pg_valid_server_encoding_id) +#undef pg_valid_server_encoding_id +#endif #define pg_valid_server_encoding_id(encoding) pg_valid_server_encoding_id_private(encoding) -// this one is a wasi system call, so change its name everywhere. +/* + * 'proc_exit' is a wasi system call, so change its name everywhere. + */ + #define proc_exit(arg) pg_proc_exit(arg) -/* ************************************************ */ -/* popen / pclose for initdb is routed to stderr */ +/* + * popen / pclose for initdb is routed to stderr + * link a pclose replacement when we are in exec.c ( PG_EXEC defined ) + */ #if defined(PG_EXEC) -// exec.c #define pclose(stream) pg_pclose(stream) #include // FILE + int pg_pclose(FILE *stream) { puts("FIXME: pclose->pg_pclose: " __FILE__); return 0; } #endif // PG_EXEC +/* and now popen will return stderr as file handle in initdb.c */ +#if defined(PG_INITDB) +#define popen(command, mode) pg_popen(command, mode) +#include // FILE +FILE *pg_popen(const char *command, const char *type) { + fprintf(stderr,"# popen[%s]\n", command); + return stderr; +} +#endif // PG_INITDB -/* ******************************* */ -/* handle pg_shmem.c special case */ + +/* + * handle pg_shmem.c special case + */ #if defined(PG_SHMEM) #include // print @@ -55,7 +83,10 @@ int pg_pclose(FILE *stream) { #include #include -/* Shared memory control operation. */ +/* + * Shared memory control operation. + */ + //extern int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf); int From 1a097618dd6d858be667e374f4a6136c5cbecb54 Mon Sep 17 00:00:00 2001 From: pmp-p Date: Tue, 23 Apr 2024 09:15:41 +0200 Subject: [PATCH 3/3] indent --- src/backend/port/sysv_shmem.c | 4 +-- src/include/port/emscripten.h | 48 +++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c index d93ec796e0406..d6c4834edcbcb 100644 --- a/src/backend/port/sysv_shmem.c +++ b/src/backend/port/sysv_shmem.c @@ -161,7 +161,7 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size) if (shmid < 0) { int shmget_errno = errno; - +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) /* * Fail quietly if error indicates a collision with existing segment. * One would expect EEXIST, given that we said IPC_EXCL, but perhaps @@ -212,7 +212,7 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size) (int) shmid, IPC_RMID); } } - +#endif /* wasm */ /* * Else complain and abort. * diff --git a/src/include/port/emscripten.h b/src/include/port/emscripten.h index 078e35e0d69b7..a1b6ab511b9d0 100644 --- a/src/include/port/emscripten.h +++ b/src/include/port/emscripten.h @@ -3,6 +3,16 @@ #ifndef I_EMSCRIPTEN #define I_EMSCRIPTEN +#include + +/* + * https://github.com/electric-sql/postgres-wasm/pull/1/files#diff-6e542ba2eb1d83ef90e65cdc0912b51a295184701c7e3bd236937c43c4cac4b9R63 + */ + +#define WAIT_USE_POLL 1 + +/* internal size 8 is invalid for passed-by-value type */ +/* #define USE_FLOAT8_BYVAL 1 */ #define HAVE_LINUX_EIDRM_BUG /* @@ -16,6 +26,8 @@ // force the name used with --single #define WASM_USERNAME "postgres" +/* reduce size */ +#define PG_FORCE_DISABLE_INLINE // we want client and server in the same lib for now. @@ -59,6 +71,8 @@ int pg_pclose(FILE *stream) { puts("FIXME: pclose->pg_pclose: " __FILE__); return 0; } + + #endif // PG_EXEC /* and now popen will return stderr as file handle in initdb.c */ @@ -66,8 +80,8 @@ int pg_pclose(FILE *stream) { #define popen(command, mode) pg_popen(command, mode) #include // FILE FILE *pg_popen(const char *command, const char *type) { - fprintf(stderr,"# popen[%s]\n", command); - return stderr; + fprintf(stderr,"# popen[%s]\n", command); + return stderr; } #endif // PG_INITDB @@ -91,37 +105,45 @@ FILE *pg_popen(const char *command, const char *type) { int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf) { - printf("FIXME: int shmctl (int __shmid=%d, int __cmd=%d, struct shmid_ds *__buf=%p)\n", __shmid, __cmd, __buf); - return 0; + printf("FIXME: int shmctl (int __shmid=%d, int __cmd=%d, struct shmid_ds *__buf=%p)\n", __shmid, __cmd, __buf); + return 0; } void *FAKE_SHM ; +key_t FAKE_KEY = 0; /* Get shared memory segment. */ // extern int shmget (key_t __key, size_t __size, int __shmflg); int shmget (key_t __key, size_t __size, int __shmflg) { - printf("FIXING: int shmget (key_t __key=%d, size_t __size=%d, int __shmflg=%d)\n", __key, __size, __shmflg); - FAKE_SHM = malloc(__size); - return 666; + printf("# FIXING: int shmget (key_t __key=%d, size_t __size=%d, int __shmflg=%d)\n", __key, __size, __shmflg); + if (!FAKE_KEY) { + FAKE_SHM = malloc(__size); + FAKE_KEY = 666; + return FAKE_KEY; + } else { + printf("# ERROR: int shmget (key_t __key=%d, size_t __size=%d, int __shmflg=%d)\n", __key, __size, __shmflg); + abort(); + } + return -1; } /* Attach shared memory segment. */ // extern void *shmat (int __shmid, const void *__shmaddr, int __shmflg); void *shmat (int __shmid, const void *__shmaddr, int __shmflg) { - printf("FIXING: void *shmat (int __shmid=%d, const void *__shmaddr=%p, int __shmflg=%d)\n", __shmid, __shmaddr, __shmflg); - if (__shmid==666) - return FAKE_SHM; - return NULL; + printf("# FIXING: void *shmat (int __shmid=%d, const void *__shmaddr=%p, int __shmflg=%d)\n", __shmid, __shmaddr, __shmflg); + if (__shmid==666) + return FAKE_SHM; + return NULL; } /* Detach shared memory segment. */ // extern int shmdt (const void *__shmaddr); int shmdt (const void *__shmaddr) { - puts("FIXME: int shmdt (const void *__shmaddr)"); - return 0; + puts("# FIXME: int shmdt (const void *__shmaddr)"); + return 0; } #endif // PG_SHMEM