From c4826571080647aa3303808f0492b2c8cbf5320f Mon Sep 17 00:00:00 2001 From: pmp-p Date: Tue, 21 Jan 2025 16:36:06 +0100 Subject: [PATCH 01/16] wasm fencing --- contrib/pgstattuple/pgstatindex.c | 4 +- contrib/xml2/Makefile | 2 +- src/backend/access/nbtree/nbtutils.c | 4 +- src/backend/access/transam/xact.c | 6 ++ src/backend/access/transam/xlogarchive.c | 4 + src/backend/bootstrap/bootstrap.c | 11 ++- src/backend/catalog/index.c | 4 +- src/backend/commands/collationcmds.c | 6 +- src/backend/commands/dbcommands.c | 3 +- src/backend/commands/event_trigger.c | 12 +++ src/backend/libpq/auth.c | 2 +- src/backend/libpq/be-fsstubs.c | 20 ++-- src/backend/libpq/pqcomm.c | 120 +++++++++++++++++++++-- src/backend/port/posix_sema.c | 7 ++ src/backend/port/sysv_shmem.c | 41 +++++++- src/backend/postmaster/checkpointer.c | 2 + src/backend/postmaster/postmaster.c | 32 ++++-- src/backend/storage/buffer/bufmgr.c | 8 +- src/backend/storage/file/fd.c | 16 ++- src/backend/storage/ipc/ipc.c | 58 ++++++++++- src/backend/storage/ipc/latch.c | 2 + src/backend/storage/ipc/procsignal.c | 3 + src/backend/storage/ipc/signalfuncs.c | 9 +- src/backend/storage/lmgr/proc.c | 8 +- src/backend/tcop/postgres.c | 10 +- src/backend/tcop/utility.c | 4 +- src/backend/utils/adt/ruleutils.c | 3 +- src/backend/utils/error/elog.c | 17 +++- src/backend/utils/fmgr/dfmgr.c | 5 +- src/backend/utils/init/miscinit.c | 16 ++- src/backend/utils/init/postinit.c | 41 +++++++- src/backend/utils/misc/timeout.c | 16 +++ src/bin/pg_config/pg_config.c | 3 + src/bin/pg_ctl/pg_ctl.c | 14 ++- src/bin/pg_dump/parallel.c | 4 +- src/bin/pg_dump/pg_dump.c | 32 ++++-- src/bin/pg_dump/pg_dumpall.c | 16 ++- src/bin/pg_resetwal/pg_resetwal.c | 2 +- src/bin/pg_upgrade/parallel.c | 3 +- src/bin/pgbench/pgbench.c | 7 +- src/bin/psql/command.c | 5 + src/common/exec.c | 2 +- src/common/logging.c | 3 +- src/fe_utils/print.c | 1 + src/fe_utils/string_utils.c | 6 +- src/include/bootstrap/bootstrap.h | 5 +- src/include/common/file_utils.h | 4 + src/include/common/logging.h | 1 - src/include/fe_utils/string_utils.h | 7 +- src/include/fmgr.h | 5 +- src/include/libpq/be-fsstubs.h | 6 +- src/include/port/pg_pthread.h | 10 +- src/include/storage/dsm_impl.h | 53 +++++++--- src/include/storage/fd.h | 8 +- src/include/storage/ipc.h | 5 +- src/include/utils/elog.h | 15 ++- src/include/utils/palloc.h | 7 +- src/interfaces/libpq/fe-auth.c | 17 ++-- src/interfaces/libpq/fe-connect.c | 92 +++++++++++++---- src/interfaces/libpq/fe-exec.c | 1 + src/interfaces/libpq/fe-misc.c | 27 ++++- src/interfaces/libpq/legacy-pqsignal.c | 2 + src/port/pqsignal.c | 5 + src/port/pthread_barrier_wait.c | 19 +++- src/test/regress/pg_regress.c | 9 ++ 65 files changed, 745 insertions(+), 147 deletions(-) diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c index 5c06ba6db438e..0ea74cef43f23 100644 --- a/contrib/pgstattuple/pgstatindex.c +++ b/contrib/pgstattuple/pgstatindex.c @@ -656,9 +656,9 @@ pgstathashindex(PG_FUNCTION_ARGS) stats.unused_pages++; else if (PageGetSpecialSize(page) != MAXALIGN(sizeof(HashPageOpaqueData))) - ereport(ERROR, + ereport(WARNING, (errcode(ERRCODE_INDEX_CORRUPTED), - errmsg("index \"%s\" contains corrupted page at block %u", + errmsg("# 661(FATAL block=%d): index \"%s\" contains corrupted page at block %u", blkno, RelationGetRelationName(rel), BufferGetBlockNumber(buf)))); else diff --git a/contrib/xml2/Makefile b/contrib/xml2/Makefile index 0d703fe0e8f94..926649f63d3f2 100644 --- a/contrib/xml2/Makefile +++ b/contrib/xml2/Makefile @@ -11,7 +11,7 @@ DATA = xml2--1.1.sql xml2--1.0--1.1.sql PGFILEDESC = "xml2 - XPath querying and XSLT" REGRESS = xml2 - +PG_CFLAGS=$(shell xml2-config --cflags) SHLIB_LINK += $(filter -lxslt, $(LIBS)) -lxml2 ifdef USE_PGXS diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index e4528db477949..c1294fba57d75 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -2732,7 +2732,7 @@ _bt_allequalimage(Relation rel, bool debugmessage) break; } } - +#if !defined(__EMSCRIPTEN__) if (debugmessage) { if (allequalimage) @@ -2742,6 +2742,6 @@ _bt_allequalimage(Relation rel, bool debugmessage) elog(DEBUG1, "index \"%s\" cannot use deduplication", RelationGetRelationName(rel)); } - +#endif return allequalimage; } diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 4a2ea4adbaf0c..a3e40843bc11a 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -1740,6 +1740,7 @@ RecordTransactionAbort(bool isSubXact) if (TransactionIdDidCommit(xid)) elog(PANIC, "cannot abort transaction %u, it was already committed", xid); + else elog(WARNING, "# 1743: aborting transaction %u", xid); /* * Are we using the replication origins feature? Or, in other words, are @@ -2748,7 +2749,9 @@ AbortTransaction(void) * handler. We do this fairly early in the sequence so that the timeout * infrastructure will be functional if needed while aborting. */ +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) sigprocmask(SIG_SETMASK, &UnBlockSig, NULL); +#endif /* * check the current transaction state @@ -5107,7 +5110,10 @@ AbortSubTransaction(void) * handler. We do this fairly early in the sequence so that the timeout * infrastructure will be functional if needed while aborting. */ +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) sigprocmask(SIG_SETMASK, &UnBlockSig, NULL); +#endif + /* * check the current transaction state diff --git a/src/backend/access/transam/xlogarchive.c b/src/backend/access/transam/xlogarchive.c index 524e80adb1ccd..80fb0ce0e48d6 100644 --- a/src/backend/access/transam/xlogarchive.c +++ b/src/backend/access/transam/xlogarchive.c @@ -33,6 +33,10 @@ #include "storage/ipc.h" #include "storage/lwlock.h" +#if defined(__wasi__) +#define system(cmd) system_wasi(cmd) +#endif + /* * Attempt to retrieve the specified file from off-line archival storage. * If successful, fill "path" with its complete path (note that this will be diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 49e956b2c577f..daff9dfbf9dd0 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -199,7 +199,11 @@ CheckerModeMain(void) * to shared memory sizing, options work (or at least do not cause an error * up to shared memory creation). */ +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) void +#else +int +#endif BootstrapModeMain(int argc, char *argv[], bool check_only) { int i; @@ -353,7 +357,7 @@ BootstrapModeMain(int argc, char *argv[], bool check_only) */ if (pg_link_canary_is_frontend()) elog(ERROR, "backend is incorrectly linked to frontend functions"); - +puts("# 360: InitPostgres(boot): " __FILE__ ); InitPostgres(NULL, InvalidOid, NULL, InvalidOid, false, false, NULL); /* Initialize stuff for bootstrap-file processing */ @@ -378,7 +382,12 @@ BootstrapModeMain(int argc, char *argv[], bool check_only) /* Clean up and exit */ cleanup(); +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) proc_exit(0); +#else + puts("# 338 cleanup(boot): " __FILE__); + return 0; +#endif } diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index bc08ab66bd6d6..7907456916660 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -2993,7 +2993,7 @@ index_build(Relation heapRelation, indexInfo->ii_ParallelWorkers = plan_create_index_workers(RelationGetRelid(heapRelation), RelationGetRelid(indexRelation)); - +#if !defined(__EMSCRIPTEN__) if (indexInfo->ii_ParallelWorkers == 0) ereport(DEBUG1, (errmsg_internal("building index \"%s\" on table \"%s\" serially", @@ -3005,7 +3005,7 @@ index_build(Relation heapRelation, RelationGetRelationName(indexRelation), RelationGetRelationName(heapRelation), indexInfo->ii_ParallelWorkers))); - +#endif /* * Switch to the table owner's userid, so that any index functions are run * as that user. Also lock down security-restricted operations and diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c index 4088481b9c7e0..e46bcb87d5d8b 100644 --- a/src/backend/commands/collationcmds.c +++ b/src/backend/commands/collationcmds.c @@ -828,14 +828,14 @@ pg_import_system_collations(PG_FUNCTION_ARGS) maxaliases = 100; aliases = (CollAliasData *) palloc(maxaliases * sizeof(CollAliasData)); naliases = 0; - locale_a_handle = OpenPipeStream("locale -a", "r"); - if (locale_a_handle == NULL) + if (locale_a_handle == NULL) { + puts("======================== ERROR ================"); ereport(ERROR, (errcode_for_file_access(), errmsg("could not execute command \"%s\": %m", "locale -a"))); - + } while (fgets(localebuf, sizeof(localebuf), locale_a_handle)) { size_t len; diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index a100d5b37e097..7edb1966ecc7b 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -1783,8 +1783,9 @@ dropdb(const char *dbname, bool missing_ok, bool force) RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT); /* Close all smgr fds in all backends. */ +#if !defined(__wasi__) && !defined(__EMSCRIPTEN__) WaitForProcSignalBarrier(EmitProcSignalBarrier(PROCSIGNAL_BARRIER_SMGRRELEASE)); - +#endif /* * Remove all tablespace subdirs belonging to the database. */ diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c index d4b00d1a828a4..9ecba5a83226f 100644 --- a/src/backend/commands/event_trigger.c +++ b/src/backend/commands/event_trigger.c @@ -642,6 +642,8 @@ EventTriggerDDLCommandStart(Node *parsetree) List *runlist; EventTriggerData trigdata; +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +#else /* * Event Triggers are completely disabled in standalone mode. There are * (at least) two reasons for this: @@ -660,6 +662,7 @@ EventTriggerDDLCommandStart(Node *parsetree) */ if (!IsUnderPostmaster) return; +#endif runlist = EventTriggerCommonSetup(parsetree, EVT_DDLCommandStart, @@ -690,12 +693,15 @@ EventTriggerDDLCommandEnd(Node *parsetree) List *runlist; EventTriggerData trigdata; +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +#else /* * See EventTriggerDDLCommandStart for a discussion about why event * triggers are disabled in single user mode. */ if (!IsUnderPostmaster) return; +#endif /* * Also do nothing if our state isn't set up, which it won't be if there @@ -738,12 +744,15 @@ EventTriggerSQLDrop(Node *parsetree) List *runlist; EventTriggerData trigdata; +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +#else /* * See EventTriggerDDLCommandStart for a discussion about why event * triggers are disabled in single user mode. */ if (!IsUnderPostmaster) return; +#endif /* * Use current state to determine whether this event fires at all. If @@ -809,12 +818,15 @@ EventTriggerTableRewrite(Node *parsetree, Oid tableOid, int reason) List *runlist; EventTriggerData trigdata; +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +#else /* * See EventTriggerDDLCommandStart for a discussion about why event * triggers are disabled in single user mode. */ if (!IsUnderPostmaster) return; +#endif /* * Also do nothing if our state isn't set up, which it won't be if there diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index eaae83cc3a8b2..e90351221010c 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -1866,7 +1866,7 @@ auth_peer(hbaPort *port) return STATUS_ERROR; } -#ifndef WIN32 +#if !defined(WIN32) && !defined(__wasi__) errno = 0; /* clear errno before call */ pw = getpwuid(uid); if (!pw) diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c index 230c65753205b..4f0d78f1a3c48 100644 --- a/src/backend/libpq/be-fsstubs.c +++ b/src/backend/libpq/be-fsstubs.c @@ -150,8 +150,12 @@ be_lo_close(PG_FUNCTION_ARGS) * *****************************************************************************/ +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +static int +#else int -lo_read(int fd, char *buf, int len) +#endif +lo_read3(int fd, char *buf, int len) { int status; LargeObjectDesc *lobj; @@ -178,8 +182,12 @@ lo_read(int fd, char *buf, int len) return status; } +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +static int +#else int -lo_write(int fd, const char *buf, int len) +#endif +lo_write3(int fd, const char *buf, int len) { int status; LargeObjectDesc *lobj; @@ -190,7 +198,7 @@ lo_write(int fd, const char *buf, int len) errmsg("invalid large-object descriptor: %d", fd))); lobj = cookies[fd]; - /* see comment in lo_read() */ + /* see comment in lo_read3() */ if ((lobj->flags & IFS_WRLOCK) == 0) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), @@ -365,7 +373,7 @@ be_loread(PG_FUNCTION_ARGS) len = 0; retval = (bytea *) palloc(VARHDRSZ + len); - totalread = lo_read(fd, VARDATA(retval), len); + totalread = lo_read3(fd, VARDATA(retval), len); SET_VARSIZE(retval, totalread + VARHDRSZ); PG_RETURN_BYTEA_P(retval); @@ -382,7 +390,7 @@ be_lowrite(PG_FUNCTION_ARGS) PreventCommandIfReadOnly("lowrite()"); bytestowrite = VARSIZE_ANY_EXHDR(wbuf); - totalwritten = lo_write(fd, VARDATA_ANY(wbuf), bytestowrite); + totalwritten = lo_write3(fd, VARDATA_ANY(wbuf), bytestowrite); PG_RETURN_INT32(totalwritten); } @@ -560,7 +568,7 @@ lo_truncate_internal(int32 fd, int64 len) errmsg("invalid large-object descriptor: %d", fd))); lobj = cookies[fd]; - /* see comment in lo_read() */ + /* see comment in lo_read3() */ if ((lobj->flags & IFS_WRLOCK) == 0) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 16378e8a73336..90c993f159dc8 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -123,8 +123,12 @@ static char *PqSendBuffer; static int PqSendBufferSize; /* Size send buffer */ static int PqSendPointer; /* Next index to store a byte in PqSendBuffer */ static int PqSendStart; /* Next index to send a byte in PqSendBuffer */ - +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +static char PqRecvBuffer_static[PQ_RECV_BUFFER_SIZE]; +static char *PqRecvBuffer; +#else static char PqRecvBuffer[PQ_RECV_BUFFER_SIZE]; +#endif static int PqRecvPointer; /* Next index to read a byte from PqRecvBuffer */ static int PqRecvLength; /* End of data available in PqRecvBuffer */ @@ -136,6 +140,7 @@ static bool PqCommReadingMsg; /* in the middle of reading a message */ /* Internal functions */ + static void socket_comm_reset(void); static void socket_close(int code, Datum arg); static void socket_set_nonblocking(bool nonblocking); @@ -147,9 +152,6 @@ static void socket_putmessage_noblock(char msgtype, const char *s, size_t len); static int internal_putbytes(const char *s, size_t len); static int internal_flush(void); -static int Lock_AF_UNIX(const char *unixSocketDir, const char *unixSocketPath); -static int Setup_AF_UNIX(const char *sock_path); - static const PQcommMethods PqCommSocketMethods = { socket_comm_reset, socket_flush, @@ -159,6 +161,10 @@ static const PQcommMethods PqCommSocketMethods = { socket_putmessage_noblock }; +static int Lock_AF_UNIX(const char *unixSocketDir, const char *unixSocketPath); +static int Setup_AF_UNIX(const char *sock_path); + + const PQcommMethods *PqCommMethods = &PqCommSocketMethods; WaitEventSet *FeBeWaitSet; @@ -180,7 +186,7 @@ pq_init(void) PqSendPointer = PqSendStart = PqRecvPointer = PqRecvLength = 0; PqCommBusy = false; PqCommReadingMsg = false; - +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) /* set up process-exit hook to close the socket */ on_proc_exit(socket_close, 0); @@ -210,7 +216,12 @@ pq_init(void) MyLatch, NULL); AddWaitEventToSet(FeBeWaitSet, WL_POSTMASTER_DEATH, PGINVALID_SOCKET, NULL, NULL); - +#else + PDEBUG("# 220: FIXME: socketfile"); + #pragma message "FIXME: socketfile" + /* because we fill before starting reading message */ + PqRecvBuffer = &PqRecvBuffer_static[0]; +#endif /* * The event positions match the order we added them, but let's sanity * check them to be sure. @@ -632,7 +643,7 @@ Setup_AF_UNIX(const char *sock_path) Assert(Unix_socket_group); if (Unix_socket_group[0] != '\0') { -#ifdef WIN32 +#if defined(WIN32) || defined(__wasi__) elog(WARNING, "configuration item unix_socket_group is not supported on this platform"); #else char *endptr; @@ -1148,6 +1159,20 @@ pq_buffer_has_data(void) * This must be called before any of the pq_get* functions. * -------------------------------- */ +#if defined(I_EMSCRIPTEN) || defined(I_WASI) +EMSCRIPTEN_KEEPALIVE void +pq_recvbuf_fill(FILE* fp, int packetlen) { + fread( PqRecvBuffer, packetlen, 1, fp); + PqRecvPointer = 0; + PqRecvLength = packetlen; +#if PDEBUG + printf("# 1199: pq_recvbuf_fill cma_rsize=%d PqRecvLength=%d buf=%p reply=%p\n", cma_rsize, PqRecvLength, &PqRecvBuffer[0], &PqSendBuffer[0]); +#endif + +} +#endif +extern int cma_rsize; +static char * PqSendBuffer_save; void pq_startmsgread(void) { @@ -1159,7 +1184,29 @@ pq_startmsgread(void) ereport(FATAL, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("terminating connection because protocol synchronization was lost"))); +#if defined(I_EMSCRIPTEN) || defined(I_WASI) + if (!pq_buffer_has_data()) { + if (cma_rsize) { + PqRecvPointer = 0; + PqRecvLength = cma_rsize; + PqRecvBuffer = (char*)0x1; + + PqSendPointer = 0; + PqSendBuffer_save = PqSendBuffer; + PqSendBuffer = 2 + (char*)(cma_rsize); + PqSendBufferSize = (64*1024*1024) - (int)(&PqSendBuffer[0]); + } else { + PqRecvBuffer = &PqRecvBuffer_static[0]; + if (PqSendBuffer_save) + PqSendBuffer=PqSendBuffer_save; + PqSendBufferSize = PQ_SEND_BUFFER_SIZE; + } + } +#if PDEBUG + printf("# 1199: pq_startmsgread cma_rsize=%d PqRecvLength=%d buf=%p reply=%p\n", cma_rsize, PqRecvLength, &PqRecvBuffer[0], &PqSendBuffer[0]); +#endif +#endif PqCommReadingMsg = true; } @@ -1282,8 +1329,65 @@ pq_getmessage(StringInfo s, int maxlen) return 0; } +#if defined(__EMSCRIPTEN__) || defined(__wasi__) + +extern FILE* SOCKET_FILE; +extern int SOCKET_DATA; + +static int +internal_putbytes(const char *s, size_t len) { + if (PqSendPointer >= PqSendBufferSize) + { + puts("# 1329: overflow"); + } + + if (!cma_rsize) { + int wc= fwrite(s, 1, len, SOCKET_FILE); +#if 0 + fprintf(stderr,"# 1334: sockfile %d +%d top=%p %d/%d\n", SOCKET_DATA, wc, PqSendBuffer, PqSendPointer,PqSendBufferSize); +#endif + SOCKET_DATA+=wc; + } else { + size_t amount; + while (len > 0) + { + /* If buffer is full, then flush it out */ + if (PqSendPointer >= PqSendBufferSize) + { + socket_set_nonblocking(false); + if (internal_flush()) + return EOF; + } + amount = PqSendBufferSize - PqSendPointer; + if (amount > len) + amount = len; + memcpy(PqSendBuffer + PqSendPointer, s, amount); + PqSendPointer += amount; + s += amount; + len -= amount; + SOCKET_DATA+=amount; + } +#if 0 + fprintf(stderr,"# 1359: cma buffer wire: %d +%zu top=%p %d/%d\n", SOCKET_DATA, amount, PqSendBuffer, PqSendPointer,PqSendBufferSize); +#endif + } + return 0; +} +static int +socket_flush(void) { + return internal_flush(); +} +static int +internal_flush(void) { + /* no flush for raw wire */ + if (!cma_rsize) { + PqSendStart = PqSendPointer = 0; + } + return 0; +} +#else static int internal_putbytes(const char *s, size_t len) { @@ -1403,7 +1507,7 @@ internal_flush(void) PqSendStart = PqSendPointer = 0; return 0; } - +#endif /* wasm */ /* -------------------------------- * pq_flush_if_writable - flush pending output if writable without blocking * diff --git a/src/backend/port/posix_sema.c b/src/backend/port/posix_sema.c index 315ed16b197eb..f0eeb1eb5e18f 100644 --- a/src/backend/port/posix_sema.c +++ b/src/backend/port/posix_sema.c @@ -298,10 +298,16 @@ PGSemaphoreReset(PGSemaphore sema) * There's no direct API for this in POSIX, so we have to ratchet the * semaphore down to 0 with repeated trywait's. */ +#if defined(__EMSCRIPTEN__) || defined(__wasi__) + sem_trywait(PG_SEM_REF(sema)); + return; +#else for (;;) { if (sem_trywait(PG_SEM_REF(sema)) < 0) { + + if (errno == EAGAIN || errno == EDEADLK) break; /* got it down to 0 */ if (errno == EINTR) @@ -309,6 +315,7 @@ PGSemaphoreReset(PGSemaphore sema) elog(FATAL, "sem_trywait failed: %m"); } } +#endif } /* diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c index eaba244bc9c85..4baf4734cc83c 100644 --- a/src/backend/port/sysv_shmem.c +++ b/src/backend/port/sysv_shmem.c @@ -17,8 +17,8 @@ * *------------------------------------------------------------------------- */ +#define PG_SHMEM #include "postgres.h" - #include #include #include @@ -691,12 +691,47 @@ PGShmemHeader * PGSharedMemoryCreate(Size size, PGShmemHeader **shim) { - IpcMemoryKey NextShmemSegID; - void *memAddress; + IpcMemoryKey NextShmemSegID = 0; + void *memAddress = NULL; PGShmemHeader *hdr; struct stat statbuf; Size sysvsize; +/* + puts("@\n@\n@\n@\n@\n@\n PGSharedMemoryCreate @\n@\n@\n@\n@\n@\n"); + + elog(NOTICE, "Init WASM shared memory"); + + hdr = (PGShmemHeader *) malloc(size); + hdr->creatorPID = getpid(); + hdr->magic = PGShmemMagic; + hdr->dsm_control = 0; + + + hdr->device = statbuf.st_dev; + hdr->inode = statbuf.st_ino; + + hdr->totalsize = size; + hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader)); + *shim = hdr; + + UsedShmemSegAddr = memAddress; + UsedShmemSegID = (unsigned long) NextShmemSegID; + + if (AnonymousShmem == NULL) + return hdr; + memcpy(AnonymousShmem, hdr, sizeof(PGShmemHeader)); + return (PGShmemHeader *) AnonymousShmem; +*/ + + + + + + + + + /* * We use the data directory's ID info (inode and device numbers) to * positively identify shmem segments associated with this data dir, and diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c index f482f6423d1d2..2923ceac6dc90 100644 --- a/src/backend/postmaster/checkpointer.c +++ b/src/backend/postmaster/checkpointer.c @@ -936,7 +936,9 @@ RequestCheckpoint(int flags) /* * If in a standalone backend, just do it ourselves. */ +#if !defined(__wasi__) && !defined(__EMSCRIPTEN__) if (!IsPostmasterEnvironment) +#endif { /* * There's no point in doing slow checkpoints in a standalone backend, diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index b42aae41fce83..f98519b18c53e 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -422,7 +422,8 @@ static void BackendRun(Port *port) pg_attribute_noreturn(); static void ExitPostmaster(int status) pg_attribute_noreturn(); static int ServerLoop(void); static int BackendStartup(Port *port); -static int ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done); +//static +int ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done); static void SendNegotiateProtocolVersion(List *unrecognized_protocol_options); static void processCancelRequest(Port *port, void *pkt); static void report_fork_failure_to_client(Port *port, int errnum); @@ -1533,7 +1534,7 @@ getInstallationPaths(const char *argv0) /* Locate the postgres executable itself */ if (find_my_exec(argv0, my_exec_path) < 0) ereport(FATAL, - (errmsg("%s: could not locate my own executable path", argv0))); + (errmsg("%s:1536: could not locate my own executable path", argv0))); #ifdef EXEC_BACKEND /* Locate executable backend before we change working directory */ @@ -1947,10 +1948,21 @@ ServerLoop(void) * should make no assumption here about the order in which the client may make * requests. */ -static int -ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) + +static inline uint32 +em_bswap32(uint32 x) +{ + return + ((x << 24) & 0xff000000) | + ((x << 8) & 0x00ff0000) | + ((x >> 8) & 0x0000ff00) | + ((x >> 24) & 0x000000ff); +} + +// static int +int ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) { - int32 len; + uint32 len; char *buf; ProtocolVersion proto; MemoryContext oldcontext; @@ -1988,15 +2000,15 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) return STATUS_ERROR; } - len = pg_ntoh32(len); + //len = pg_ntoh32(len); + len = em_bswap32(len); len -= 4; - - if (len < (int32) sizeof(ProtocolVersion) || + if (len < (uint32) sizeof(ProtocolVersion) || len > MAX_STARTUP_PACKET_LENGTH) { ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("invalid length of startup packet"))); + errmsg("# 2000 invalid length of startup packet"))); return STATUS_ERROR; } @@ -2029,7 +2041,7 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) { ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("invalid length of startup packet"))); + errmsg("# 2033 invalid length of startup packet"))); return STATUS_ERROR; } processCancelRequest(port, buf); diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index e066a3f888fb7..f1c8b40efb5b6 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -1134,16 +1134,16 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, { ereport(WARNING, (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("invalid page in block %u of relation %s; zeroing out page", + errmsg("1137: invalid page in block %u of relation %s; zeroing out page", blockNum, relpath(smgr->smgr_rlocator, forkNum)))); MemSet((char *) bufBlock, 0, BLCKSZ); } else - ereport(ERROR, + ereport(WARNING, (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("invalid page in block %u of relation %s", - blockNum, + errmsg("1145(FATAL): invalid page in block %u fork=%d p=%p sz=%d of relation %s", + blockNum,forkNum,bufBlock, BLCKSZ, relpath(smgr->smgr_rlocator, forkNum)))); } } diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index 16b3e8f90584b..042de5f1b1340 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -69,7 +69,7 @@ * *------------------------------------------------------------------------- */ - +#define PG_FD #include "postgres.h" #include @@ -478,6 +478,11 @@ pg_fdatasync(int fd) void pg_flush_data(int fd, off_t offset, off_t nbytes) { +#if defined(__EMSCRIPTEN__) || defined(__wasi__) + //int res = sync_file_range(fd, offset, nbytes, SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER); + (void)fsync(fd); + // fprintf(stderr, "# pg_flush_data(int fd=%d, off_t offset=%lld, off_t nbytes=%lld res=%d\n", fd,offset,nbytes, res); +#else /* * Right now file flushing is primarily used to avoid making later * fsync()/fdatasync() calls have less impact. Thus don't trigger flushes @@ -648,6 +653,7 @@ pg_flush_data(int fd, off_t offset, off_t nbytes) return; } #endif +#endif /* wasm */ } /* @@ -660,7 +666,7 @@ pg_ftruncate(int fd, off_t length) retry: ret = ftruncate(fd, length); - +printf("# 670 pg_ftruncate(int fd=%d, off_t length=%lld)=%d\n" __FILE__, fd, length, ret); if (ret == -1 && errno == EINTR) goto retry; @@ -692,7 +698,7 @@ pg_truncate(const char *path, off_t length) retry: ret = truncate(path, length); - +printf("# 670 pg_truncate(path=%s, off_t length=%lld)=%d\n" __FILE__, path, length, ret); if (ret == -1 && errno == EINTR) goto retry; #endif @@ -2619,7 +2625,7 @@ OpenTransientFilePerm(const char *fileName, int fileFlags, mode_t fileMode) return -1; /* failure */ } - +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) /* * Routines that want to initiate a pipe stream should use OpenPipeStream * rather than plain popen(). This lets fd.c deal with freeing FDs if @@ -2679,7 +2685,7 @@ OpenPipeStream(const char *command, const char *mode) return NULL; } - +#endif /* * Free an AllocateDesc of any type. * diff --git a/src/backend/storage/ipc/ipc.c b/src/backend/storage/ipc/ipc.c index 6591b5d6a8b64..9a6abc6b8cb36 100644 --- a/src/backend/storage/ipc/ipc.c +++ b/src/backend/storage/ipc/ipc.c @@ -103,6 +103,48 @@ static int on_proc_exit_index, void proc_exit(int code) { +#if defined(__EMSCRIPTEN__) || defined(__wasi__) + if (code==66) { + fprintf(stderr,"# 108:fake shutdown\n"); + proc_exit_inprogress = true; + InterruptPending = false; + ProcDiePending = false; + QueryCancelPending = false; + InterruptHoldoffCount = 1; + CritSectionCount = 0; + + error_context_stack = NULL; + debug_query_string = NULL; + + shmem_exit_inprogress = true; + int save_before_shmem_exit_index = before_shmem_exit_index; + while (--before_shmem_exit_index >= 0) { + if (before_shmem_exit_index!=4) { + printf("# skipped shmem_exit_index=%d/%d\n", before_shmem_exit_index, save_before_shmem_exit_index); + continue; + } else + printf("# before_shmem_exit_index=%d/%d\n", before_shmem_exit_index, save_before_shmem_exit_index); + before_shmem_exit_list[before_shmem_exit_index].function(code, before_shmem_exit_list[before_shmem_exit_index].arg); + } + before_shmem_exit_index = save_before_shmem_exit_index; + puts("# dsm_backend_shutdown ?"); + // dsm_backend_shutdown(); + shmem_exit_inprogress = false; + /* + + int save_on_proc_exit_index = on_proc_exit_index; + while (--on_proc_exit_index >= 0) { + printf("# on_proc_exit_list=%d/%d\n", on_proc_exit_list, save_on_proc_exit_index); + on_proc_exit_list[on_proc_exit_index].function(code, on_proc_exit_list[on_proc_exit_index].arg); + } + on_proc_exit_index = save_on_proc_exit_index; + */ + } else { + proc_exit_inprogress = true; + fprintf(stderr,"# proc_exit(%d) ignored at 118:%s\n",code, __FILE__); + } + return; +#endif /* not safe if forked by system(), etc. */ if (MyProcPid != (int) getpid()) elog(PANIC, "proc_exit() called in child process"); @@ -152,7 +194,6 @@ proc_exit(int code) #endif elog(DEBUG3, "exit(%d)", code); - exit(code); } @@ -228,7 +269,7 @@ void shmem_exit(int code) { shmem_exit_inprogress = true; - +if (code!=66){ /* * Call before_shmem_exit callbacks. * @@ -276,7 +317,7 @@ shmem_exit(int code) on_shmem_exit_list[on_shmem_exit_index].function(code, on_shmem_exit_list[on_shmem_exit_index].arg); on_shmem_exit_index = 0; - +} shmem_exit_inprogress = false; } @@ -364,6 +405,17 @@ before_shmem_exit(pg_on_exit_callback function, Datum arg) void on_shmem_exit(pg_on_exit_callback function, Datum arg) { +#if defined(__wasi__) || defined(__EMSCRIPTEN__) + if (!atexit_callback_setup) { + PDEBUG("# 410:" __FILE__ " on_shmem_exit(pg_on_exit_callback function, Datum arg) FIRST CALL"); + if (on_shmem_exit_index >= MAX_ON_EXITS) { + PDEBUG("# 412:" __FILE__ " on_shmem_exit(pg_on_exit_callback function, Datum arg) OVERFLOW"); + } + } else { + PDEBUG("# 415:" __FILE__ " on_shmem_exit(pg_on_exit_callback function, Datum arg) STUB"); + return; + } +#endif if (on_shmem_exit_index >= MAX_ON_EXITS) ereport(FATAL, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c index e572677c7034c..799152a1eb006 100644 --- a/src/backend/storage/ipc/latch.c +++ b/src/backend/storage/ipc/latch.c @@ -206,6 +206,7 @@ static inline int WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, void InitializeLatchSupport(void) { +#if !defined(__wasi__) #if defined(WAIT_USE_SELF_PIPE) int pipefd[2]; @@ -315,6 +316,7 @@ InitializeLatchSupport(void) /* Ignore SIGURG, because we'll receive it via kqueue. */ pqsignal(SIGURG, SIG_IGN); #endif +#endif /* __wasi__ */ } void diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index c85cb5cc18dbb..d1c0dfdc81420 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -420,6 +420,9 @@ WaitForProcSignalBarrier(uint64 generation) (errmsg("still waiting for backend with PID %d to accept ProcSignalBarrier", (int) slot->pss_pid))); oldval = pg_atomic_read_u64(&slot->pss_barrierGeneration); +#if defined(__EMSCRIPTEN__) || defined(__wasi__) + break; +#endif } ConditionVariableCancelSleep(); } diff --git a/src/backend/storage/ipc/signalfuncs.c b/src/backend/storage/ipc/signalfuncs.c index b595c2d691233..b29ce76edbd8b 100644 --- a/src/backend/storage/ipc/signalfuncs.c +++ b/src/backend/storage/ipc/signalfuncs.c @@ -98,7 +98,12 @@ pg_signal_backend(int pid, int sig) */ /* If we have setsid(), signal the backend's whole process group */ -#ifdef HAVE_SETSID +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +# if PGDEBUG + printf("# 103: FIXME: kill(pid=%d, sig=%d) ", pid, sig); +# endif + if (0) +#elif defined(HAVE_SETSID) if (kill(-pid, sig)) #else if (kill(pid, sig)) @@ -106,7 +111,7 @@ pg_signal_backend(int pid, int sig) { /* Again, just a warning to allow loops */ ereport(WARNING, - (errmsg("could not send signal to process %d: %m", pid))); + (errmsg("# 109: could not send signal to process %d: %m", pid))); return SIGNAL_BACKEND_ERROR; } return SIGNAL_BACKEND_SUCCESS; diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index e9e445bb2166d..9b1d2b61d377e 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -306,7 +306,11 @@ InitProcess(void) elog(PANIC, "proc header uninitialized"); if (MyProc != NULL) - elog(ERROR, "you already exist"); +#if defined(__wasi__) || defined(__EMSCRIPTEN__) + elog(WARNING, "# 309: you already exist"); +#else + elog(ERROR, "# 309: you already exist"); +#endif /* Decide which list should supply our PGPROC. */ if (IsAnyAutoVacuumProcess()) @@ -519,7 +523,7 @@ InitAuxiliaryProcess(void) elog(PANIC, "proc header uninitialized"); if (MyProc != NULL) - elog(ERROR, "you already exist"); + elog(ERROR, "# 522: you already exist"); /* * We use the ProcStructLock to protect assignment and releasing of diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 3f427f1b47f3e..904b93bf1be62 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -4076,7 +4076,11 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx, #endif } - +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +#define PG_MAIN +#include PG_MAIN_INCLUDE +#undef PG_MAIN +#else /* * PostgresSingleUserMain * Entry point for single user mode. argc/argv are the command line @@ -4972,7 +4976,7 @@ PostgresMain(const char *dbname, const char *username) } } /* end of input-reading loop */ } - +#endif /* wasm */ /* * Throw an error if we're a WAL sender process. * @@ -5091,7 +5095,7 @@ ShowUsage(const char *title) (long) user.tv_usec, (long) sys.tv_sec, (long) sys.tv_usec); -#ifndef WIN32 +#if !defined(WIN32) && !defined(__wasi__) /* * The following rusage fields are not defined by POSIX, but they're diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index e3ccf6c7f7e8b..a95d933b42ac6 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -811,7 +811,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, ListenStmt *stmt = (ListenStmt *) parsetree; CheckRestrictedOperation("LISTEN"); - +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) /* * We don't allow LISTEN in background processes, as there is * no mechanism for them to collect NOTIFY messages, so they'd @@ -827,7 +827,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, /* translator: %s is name of a SQL command, eg LISTEN */ errmsg("cannot execute %s within a background process", "LISTEN"))); - +#endif Async_Listen(stmt->conditionname); } break; diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index f0b053e2f67c7..97e20f286c1f5 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -322,8 +322,9 @@ static SPIPlanPtr plan_getviewrule = NULL; static const char *query_getviewrule = "SELECT * FROM pg_catalog.pg_rewrite WHERE ev_class = $1 AND rulename = $2"; /* GUC parameters */ +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) bool quote_all_identifiers = false; - +#endif /* ---------- * Local functions diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 155d8519a74a6..74117a91fae45 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -349,12 +349,16 @@ errstart(int elevel, const char *domain) ErrorData *edata; bool output_to_server; bool output_to_client = false; +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +# warning "FIXME: error levels" +#else int i; /* * Check some cases in which we want to promote an error into a more * severe error. None of this logic applies for non-error messages. */ + if (elevel >= ERROR) { /* @@ -395,7 +399,7 @@ errstart(int elevel, const char *domain) for (i = 0; i <= errordata_stack_depth; i++) elevel = Max(elevel, errordata[i].elevel); } - +#endif /* * Now decide whether we need to process this report at all; if it's * warning or less and not enabled for logging, just return false without @@ -540,7 +544,13 @@ errfinish(const char *filename, int lineno, const char *funcname) */ recursion_depth--; +#if 0 //defined(__EMSCRIPTEN__) || defined(__wasi__) + fprintf(stderr, "# 547: PG_RE_THROW(ERROR : %d) ignored\n", recursion_depth); + trap(); +#else + fprintf(stderr, "# 549: PG_RE_THROW(ERROR : %d)\n", recursion_depth); PG_RE_THROW(); +#endif } /* Emit the message to the right places */ @@ -588,7 +598,11 @@ errfinish(const char *filename, int lineno, const char *funcname) * FATAL termination. The postmaster may or may not consider this * worthy of panic, depending on which subprocess returns it. */ +#if defined(__EMSCRIPTEN__) || defined(__wasi__) + puts("# 599: proc_exit(FATAL) ignored"); +#else proc_exit(1); +#endif } if (elevel >= PANIC) @@ -698,6 +712,7 @@ errsave_finish(struct Node *context, const char *filename, int lineno, */ if (edata->elevel >= ERROR) { +puts("#712"); errfinish(filename, lineno, funcname); pg_unreachable(); } diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c index b85d52c913c3a..867cb669595bf 100644 --- a/src/backend/utils/fmgr/dfmgr.c +++ b/src/backend/utils/fmgr/dfmgr.c @@ -121,12 +121,15 @@ load_external_function(const char *filename, const char *funcname, /* Look up the function within the library. */ retval = dlsym(lib_handle, funcname); - +#if !defined(__wasi__) if (retval == NULL && signalNotFound) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("could not find function \"%s\" in file \"%s\"", funcname, fullname))); +#else + fprintf(stderr, "could not find function \"%s\" in file \"%s\" rv=%p snf=%b\n", funcname, fullname, retval, signalNotFound); +#endif pfree(fullname); return retval; diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index fac79f7871a7b..0ee824b45faaa 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -144,7 +144,7 @@ InitPostmasterChild(void) * children, but for consistency we make all postmaster child processes do * this. */ -#ifdef HAVE_SETSID +#if defined(HAVE_SETSID) && !defined(__wasi__) if (setsid() < 0) elog(FATAL, "setsid() failed: %m"); #endif @@ -210,7 +210,7 @@ InitStandaloneProcess(const char *argv0) if (my_exec_path[0] == '\0') { if (find_my_exec(argv0, my_exec_path) < 0) - elog(FATAL, "%s: could not locate my own executable path", + elog(WARNING, "%s:212: could not locate my own executable path", argv0); } @@ -369,7 +369,7 @@ checkDataDir(void) * * XXX can we safely enable this check on Windows? */ -#if !defined(WIN32) && !defined(__CYGWIN__) +#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__EMSCRIPTEN__) && !defined(__wasi__) if (stat_buf.st_uid != geteuid()) ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), @@ -389,7 +389,7 @@ checkDataDir(void) * be proper support for Unix-y file permissions. Need to think of a * reasonable check to apply on Windows. */ -#if !defined(WIN32) && !defined(__CYGWIN__) +#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__EMSCRIPTEN__) && !defined(__wasi__) if (stat_buf.st_mode & PG_MODE_MASK_GROUP) ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), @@ -410,7 +410,7 @@ checkDataDir(void) * Suppress when on Windows, because there may not be proper support for * Unix-y file permissions. */ -#if !defined(WIN32) && !defined(__CYGWIN__) +#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__EMSCRIPTEN__) && !defined(__wasi__) SetDataDirectoryCreatePerm(stat_buf.st_mode); umask(pg_mode_mask); @@ -1270,7 +1270,13 @@ CreateLockFile(const char *filename, bool amPostmaster, * Think not to make the file protection weaker than 0600/0640. See * comments below. */ + +#if defined(__wasi__) +printf("# 1228: CreateLockFile(%s) w+ (forced)\n", filename); + fd = fileno(fopen(filename, "w+")); +#else fd = open(filename, O_RDWR | O_CREAT | O_EXCL, pg_file_create_mode); +#endif if (fd >= 0) break; /* Success; exit the retry loop */ diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index b59838bfa3587..db9f105a6ec74 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -13,6 +13,7 @@ * *------------------------------------------------------------------------- */ +#define PG_POSTINIT #include "postgres.h" #include @@ -715,6 +716,7 @@ BaseInit(void) * Be very careful with the order of calls in the InitPostgres function. * -------------------------------- */ + void InitPostgres(const char *in_dbname, Oid dboid, const char *username, Oid useroid, @@ -884,8 +886,18 @@ InitPostgres(const char *in_dbname, Oid dboid, } else if (!IsUnderPostmaster) { +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +if (!strcmp( username , WASM_USERNAME )) { +#endif InitializeSessionUserIdStandalone(); am_superuser = true; +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +} else { + //puts("# 894: switching session id"); + InitializeSessionUserId(username, InvalidOid); + am_superuser = superuser(); +} +#endif if (!ThereIsAtLeastOneRole()) ereport(WARNING, (errcode(ERRCODE_UNDEFINED_OBJECT), @@ -1256,6 +1268,32 @@ InitPostgres(const char *in_dbname, Oid dboid, CommitTransactionCommand(); } +/* ========================================================================*/ +/* +void +ReInitPostgres(const char *in_dbname, Oid dboid, + const char *username, Oid useroid, + bool load_session_libraries, + bool override_allow_connections, + char *out_dbname) +{ + puts("ReInitPostgres:Begin"); + InitPostgres(in_dbname, dboid, username, useroid, load_session_libraries, override_allow_connections, out_dbname); + puts("ReInitPostgres:End"); +} +*/ +/* ========================================================================*/ + + + + + + + + + + + /* * Process any command-line switches and any additional GUC variable * settings passed in the startup packet. @@ -1362,14 +1400,15 @@ process_settings(Oid databaseid, Oid roleid) static void ShutdownPostgres(int code, Datum arg) { +puts("# 1348: " __FILE__); /* Make sure we've killed any active transaction */ AbortOutOfAnyTransaction(); - /* * User locks are not released by transaction end, so be sure to release * them explicitly. */ LockReleaseAll(USER_LOCKMETHOD, true); +puts("# 1356: " __FILE__); } diff --git a/src/backend/utils/misc/timeout.c b/src/backend/utils/misc/timeout.c index 8ab755d363d47..f7c88fac469d7 100644 --- a/src/backend/utils/misc/timeout.c +++ b/src/backend/utils/misc/timeout.c @@ -110,10 +110,20 @@ find_active_timeout(TimeoutId id) * Insert specified timeout reason into the list of active timeouts * at the given index. */ + +bool insert_timeout_warned = false; static void insert_timeout(TimeoutId id, int index) { int i; +#if defined(__EMSCRIPTEN__) || defined(__wasi__) + if (!insert_timeout_warned) //(index<0) + { + insert_timeout_warned = true; + fprintf(stderr, "# 117(FATAL): insert_timeout(TimeoutId id=%d, int index=%d): " __FILE__ "\n", id, index); + } + return; +#endif if (index < 0 || index > num_active_timeouts) elog(FATAL, "timeout index %d out of range 0..%d", index, @@ -128,6 +138,7 @@ insert_timeout(TimeoutId id, int index) active_timeouts[index] = &all_timeouts[id]; num_active_timeouts++; + } /* @@ -209,6 +220,10 @@ enable_timeout(TimeoutId id, TimestampTz now, TimestampTz fin_time, static void schedule_alarm(TimestampTz now) { +#if defined(__wasi__) + puts("# 224: schedule_alarm(TimestampTz now)"); + (void)signal_due_at; +#else if (num_active_timeouts > 0) { struct itimerval timeval; @@ -347,6 +362,7 @@ schedule_alarm(TimestampTz now) elog(FATAL, "could not enable SIGALRM timer: %m"); } } +#endif } diff --git a/src/bin/pg_config/pg_config.c b/src/bin/pg_config/pg_config.c index 70cab817ddd68..5458bb918f520 100644 --- a/src/bin/pg_config/pg_config.c +++ b/src/bin/pg_config/pg_config.c @@ -152,7 +152,9 @@ main(int argc, char **argv) if (find_my_exec(argv[0], my_exec_path) < 0) { fprintf(stderr, _("%s: could not find own program executable\n"), progname); +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) exit(1); +#endif } configdata = get_configdata(my_exec_path, &configdata_len); @@ -162,6 +164,7 @@ main(int argc, char **argv) for (i = 0; i < configdata_len; i++) printf("%s = %s\n", configdata[i].name, configdata[i].setting); exit(0); + } /* otherwise print requested items */ diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c index 1465b19bfc4f1..b4c8f98cfc442 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -155,6 +155,16 @@ static bool wait_for_postmaster_stop(void); static bool wait_for_postmaster_promote(void); static bool postmaster_is_alive(pid_t pid); +#if defined(__wasi__) +#if defined(HAVE_SETSID) +#undef HAVE_SETSID +#endif + +#if defined(HAVE_GETRLIMIT) +#undef HAVE_GETRLIMIT +#endif +#endif /* __wasi__ */ + #if defined(HAVE_GETRLIMIT) static void unlimit_core_size(void); #endif @@ -493,9 +503,9 @@ start_postmaster(void) else cmd = psprintf("exec \"%s\" %s%s < \"%s\" 2>&1", exec_path, pgdata_opt, post_opts, DEVNULL); - +#if !defined(__wasi__) (void) execl("/bin/sh", "/bin/sh", "-c", cmd, (char *) NULL); - +#endif /* exec failed */ write_stderr(_("%s: could not start server: %s\n"), progname, strerror(errno)); diff --git a/src/bin/pg_dump/parallel.c b/src/bin/pg_dump/parallel.c index da0723ad38587..51ff2ab674c2e 100644 --- a/src/bin/pg_dump/parallel.c +++ b/src/bin/pg_dump/parallel.c @@ -49,7 +49,7 @@ * The pstate->te[] entry for each worker is valid when it's in WRKR_WORKING * state, and must be NULL in other states. */ - +#define PG_DUMP_PARALLEL #include "postgres_fe.h" #ifndef WIN32 @@ -445,6 +445,7 @@ ShutdownWorkersHard(ParallelState *pstate) static void WaitForTerminatingWorkers(ParallelState *pstate) { +#if !defined(__wasi__) while (!HasEveryWorkerTerminated(pstate)) { ParallelSlot *slot = NULL; @@ -504,6 +505,7 @@ WaitForTerminatingWorkers(ParallelState *pstate) slot->workerStatus = WRKR_TERMINATED; pstate->te[j] = NULL; } +#endif /* __wasi__ */ } diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 31bbcb9fdca1f..92cb4f66f3219 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -30,6 +30,13 @@ *------------------------------------------------------------------------- */ #include "postgres_fe.h" +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) +#ifdef quote_all_identifiers +#undef quote_all_identifiers +#endif +#define fe_utils_quote_all_identifiers quote_all_identifiers +static bool quote_all_identifiers; +#endif #include #include @@ -328,8 +335,11 @@ static void set_restrict_relation_kind(Archive *AH, const char *value); static void setupDumpWorker(Archive *AH); static TableInfo *getRootTableInfo(const TableInfo *tbinfo); static bool forcePartitionRootLoad(const TableInfo *tbinfo); - - +#if defined(__wasi__) +__attribute__((export_name("_setup"))) void setup() { + puts("WASM_SYM_EXPORTED"); +} +#endif int main(int argc, char **argv) { @@ -411,7 +421,7 @@ main(int argc, char **argv) {"lock-wait-timeout", required_argument, NULL, 2}, {"no-table-access-method", no_argument, &dopt.outputNoTableAm, 1}, {"no-tablespaces", no_argument, &dopt.outputNoTablespaces, 1}, - {"quote-all-identifiers", no_argument, "e_all_identifiers, 1}, + {"quote-all-identifiers", no_argument, &fe_utils_quote_all_identifiers, true}, {"load-via-partition-root", no_argument, &dopt.load_via_partition_root, 1}, {"role", required_argument, NULL, 3}, {"section", required_argument, NULL, 5}, @@ -435,7 +445,9 @@ main(int argc, char **argv) {NULL, 0, NULL, 0} }; - +#if defined(__wasi__) +chdir("/"); +#endif pg_logging_init(argv[0]); pg_logging_set_level(PG_LOG_WARNING); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump")); @@ -803,9 +815,12 @@ main(int argc, char **argv) * Open the database using the Archiver, so it knows about it. Errors mean * death. */ +puts("# 813 : " __FILE__); + //setup(); ConnectDatabase(fout, &dopt.cparams, false); +puts("# 815 : " __FILE__); setup_connection(fout, dumpencoding, dumpsnapshot, use_role); - +puts("# 817 : " __FILE__); /* * On hot standbys, never try to dump unlogged table data, since it will * just throw an error. @@ -1152,9 +1167,10 @@ setup_connection(Archive *AH, const char *dumpencoding, const char *dumpsnapshot, char *use_role) { DumpOptions *dopt = AH->dopt; +puts("# 1164 : get_connection : "__FILE__); PGconn *conn = GetConnection(AH); const char *std_strings; - +puts("# 1164 : setup_connection"); PQclear(ExecuteSqlQueryForSingleRow(AH, ALWAYS_SECURE_SEARCH_PATH_SQL)); /* @@ -1239,8 +1255,8 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Quote all identifiers, if requested. */ - if (quote_all_identifiers) - ExecuteSqlStatement(AH, "SET quote_all_identifiers = true"); + if (fe_utils_quote_all_identifiers) + ExecuteSqlStatement(AH, "SET fe_utils_quote_all_identifiers = true"); /* * Adjust row-security mode, if supported. diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 591fcb07c5b16..86b8cda0c0742 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -14,7 +14,13 @@ */ #include "postgres_fe.h" - +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) +#ifdef quote_all_identifiers +#undef quote_all_identifiers +#endif +#define fe_utils_quote_all_identifiers quote_all_identifiers +static bool quote_all_identifiers; +#endif #include #include @@ -163,7 +169,7 @@ main(int argc, char *argv[]) {"lock-wait-timeout", required_argument, NULL, 2}, {"no-table-access-method", no_argument, &no_table_access_method, 1}, {"no-tablespaces", no_argument, &no_tablespaces, 1}, - {"quote-all-identifiers", no_argument, "e_all_identifiers, 1}, + {"quote-all-identifiers", no_argument, &fe_utils_quote_all_identifiers, true}, {"load-via-partition-root", no_argument, &load_via_partition_root, 1}, {"role", required_argument, NULL, 3}, {"use-set-session-authorization", no_argument, &use_setsessauth, 1}, @@ -434,7 +440,7 @@ main(int argc, char *argv[]) appendPQExpBufferStr(pgdumpopts, " --no-table-access-method"); if (no_tablespaces) appendPQExpBufferStr(pgdumpopts, " --no-tablespaces"); - if (quote_all_identifiers) + if (fe_utils_quote_all_identifiers) appendPQExpBufferStr(pgdumpopts, " --quote-all-identifiers"); if (load_via_partition_root) appendPQExpBufferStr(pgdumpopts, " --load-via-partition-root"); @@ -534,8 +540,8 @@ main(int argc, char *argv[]) } /* Force quoting of all identifiers if requested. */ - if (quote_all_identifiers) - executeCommand(conn, "SET quote_all_identifiers = true"); + if (fe_utils_quote_all_identifiers) + executeCommand(conn, "SET fe_utils_quote_all_identifiers = true"); fprintf(OPF, "--\n-- PostgreSQL database cluster dump\n--\n\n"); if (verbose) diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index ca57713f63bb4..278a0f5af4bcd 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -330,7 +330,7 @@ main(int argc, char *argv[]) * -- any other user won't have sufficient permissions to modify files in * the data directory. */ -#ifndef WIN32 +#if !defined(WIN32) && !defined(__EMSCRIPTEN__) && !defined(__wasi__) if (geteuid() == 0) { pg_log_error("cannot be executed by \"root\""); diff --git a/src/bin/pg_upgrade/parallel.c b/src/bin/pg_upgrade/parallel.c index eaf0f0afefa93..93346c1d000cc 100644 --- a/src/bin/pg_upgrade/parallel.c +++ b/src/bin/pg_upgrade/parallel.c @@ -277,6 +277,7 @@ win32_transfer_all_new_dbs(transfer_thread_arg *args) bool reap_child(bool wait_for_child) { +#if !defined(__wasi__) #ifndef WIN32 int work_status; pid_t child; @@ -336,6 +337,6 @@ reap_child(bool wait_for_child) /* do this after job has been removed */ parallel_jobs--; - +#endif /* __wasi__ */ return true; } diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index c1134eae5b531..5f0568f2e1669 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -137,7 +137,7 @@ typedef struct socket_set EnterSynchronizationBarrier((barrier), \ SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY) #define THREAD_BARRIER_DESTROY(barrier) -#elif defined(ENABLE_THREAD_SAFETY) +#elif defined(ENABLE_THREAD_SAFETY) && !defined(__wasi__) /* Use POSIX threads */ #include "port/pg_pthread.h" #define THREAD_T pthread_t @@ -155,6 +155,11 @@ typedef struct socket_set #define THREAD_BARRIER_DESTROY(barrier) pthread_barrier_destroy((barrier)) #else /* No threads implementation, use none (-j 1) */ +#if defined(__wasi__) +# if defined(ENABLE_THREAD_SAFETY) +# undef ENABLE_THREAD_SAFETY +# endif +#endif #define THREAD_T void * #define THREAD_FUNC_RETURN_TYPE void * #define THREAD_FUNC_RETURN return NULL diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index d0ee47b517dee..37cd36542d0ce 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -5150,6 +5150,10 @@ do_shell(const char *command) static bool do_watch(PQExpBuffer query_buf, double sleep, int iter) { +#if defined(__wasi__) + pg_log_error("#5150 wasi: could not set timer"); + return false; +#else long sleep_ms = (long) (sleep * 1000); printQueryOpt myopt = pset.popt; const char *strftime_fmt; @@ -5389,6 +5393,7 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter) pg_free(title); return (res >= 0); +#endif /* __wasi__ */ } /* diff --git a/src/common/exec.c b/src/common/exec.c index f209b934df781..1b7073ecca304 100644 --- a/src/common/exec.c +++ b/src/common/exec.c @@ -22,7 +22,7 @@ * This should be harmless everywhere else. */ #define _DARWIN_BETTER_REALPATH - +#define PG_EXEC #ifndef FRONTEND #include "postgres.h" #else diff --git a/src/common/logging.c b/src/common/logging.c index dab718b482ec3..eaed3139fc106 100644 --- a/src/common/logging.c +++ b/src/common/logging.c @@ -19,8 +19,9 @@ #include "common/logging.h" enum pg_log_level __pg_log_level; - +#if !defined(PG_MAIN) static const char *progname; +#endif static int log_flags; static void (*log_pre_callback) (void); diff --git a/src/fe_utils/print.c b/src/fe_utils/print.c index 7af1ccb6b562b..9a3cc047d2a5b 100644 --- a/src/fe_utils/print.c +++ b/src/fe_utils/print.c @@ -15,6 +15,7 @@ * *------------------------------------------------------------------------- */ +#define FE_UTILS_PRINT #include "postgres_fe.h" #include diff --git a/src/fe_utils/string_utils.c b/src/fe_utils/string_utils.c index 0429a72bfe245..e7c573ec763cb 100644 --- a/src/fe_utils/string_utils.c +++ b/src/fe_utils/string_utils.c @@ -23,7 +23,9 @@ static PQExpBuffer defaultGetLocalPQExpBuffer(void); /* Globals exported by this file */ -int quote_all_identifiers = 0; +bool fe_utils_quote_all_identifiers = false; + + PQExpBuffer (*getLocalPQExpBuffer) (void) = defaultGetLocalPQExpBuffer; @@ -72,7 +74,7 @@ fmtId(const char *rawid) * These checks need to match the identifier production in scan.l. Don't * use islower() etc. */ - if (quote_all_identifiers) + if (fe_utils_quote_all_identifiers) need_quotes = true; /* slightly different rules for first character */ else if (!((rawid[0] >= 'a' && rawid[0] <= 'z') || rawid[0] == '_')) diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h index 2c28a52ce71fb..b7533b0f9fefe 100644 --- a/src/include/bootstrap/bootstrap.h +++ b/src/include/bootstrap/bootstrap.h @@ -31,8 +31,11 @@ extern PGDLLIMPORT Relation boot_reldesc; extern PGDLLIMPORT Form_pg_attribute attrtypes[MAXATTR]; extern PGDLLIMPORT int numattr; - +#if defined(__EMSCRIPTEN__) || defined(__wasi__) + int BootstrapModeMain(int argc, char *argv[], bool check_only); +#else extern void BootstrapModeMain(int argc, char *argv[], bool check_only) pg_attribute_noreturn(); +#endif extern void closerel(char *relname); extern void boot_openrel(char *relname); diff --git a/src/include/common/file_utils.h b/src/include/common/file_utils.h index b7efa1226d6ef..bdc0fcd388811 100644 --- a/src/include/common/file_utils.h +++ b/src/include/common/file_utils.h @@ -27,10 +27,14 @@ typedef enum PGFileType struct iovec; /* avoid including port/pg_iovec.h here */ #ifdef FRONTEND +#if !defined(fsync_fname) extern int fsync_fname(const char *fname, bool isdir); +#endif extern void fsync_pgdata(const char *pg_data, int serverVersion); extern void fsync_dir_recurse(const char *dir); +#if !defined(durable_rename) extern int durable_rename(const char *oldfile, const char *newfile); +#endif extern int fsync_parent_path(const char *fname); #endif diff --git a/src/include/common/logging.h b/src/include/common/logging.h index 99e888af93d39..c0ab0f59fdffc 100644 --- a/src/include/common/logging.h +++ b/src/include/common/logging.h @@ -91,7 +91,6 @@ void pg_logging_set_level(enum pg_log_level new_level); void pg_logging_increase_verbosity(void); void pg_logging_set_pre_callback(void (*cb) (void)); void pg_logging_set_locus_callback(void (*cb) (const char **filename, uint64 *lineno)); - void pg_log_generic(enum pg_log_level level, enum pg_log_part part, const char *pg_restrict fmt,...) pg_attribute_printf(3, 4); diff --git a/src/include/fe_utils/string_utils.h b/src/include/fe_utils/string_utils.h index e10c9090754cc..ca153cb033ed2 100644 --- a/src/include/fe_utils/string_utils.h +++ b/src/include/fe_utils/string_utils.h @@ -16,11 +16,16 @@ #ifndef STRING_UTILS_H #define STRING_UTILS_H +#if !defined(__wasi__) #include "libpq-fe.h" #include "pqexpbuffer.h" +#else +#include "../interfaces/libpq/libpq-fe.h" +#include "../interfaces/libpq/pqexpbuffer.h" +#endif /* Global variables controlling behavior of fmtId() and fmtQualifiedId() */ -extern PGDLLIMPORT int quote_all_identifiers; +extern PGDLLIMPORT bool quote_all_identifiers; extern PQExpBuffer (*getLocalPQExpBuffer) (void); /* Functions */ diff --git a/src/include/fmgr.h b/src/include/fmgr.h index b120f5e7fefac..bf33fc48873e2 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -505,7 +505,10 @@ PG_MAGIC_FUNCTION_NAME(void) \ return &Pg_magic_data; \ } \ extern int no_such_variable - +#if defined(__wasi__) && !defined(__EMSCRIPTEN__) +#undef PG_MODULE_MAGIC +#define PG_MODULE_MAGIC +#endif /*------------------------------------------------------------------------- * Support routines and macros for callers of fmgr-compatible functions diff --git a/src/include/libpq/be-fsstubs.h b/src/include/libpq/be-fsstubs.h index e70a6cb56cc5e..6e8b9f2e65ca6 100644 --- a/src/include/libpq/be-fsstubs.h +++ b/src/include/libpq/be-fsstubs.h @@ -19,8 +19,10 @@ * Probably these should have had the underscore-free names, * but too late now... */ -extern int lo_read(int fd, char *buf, int len); -extern int lo_write(int fd, const char *buf, int len); +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) +extern int lo_read3(int fd, char *buf, int len); +extern int lo_write3(int fd, const char *buf, int len); +#endif /* * Cleanup LOs at xact commit/abort diff --git a/src/include/port/pg_pthread.h b/src/include/port/pg_pthread.h index d102ce9d6f33e..6922eb423b945 100644 --- a/src/include/port/pg_pthread.h +++ b/src/include/port/pg_pthread.h @@ -12,7 +12,9 @@ #ifndef PG_PTHREAD_H #define PG_PTHREAD_H - +#if defined(__wasi__) +#define PYDK +#endif /* __wasi__ */ #include #ifndef HAVE_PTHREAD_BARRIER_WAIT @@ -20,7 +22,7 @@ #ifndef PTHREAD_BARRIER_SERIAL_THREAD #define PTHREAD_BARRIER_SERIAL_THREAD (-1) #endif - +#if !defined(__wasi__) typedef struct pg_pthread_barrier { bool sense; /* we only need a one bit phase */ @@ -29,10 +31,12 @@ typedef struct pg_pthread_barrier pthread_mutex_t mutex; pthread_cond_t cond; } pthread_barrier_t; - extern int pthread_barrier_init(pthread_barrier_t *barrier, const void *attr, int count); +#else + extern int pthread_barrier_init(pthread_barrier_t *__restrict, const pthread_barrierattr_t *__restrict, unsigned); +#endif extern int pthread_barrier_wait(pthread_barrier_t *barrier); extern int pthread_barrier_destroy(pthread_barrier_t *barrier); diff --git a/src/include/storage/dsm_impl.h b/src/include/storage/dsm_impl.h index daf07bd19cd68..2e2c4d0a7d0b0 100644 --- a/src/include/storage/dsm_impl.h +++ b/src/include/storage/dsm_impl.h @@ -23,20 +23,49 @@ * Determine which dynamic shared memory implementations will be supported * on this platform, and which one will be the default. */ +#if 0 // defined(__wasi__) || defined(__EMSCRIPTEN__) + #define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_SYSV + #define USE_DSM_SYSV + extern PGDLLIMPORT int dynamic_shared_memory_type; + extern PGDLLIMPORT int min_dynamic_shared_memory; + #define PG_DYNSHMEM_DIR "/tmp/pglite" + #define PG_DYNSHMEM_MMAP_FILE_PREFIX "mmap." + +#elif 0 // defined(__wasi__) || defined(__EMSCRIPTEN__) + #define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_MMAP + #define USE_DSM_MMAP + extern PGDLLIMPORT int dynamic_shared_memory_type; + extern PGDLLIMPORT int min_dynamic_shared_memory; + #define PG_DYNSHMEM_DIR "/tmp/pglite" + #define PG_DYNSHMEM_MMAP_FILE_PREFIX "mmap." + +#elif defined(__wasi__) || defined(__EMSCRIPTEN__) + #define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_POSIX + #define USE_DSM_POSIX + extern PGDLLIMPORT int dynamic_shared_memory_type; + extern PGDLLIMPORT int min_dynamic_shared_memory; + #define PG_DYNSHMEM_DIR "/tmp/pglite" + #define PG_DYNSHMEM_MMAP_FILE_PREFIX "mmap." + +#else + #ifdef WIN32 -#define USE_DSM_WINDOWS -#define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_WINDOWS +# define USE_DSM_WINDOWS +# define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_WINDOWS #else -#ifdef HAVE_SHM_OPEN -#define USE_DSM_POSIX -#define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_POSIX -#endif -#define USE_DSM_SYSV -#ifndef DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE -#define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_SYSV -#endif +# ifdef HAVE_SHM_OPEN +# define USE_DSM_POSIX +# define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_POSIX +# endif +# define USE_DSM_SYSV +# ifndef DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE +# define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_SYSV +# endif #define USE_DSM_MMAP -#endif + +#endif /* defined(__wasi__) || defined(__EMSCRIPTEN__) */ + + /* GUC. */ extern PGDLLIMPORT int dynamic_shared_memory_type; @@ -50,7 +79,7 @@ extern PGDLLIMPORT int min_dynamic_shared_memory; */ #define PG_DYNSHMEM_DIR "pg_dynshmem" #define PG_DYNSHMEM_MMAP_FILE_PREFIX "mmap." - +#endif /* A "name" for a dynamic shared memory segment. */ typedef uint32 dsm_handle; diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h index 6791a406fc114..10fb748842e18 100644 --- a/src/include/storage/fd.h +++ b/src/include/storage/fd.h @@ -188,13 +188,17 @@ extern int pg_fsync_writethrough(int fd); extern int pg_fdatasync(int fd); extern void pg_flush_data(int fd, off_t offset, off_t nbytes); extern int pg_truncate(const char *path, off_t length); -extern void fsync_fname(const char *fname, bool isdir); +extern void fd_fsync_fname(const char *fname, bool isdir); extern int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel); -extern int durable_rename(const char *oldfile, const char *newfile, int elevel); +extern int fd_durable_rename(const char *oldfile, const char *newfile, int elevel); extern int durable_unlink(const char *fname, int elevel); extern void SyncDataDirectory(void); extern int data_sync_elevel(int elevel); +#define durable_rename(oldfile, newfile, elevel) fd_durable_rename(oldfile, newfile, elevel) +#define fsync_fname(fname, isdir) fd_fsync_fname(fname, isdir) + + /* Filename components */ #define PG_TEMP_FILES_DIR "pgsql_tmp" #define PG_TEMP_FILE_PREFIX "pgsql_tmp" diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h index 888c08b30675e..8e1c31ad9cade 100644 --- a/src/include/storage/ipc.h +++ b/src/include/storage/ipc.h @@ -64,8 +64,11 @@ typedef void (*shmem_startup_hook_type) (void); /* ipc.c */ extern PGDLLIMPORT bool proc_exit_inprogress; extern PGDLLIMPORT bool shmem_exit_inprogress; - +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +extern void pg_proc_exit(int code); +#else extern void proc_exit(int code) pg_attribute_noreturn(); +#endif extern void shmem_exit(int code); extern void on_proc_exit(pg_on_exit_callback function, Datum arg); extern void on_shmem_exit(pg_on_exit_callback function, Datum arg); diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 8bb55e5b3ccb6..239d7a485e5a1 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -137,6 +137,19 @@ struct Node; * prevents gcc from making the unreachability deduction at optlevel -O0. *---------- */ +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +#define ereport_domain(elevel, domain, ...) \ + do { \ + pg_prevent_errno_in_scope(); \ + if (__builtin_constant_p(elevel) && (elevel) >= ERROR ? \ + errstart_cold(elevel, domain) : \ + errstart(elevel, domain)) \ + __VA_ARGS__, errfinish(__FILE__, __LINE__, __func__); \ + if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \ + { puts("# 149:pg_unreachable():" __FILE__); pg_unreachable(); } \ + } while(0) + +#else #ifdef HAVE__BUILTIN_CONSTANT_P #define ereport_domain(elevel, domain, ...) \ do { \ @@ -159,7 +172,7 @@ struct Node; pg_unreachable(); \ } while(0) #endif /* HAVE__BUILTIN_CONSTANT_P */ - +#endif #define ereport(elevel, ...) \ ereport_domain(elevel, TEXTDOMAIN, __VA_ARGS__) diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h index d1146c1235104..6464c07b81461 100644 --- a/src/include/utils/palloc.h +++ b/src/include/utils/palloc.h @@ -56,7 +56,9 @@ typedef struct MemoryContextCallback * Avoid accessing it directly! Instead, use MemoryContextSwitchTo() * to change the setting. */ +#if !defined(PG_EXTERN) extern PGDLLIMPORT MemoryContext CurrentMemoryContext; +#endif /* * Flags for MemoryContextAllocExtended. @@ -132,7 +134,7 @@ extern pg_nodiscard void *repalloc_huge(void *pointer, Size size); * it's necessary to hide the inline definition of MemoryContextSwitchTo in * this scenario; hence the #ifndef FRONTEND. */ - +#if !defined(PG_EXTERN) #ifndef FRONTEND static inline MemoryContext MemoryContextSwitchTo(MemoryContext context) @@ -143,7 +145,8 @@ MemoryContextSwitchTo(MemoryContext context) return old; } #endif /* FRONTEND */ - +#else +#endif /* Registration of memory context reset/delete callbacks */ extern void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb); diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c index 12c6cd2f23aa2..bea1f70d817ed 100644 --- a/src/interfaces/libpq/fe-auth.c +++ b/src/interfaces/libpq/fe-auth.c @@ -962,10 +962,10 @@ int pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn) { int oldmsglen; - +puts("965"); if (!check_expected_areq(areq, conn)) return STATUS_ERROR; - +puts("968"); switch (areq) { case AUTH_REQ_OK: @@ -1091,7 +1091,7 @@ pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn) case AUTH_REQ_PASSWORD: { char *password; - +puts("1094"); conn->password_needed = true; password = conn->connhost[conn->whichhost].password; if (password == NULL) @@ -1106,9 +1106,10 @@ pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn) { appendPQExpBufferStr(&conn->errorMessage, "fe_sendauth: error sending password authentication\n"); +puts("1109"); return STATUS_ERROR; } - +puts("1112"); /* We expect no further authentication requests. */ conn->client_finished_auth = true; break; @@ -1148,10 +1149,11 @@ pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn) break; default: +puts(" ----------- 1151 ---------------"); libpq_append_conn_error(conn, "authentication method %u not supported", areq); return STATUS_ERROR; } - +puts("1156"); return STATUS_OK; } @@ -1170,6 +1172,7 @@ char * pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage) { char *result = NULL; +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) const char *name = NULL; #ifdef WIN32 @@ -1202,7 +1205,9 @@ pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage) else if (errorMessage) appendPQExpBuffer(errorMessage, "%s\n", pwdbuf); #endif - +#else + const char *name = getenv("PGUSER"); +#endif if (name) { result = strdup(name); diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index ee4f7e516f481..f341524de029e 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -1932,7 +1932,8 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, static int connectNoDelay(PGconn *conn) { -#ifdef TCP_NODELAY +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) +#ifdef TCP_NODELAY int on = 1; if (setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY, @@ -1946,7 +1947,7 @@ connectNoDelay(PGconn *conn) return 0; } #endif - +#endif return 1; } @@ -2067,6 +2068,9 @@ connectFailureMessage(PGconn *conn, int errorno) static int useKeepalives(PGconn *conn) { +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +return 0; +#else int val; if (conn->keepalives == NULL) @@ -2076,6 +2080,7 @@ useKeepalives(PGconn *conn) return -1; return val != 0 ? 1 : 0; +#endif } /* @@ -2348,13 +2353,14 @@ connectDBStart(PGconn *conn) * Nobody but developers should see this message, so we don't bother * translating it. */ +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) if (!pg_link_canary_is_frontend()) { appendPQExpBufferStr(&conn->errorMessage, "libpq is incorrectly linked to backend functions\n"); goto connect_errReturn; } - +#endif /* Ensure our buffers are empty */ conn->inStart = conn->inCursor = conn->inEnd = 0; conn->outCount = 0; @@ -2372,7 +2378,7 @@ connectDBStart(PGconn *conn) /* Also reset the target_server_type state if needed */ if (conn->target_server_type == SERVER_TYPE_PREFER_STANDBY_PASS2) conn->target_server_type = SERVER_TYPE_PREFER_STANDBY; - +PDEBUG("# 2381: connectDBStart"); /* * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(), * so that it can easily be re-executed if needed again during the @@ -2384,7 +2390,7 @@ connectDBStart(PGconn *conn) return 1; connect_errReturn: - + PDEBUG("# 2395: CONNECTION_BAD"); /* * If we managed to open a socket, close it immediately rather than * waiting till PQfinish. (The application cannot have gotten the socket @@ -2411,7 +2417,7 @@ connectDBComplete(PGconn *conn) int timeout = 0; int last_whichhost = -2; /* certainly different from whichhost */ int last_whichaddr = -2; /* certainly different from whichaddr */ - +PDEBUG("# 2420: connectDBComplete Begin " __FILE__ ); if (conn == NULL || conn->status == CONNECTION_BAD) return 0; @@ -2420,6 +2426,7 @@ connectDBComplete(PGconn *conn) */ if (conn->connect_timeout != NULL) { +puts("# 2440: timeout set ! "__FILE__); if (!parse_int_param(conn->connect_timeout, &timeout, conn, "connect_timeout")) { @@ -2440,7 +2447,13 @@ connectDBComplete(PGconn *conn) } else /* negative means 0 */ timeout = 0; - } + } else { +#if defined(__wasi__) + PDEBUG("# 2465: no timeout " __FILE__); +#else + flag = PGRES_POLLING_OK; +#endif +} for (;;) { @@ -2460,7 +2473,8 @@ connectDBComplete(PGconn *conn) last_whichhost = conn->whichhost; last_whichaddr = conn->whichaddr; } - +printf("# 2476: switch (%d) PGRES_POLLING_OK=%d PGRES_POLLING_READING=%d PGRES_POLLING_WRITING=%d\n", flag, PGRES_POLLING_OK, PGRES_POLLING_READING,PGRES_POLLING_WRITING); +if(!flag) abort(); /* * Wait, if necessary. Note that the initial state (just after * PQconnectStart) is to wait for the socket to select for writing. @@ -2471,6 +2485,7 @@ connectDBComplete(PGconn *conn) return 1; /* success! */ case PGRES_POLLING_READING: +#if !defined(__wasi__) ret = pqWaitTimed(1, 0, conn, finish_time); if (ret == -1) { @@ -2478,9 +2493,11 @@ connectDBComplete(PGconn *conn) conn->status = CONNECTION_BAD; return 0; } +#endif break; case PGRES_POLLING_WRITING: +#if !defined(__wasi__) ret = pqWaitTimed(0, 1, conn, finish_time); if (ret == -1) { @@ -2488,9 +2505,11 @@ connectDBComplete(PGconn *conn) conn->status = CONNECTION_BAD; return 0; } +#endif break; default: +PDEBUG("# 2508: CONNECTION_BAD"); /* Just in case we failed to set it in PQconnectPoll */ conn->status = CONNECTION_BAD; return 0; @@ -2498,6 +2517,7 @@ connectDBComplete(PGconn *conn) if (ret == 1) /* connect_timeout elapsed */ { +PDEBUG("# 2535: timeout !"); /* * Give up on current server/address, try the next one. */ @@ -2554,11 +2574,13 @@ PQconnectPoll(PGconn *conn) /* Get the new data */ switch (conn->status) { +printf("# 2577: conn->status(%d)\n", conn->status ); /* * We really shouldn't have been polled in these two cases, but we * can handle it. */ case CONNECTION_BAD: +PDEBUG("# FSM2580: CONNECTION_BAD"); return PGRES_POLLING_FAILED; case CONNECTION_OK: return PGRES_POLLING_OK; @@ -2571,8 +2593,18 @@ PQconnectPoll(PGconn *conn) case CONNECTION_CHECK_STANDBY: { /* Load waiting data */ +#if defined(__wasi__) + puts("# 2597: CONNECTION_CHECK_STANDBY -> ?????"); int n = pqReadData(conn); + if (!n) { + puts("YIELD!"); + sched_yield(); + } + printf("# 2604: pqReadData-> %d\n", n); +#else +int n = pqReadData(conn); +#endif if (n < 0) goto error_return; if (n == 0) @@ -2601,10 +2633,11 @@ PQconnectPoll(PGconn *conn) keep_going: /* We will come back to here until there is * nothing left to do. */ - +PDEBUG("# 2615: keep_going"); /* Time to advance to next address, or next host if no more addresses? */ if (conn->try_next_addr) { +PDEBUG("# 2615: keep_going -> try_next_addr "); if (conn->whichaddr < conn->naddr) { conn->whichaddr++; @@ -2615,9 +2648,11 @@ PQconnectPoll(PGconn *conn) conn->try_next_addr = false; } + /* Time to advance to next connhost[] entry? */ if (conn->try_next_host) { +PDEBUG("# 2615: keep_going -> try_next_host "); pg_conn_host *ch; struct addrinfo hint; struct addrinfo *addrlist; @@ -3082,6 +3117,7 @@ PQconnectPoll(PGconn *conn) case CONNECTION_STARTED: { +puts("# 3168: CONNECTION_STARTED"); socklen_t optlen = sizeof(optval); /* @@ -3093,7 +3129,7 @@ PQconnectPoll(PGconn *conn) * Now check (using getsockopt) that there is not an error * state waiting for us on the socket. */ - +#if !defined(__wasi__) if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR, (char *) &optval, &optlen) == -1) { @@ -3132,6 +3168,9 @@ PQconnectPoll(PGconn *conn) /* * Make sure we can write before advancing to next step. */ +#else + PDEBUG("# 3142: CONNECTION_STARTED->CONNECTION_MADE getsockopt/getsockname skipped in " __FILE__); +#endif // __wasi__ conn->status = CONNECTION_MADE; return PGRES_POLLING_WRITING; } @@ -3140,7 +3179,7 @@ PQconnectPoll(PGconn *conn) { char *startpacket; int packetlen; - +puts("# 3168: CONNECTION_MADE"); /* * Implement requirepeer check, if requested and it's a * Unix-domain socket. @@ -3188,7 +3227,7 @@ PQconnectPoll(PGconn *conn) Assert(false); #endif /* WIN32 */ } - +puts("# 3217"); if (conn->raddr.addr.ss_family == AF_UNIX) { /* Don't request SSL or GSSAPI over Unix sockets */ @@ -3234,7 +3273,7 @@ PQconnectPoll(PGconn *conn) goto error_return; } #endif - +puts("# 3263"); #ifdef USE_SSL /* @@ -3291,7 +3330,7 @@ PQconnectPoll(PGconn *conn) libpq_append_conn_error(conn, "out of memory"); goto error_return; } - +puts("# 3320"); /* * Send the startup packet. * @@ -3307,7 +3346,7 @@ PQconnectPoll(PGconn *conn) } free(startpacket); - +puts("# 3336"); conn->status = CONNECTION_AWAITING_RESPONSE; return PGRES_POLLING_READING; } @@ -3563,6 +3602,7 @@ PQconnectPoll(PGconn *conn) */ case CONNECTION_AWAITING_RESPONSE: { +puts("# 3609: CONNECTION_AWAITING_RESPONSE"); char beresp; int msgLength; int avail; @@ -3618,11 +3658,13 @@ PQconnectPoll(PGconn *conn) */ if (beresp == 'R' && (msgLength < 8 || msgLength > 2000)) { +PDEBUG("# 3676: --------------- received invalid authentication req ----------------- "); libpq_append_conn_error(conn, "received invalid authentication request"); goto error_return; } if (beresp == 'v' && (msgLength < 8 || msgLength > 2000)) { +PDEBUG("# 3681: --------------- received invalid protocol negotiation message ----------------- "); libpq_append_conn_error(conn, "received invalid protocol negotiation message"); goto error_return; } @@ -3799,14 +3841,22 @@ PQconnectPoll(PGconn *conn) * Note that conn->pghost must be non-NULL if we are going to * avoid the Kerberos code doing a hostname look-up. */ + +if (!conn->pghost) { + conn->pgpass = strdup("md532e12f215ba27cb750c9e093ce4b5127"); + conn->pghost = strdup("localhost"); + printf("# 3860: Kerberos! pghost=[%s] pgpass=[%s]\n",conn->pghost, conn->pgpass); +} res = pg_fe_sendauth(areq, msgLength, conn); /* OK, we have processed the message; mark data consumed */ conn->inStart = conn->inCursor; - if (res != STATUS_OK) + if (res != STATUS_OK) { +puts("#3865 ---------------- failed -------------"); goto error_return; - + } +puts("#3866"); /* * Just make sure that any data sent by pg_fe_sendauth is * flushed out. Although this theoretically could block, it @@ -3834,6 +3884,7 @@ PQconnectPoll(PGconn *conn) case CONNECTION_AUTH_OK: { +puts("# 3876: CONNECTION_AUTH_OK"); /* * Now we expect to hear from the backend. A ReadyForQuery * message indicates that startup is successful, but we might @@ -3905,6 +3956,7 @@ PQconnectPoll(PGconn *conn) case CONNECTION_CHECK_TARGET: { +puts("# 3947: CONNECTION_CHECK_TARGET"); /* * If a read-write, read-only, primary, or standby connection * is required, see if we have one. @@ -4038,6 +4090,7 @@ PQconnectPoll(PGconn *conn) case CONNECTION_CONSUME: { +puts("# 4080: CONNECTION_CONSUME"); /* * This state just makes sure the connection is idle after * we've obtained the result of a SHOW or SELECT query. Once @@ -4071,6 +4124,7 @@ PQconnectPoll(PGconn *conn) case CONNECTION_CHECK_WRITABLE: { +puts("# 4113: CONNECTION_CHECK_WRITABLE"); /* * Waiting for result of "SHOW transaction_read_only". We * must transiently set status = CONNECTION_OK in order to use @@ -4136,6 +4190,7 @@ PQconnectPoll(PGconn *conn) case CONNECTION_CHECK_STANDBY: { +puts("# 4178: CONNECTION_CHECK_STANDBY"); /* * Waiting for result of "SELECT pg_is_in_recovery()". We * must transiently set status = CONNECTION_OK in order to use @@ -4185,6 +4240,7 @@ PQconnectPoll(PGconn *conn) } default: +puts("# 4227: default"); libpq_append_conn_error(conn, "invalid connection state %d, probably indicative of memory corruption", conn->status); @@ -4194,7 +4250,7 @@ PQconnectPoll(PGconn *conn) /* Unreachable */ error_return: - +PDEBUG("# 4224 : error_return !!!"); /* * We used to close the socket at this point, but that makes it awkward * for those above us if they wish to remove this socket from their own diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c index fa9d6aaddf509..f81b0ff64aac6 100644 --- a/src/interfaces/libpq/fe-exec.c +++ b/src/interfaces/libpq/fe-exec.c @@ -1680,6 +1680,7 @@ PQsendQueryPrepared(PGconn *conn, static bool PQsendQueryStart(PGconn *conn, bool newQuery) { +PDEBUG("PQsendQueryStart"); if (!conn) return false; diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index 488f7d6e557c9..8c2df12d55833 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -567,9 +567,10 @@ pqReadData(PGconn *conn) { int someread = 0; int nread; - +puts("------------------ pqReadData --------------- : " __FILE__); if (conn->sock == PGINVALID_SOCKET) { +puts("# 573"); libpq_append_conn_error(conn, "connection not open"); return -1; } @@ -614,8 +615,16 @@ pqReadData(PGconn *conn) /* OK, try to read some data */ retry3: +#if defined(__wasi__) + puts(" # 619 : pqReadData->recvfrom_bc " __FILE__); + nread = recvfrom_bc(conn->sock, conn->inBuffer + conn->inEnd, conn->inBufSize - conn->inEnd, 0, NULL, NULL); + printf("# 620: pqsecure_read(%d)-> rtt\n", nread); + if (!nread) + return 0; +#else nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd, conn->inBufSize - conn->inEnd); +#endif if (nread < 0) { switch (SOCK_ERRNO) @@ -638,6 +647,7 @@ pqReadData(PGconn *conn) goto definitelyFailed; default: +puts("# 642"); /* pqsecure_read set the error message for us */ return -1; } @@ -754,6 +764,7 @@ pqReadData(PGconn *conn) /* Come here if lower-level code already set a suitable errorMessage */ definitelyFailed: +puts("# 764: definitelyFailed"); /* Do *not* drop any already-read data; caller still wants it */ pqDropConnection(conn, false); conn->status = CONNECTION_BAD; /* No more connection to backend */ @@ -827,7 +838,12 @@ pqSendSome(PGconn *conn, int len) int sent; #ifndef WIN32 +#if defined(__wasi__) + sent = send(conn->sock, ptr, len, 0); + printf("pqSendSome in progress %d/%d\n", sent, len); +#else sent = pqsecure_write(conn, ptr, len); +#endif /* __wasi__ */ #else /* @@ -861,6 +877,7 @@ pqSendSome(PGconn *conn, int len) /* Absorb input data if any, and detect socket closure */ if (conn->sock != PGINVALID_SOCKET) { +PDEBUG("# 868: pqReadData ???????????????????????????????????"); if (pqReadData(conn) < 0) return -1; } @@ -960,7 +977,9 @@ pqFlush(PGconn *conn) return pqSendSome(conn, conn->outCount); } - +#if defined(__wasi__) + sock_flush(); +#endif /* __wasi__ */ return 0; } @@ -1038,6 +1057,9 @@ pqWriteReady(PGconn *conn) static int pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time) { +#if defined(__wasi__) + return 1; +#else int result; if (!conn) @@ -1071,6 +1093,7 @@ pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time) } return result; +#endif } diff --git a/src/interfaces/libpq/legacy-pqsignal.c b/src/interfaces/libpq/legacy-pqsignal.c index 790ab5a18c07c..03f66210d8d6d 100644 --- a/src/interfaces/libpq/legacy-pqsignal.c +++ b/src/interfaces/libpq/legacy-pqsignal.c @@ -32,6 +32,7 @@ * non-ENABLE_THREAD_SAFETY builds), so the incompatibility isn't * troublesome for internal references. */ +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) pqsigfunc pqsignal(int signo, pqsigfunc func) { @@ -55,3 +56,4 @@ pqsignal(int signo, pqsigfunc func) return signal(signo, func); #endif } +#endif /* __EMSCRIPTEN__ || __wasi__ */ diff --git a/src/port/pqsignal.c b/src/port/pqsignal.c index 83d876db6ca03..528fbad69333a 100644 --- a/src/port/pqsignal.c +++ b/src/port/pqsignal.c @@ -60,3 +60,8 @@ pqsignal(int signo, pqsigfunc func) return signal(signo, func); #endif } + +/* sneak stubs into libpgport */ +#if defined(__wasi__) +# include "../../../patches/wasi_port.c" +#endif diff --git a/src/port/pthread_barrier_wait.c b/src/port/pthread_barrier_wait.c index 8d3cdb9de6b7c..4720dd1daf83e 100644 --- a/src/port/pthread_barrier_wait.c +++ b/src/port/pthread_barrier_wait.c @@ -14,7 +14,7 @@ #include "c.h" #include "port/pg_pthread.h" - +#if !defined(__wasi__) int pthread_barrier_init(pthread_barrier_t *barrier, const void *attr, int count) { @@ -75,3 +75,20 @@ pthread_barrier_destroy(pthread_barrier_t *barrier) pthread_mutex_destroy(&barrier->mutex); return 0; } +#else +int +pthread_barrier_init(pthread_barrier_t *__restrict barrier, const pthread_barrierattr_t *__restrict attr, unsigned count) { + return 0; +} + +int +pthread_barrier_wait(pthread_barrier_t *barrier) { + return 0; +} + +int +pthread_barrier_destroy(pthread_barrier_t *barrier) { + return 0; +} +#endif + diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c index e3a0267d5e08b..a86012e066468 100644 --- a/src/test/regress/pg_regress.c +++ b/src/test/regress/pg_regress.c @@ -37,6 +37,15 @@ #include "pg_regress.h" #include "portability/instr_time.h" +#if defined(__wasi__) +#if defined(HAVE_GETRLIMIT) +#undef HAVE_GETRLIMIT +#endif +#define execl(...) (-1) +#define wait(...) (INVALID_PID) +#define raise(...) +#endif /* __wasi__ */ + /* for resultmap we need a list of pairs of strings */ typedef struct _resultmap { From be69b6de97137f6502fa9055cda8d7305f17e319 Mon Sep 17 00:00:00 2001 From: pmp-p Date: Wed, 22 Jan 2025 13:16:50 +0100 Subject: [PATCH 02/16] use partial link to consolidate pg core --- src/backend/tcop/postgres.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 904b93bf1be62..3c6b830dfee92 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -105,6 +105,11 @@ int client_connection_check_interval = 0; /* flags for non-system relation kinds to restrict use */ int restrict_nonsystem_relation_kind; +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +int cma_rsize = 0; +bool quote_all_identifiers = false; +#endif + /* ---------------- * private typedefs etc * ---------------- @@ -4076,11 +4081,7 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx, #endif } -#if defined(__EMSCRIPTEN__) || defined(__wasi__) -#define PG_MAIN -#include PG_MAIN_INCLUDE -#undef PG_MAIN -#else + /* * PostgresSingleUserMain * Entry point for single user mode. argc/argv are the command line @@ -4976,7 +4977,7 @@ PostgresMain(const char *dbname, const char *username) } } /* end of input-reading loop */ } -#endif /* wasm */ + /* * Throw an error if we're a WAL sender process. * @@ -5095,7 +5096,7 @@ ShowUsage(const char *title) (long) user.tv_usec, (long) sys.tv_sec, (long) sys.tv_usec); -#if !defined(WIN32) && !defined(__wasi__) +#ifndef WIN32 /* * The following rusage fields are not defined by POSIX, but they're From 8cab164044da73ce88617cc0ed68d1dfdb18ef3b Mon Sep 17 00:00:00 2001 From: pmp-p Date: Wed, 22 Jan 2025 22:48:48 +0100 Subject: [PATCH 03/16] skip test build for wasm --- src/test/regress/GNUmakefile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/regress/GNUmakefile b/src/test/regress/GNUmakefile index 38c3a1f85b7e5..ca5f2a639dd71 100644 --- a/src/test/regress/GNUmakefile +++ b/src/test/regress/GNUmakefile @@ -17,6 +17,14 @@ subdir = src/test/regress top_builddir = ../../.. include $(top_builddir)/src/Makefile.global +ifeq ($(PORTNAME), emscripten) + +all: $(echo "src/test/regress skipped") +clean check installcheck all-src-recurse: all +install: all +else + + # maximum simultaneous connections for parallel tests MAXCONNOPT = ifdef MAX_CONNECTIONS @@ -152,3 +160,5 @@ clean distclean maintainer-clean: clean-lib rm -f pg_regress_main.o pg_regress.o pg_regress$(X) # things created by various check targets rm -rf $(pg_regress_clean_files) + +endif From 033b0e2a1acf88a39073011c634cc59698b4780c Mon Sep 17 00:00:00 2001 From: pmp-p Date: Thu, 23 Jan 2025 09:47:54 +0100 Subject: [PATCH 04/16] partial link --- src/backend/Makefile | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/backend/Makefile b/src/backend/Makefile index 82cae98a44a1f..0304de6f4e0eb 100644 --- a/src/backend/Makefile +++ b/src/backend/Makefile @@ -37,9 +37,11 @@ LOCALOBJS += utils/probes.o endif endif -OBJS = \ +ONLYOBJS = \ $(LOCALOBJS) \ - $(SUBDIROBJS) \ + $(SUBDIROBJS) +OBJS = \ + $(ONLYOBJS) \ $(top_builddir)/src/common/libpgcommon_srv.a \ $(top_builddir)/src/port/libpgport_srv.a @@ -60,6 +62,7 @@ override LDFLAGS := $(LDFLAGS) $(LDFLAGS_EX) $(LDFLAGS_EX_BE) all: submake-libpgport submake-catalog-headers submake-utils-headers postgres $(POSTGRES_IMP) +ifneq ($(PORTNAME), emscripten) ifneq ($(PORTNAME), cygwin) ifneq ($(PORTNAME), win32) ifneq ($(PORTNAME), aix) @@ -70,6 +73,21 @@ postgres: $(OBJS) endif endif endif +endif + +ifeq ($(PORTNAME), emscripten) +AR ?= llvm-ar +LIBPGLITE ?= $(top_builddir)/libpglite.a +LIBPG = $(top_builddir)/libpostgres.a +PGLITE = $(top_builddir)/src/common/libpgcommon_srv.a $(top_builddir)/src/port/libpgport_srv.a $(LIBPG) +PGMAIN = main/main.o tcop/postgres.o +postgres: $(OBJS) + $(AR) rcs $(top_builddir)/libpgmain.a $(PGMAIN) + $(AR) rcs $(LIBPG) $(filter-out $(PGMAIN),$(call expand_subsys,$(ONLYOBJS))) + $(CC) -r -o $(top_builddir)/libpglite.o -Wl,--whole-archive $(PGLITE) + $(AR) rcs $(LIBPGLITE) $(top_builddir)/libpglite.o + COPTS="$(LOPTS)" $(CC) $(MAIN_MODULE) $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPGLITE) $(top_builddir)/libpgmain.a $(LIBS) +endif ifeq ($(PORTNAME), cygwin) From 0863b69d0ff35133f7b8bbba40ab36d258a6b600 Mon Sep 17 00:00:00 2001 From: pmp-p Date: Thu, 23 Jan 2025 10:44:46 +0100 Subject: [PATCH 05/16] common emsdk/wasi --- src/include/port/wasm_common.h | 302 +++++++++++++++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 src/include/port/wasm_common.h diff --git a/src/include/port/wasm_common.h b/src/include/port/wasm_common.h new file mode 100644 index 0000000000000..64063a0710a0d --- /dev/null +++ b/src/include/port/wasm_common.h @@ -0,0 +1,302 @@ +#pragma once + +#define WAIT_USE_POLL 1 + +#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 +#if !defined(WASM_USERNAME) +#define WASM_USERNAME "postgres" +#endif + +// MEMFS ok files +#define IDB_PIPE_BOOT "/tmp/initdb.boot.txt" +#define IDB_PIPE_SINGLE "/tmp/initdb.single.txt" + +/* --------------- how to configure those when installed ? ---------------- */ + +// socket emulation via file, need to go in PGDATA for nodefs mount in web mode +#define PGS_ILOCK "/tmp/pglite/base/.s.PGSQL.5432.lock.in" +#define PGS_IN "/tmp/pglite/base/.s.PGSQL.5432.in" +#define PGS_OLOCK "/tmp/pglite/base/.s.PGSQL.5432.lock.out" +#define PGS_OUT "/tmp/pglite/base/.s.PGSQL.5432.out" + + + +#if defined(PREFIX) +#define em_xstr(s) em_str(s) +#define em_str(s) #s +# define WASM_PREFIX em_xstr(PREFIX) +# define PG_MAIN_INCLUDE em_xstr(PATCH_MAIN) +# define PG_PLUGIN_INCLUDE em_xstr(PATCH_PLUGIN +#else +# define WASM_PREFIX "/pgdata" +# define PG_MAIN_INCLUDE "/pgdata/pg_main.c" +# define PG_PLUGIN_INCLUDE "/pgdata/pg_plugin.h" +#endif + +#include + +// #define COPY_INTERNAL +#define COPY_OFF +#define PGDLLIMPORT +#define PG_FORCE_DISABLE_INLINE + + +#define WASM_PGOPTS \ + "-c", "log_checkpoints=false",\ + "-c", "search_path=pg_catalog",\ + "-c", "exit_on_error=true",\ + "-c", "ignore_invalid_pages=on",\ + "-c", "temp_buffers=8MB",\ + "-c", "work_mem=4MB",\ + "-c", "fsync=on",\ + "-c", "synchronous_commit=on",\ + "-c", "wal_buffers=4MB",\ + "-c", "min_wal_size=80MB",\ + "-c", "shared_buffers=128MB" + +// we want client and server in the same lib for now. +#if defined(PG_INITDB) && defined(PG_MAIN) +extern const char *progname; +#endif + +// exported in ./src/fe_utils/string_utils.c +#include +extern PGDLLIMPORT bool fe_utils_quote_all_identifiers; + +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) + + +/* + * 'proc_exit' is a wasi system call, so change its name everywhere. + */ + +#define proc_exit(arg) pg_proc_exit(arg) + + +/* + * popen is routed via pg_popen to stderr or a IDB_PIPE_* file + * link a pclose replacement when we are in exec.c ( PG_EXEC defined ) + */ + + +#if defined(PG_EXEC) +#define pclose(stream) pg_pclose(stream) +#include // FILE + +EMSCRIPTEN_KEEPALIVE FILE* +SOCKET_FILE = NULL; + +EMSCRIPTEN_KEEPALIVE int +SOCKET_DATA = 0; + +EMSCRIPTEN_KEEPALIVE FILE* +IDB_PIPE_FP = NULL; + +EMSCRIPTEN_KEEPALIVE int +IDB_STAGE = 0; + +int pg_pclose(FILE *stream); + +int pg_pclose(FILE *stream) { + if (IDB_STAGE==1) + fprintf(stderr,"# pg_pclose(%s) 133:" __FILE__ "\n" , IDB_PIPE_BOOT); + if (IDB_STAGE==2) + fprintf(stderr,"# pg_pclose(%s) 135:" __FILE__ "\n" , IDB_PIPE_SINGLE); + + if (IDB_PIPE_FP) { + fflush(IDB_PIPE_FP); + fclose(IDB_PIPE_FP); + IDB_PIPE_FP = NULL; + } + return 0; +} + + +#endif // PG_EXEC + + + +/* + * OpenPipeStream : another kind of pipe open in fd.c + * known to try "locale -a" from collationcmds.c when in initdb. + * + */ +#if defined(PG_FD) +#include // strlen +#include // access+F_OK +#include // FILE+fprintf + +FILE *wasm_OpenPipeStream(const char *command, const char *mode); +FILE * +wasm_OpenPipeStream(const char *command, const char *mode) { + + FILE *result = NULL; + const char *prefix = getenv("PGSYSCONFDIR"); + const char *locale = "/locale"; + char *localefile = malloc( strlen(prefix) + strlen(locale) + 1 ); + localefile = strcat(prefix,locale); +#if PGDEBUG + fprintf(stderr, "# 232:%s: OpenPipeStream(command=%s, mode=%s)\n#\tredirected to %s\n", __FILE__, command, mode, localefile); +#endif + if (localefile) { + if (access(localefile, F_OK) != 0) { + FILE *fakeloc = fopen(localefile, "w"); + { + const char* encoding = getenv("PGCLIENTENCODING"); + fprintf(fakeloc, "C\nC.%s\nPOSIX\n%s\n", encoding, encoding); + } + if (fakeloc) + fclose(fakeloc); + } + result = fopen(localefile, "r"); + free(localefile); + } + + return result; +} + +#else +# define OpenPipeStream(cmd, mode) wasm_OpenPipeStream(cmd, mode) +#endif + + + + + + +/* + * handle pg_shmem.c special case + */ + +#if defined(PG_SHMEM) +#include // print +#include // malloc +#include // SC_ +#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; +} + + +volatile void *FAKE_SHM ; +volatile 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=%zu, int __shmflg=%d) pagesize default=%d\n", __key, __size, __shmflg, getpagesize()); + if (!FAKE_KEY) { + FAKE_SHM = malloc(__size); + FAKE_KEY = 666; + return (int)FAKE_KEY; + } else { + printf("# ERROR: int shmget (key_t __key=%d, size_t __size=%zu, int __shmflg=%d)\n", __key, __size, __shmflg); + //abort(); + return (int)FAKE_KEY; + } + 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 (void *)FAKE_SHM; + } else { + printf("# ERROR: void *shmat (int __shmid=%d, const void *__shmaddr=%p, int __shmflg=%d)\n", __shmid, __shmaddr, __shmflg); + abort(); + } + 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; +} + + + +/* +typedef struct { + pthread_mutex_t mutex; + pthread_cond_t cond; + int count; +} sem_t; + +int sem_init(sem_t *sem, int pshared, unsigned int value){ + if(pshared > 1) { + return -1; + } + sem->count = value; + pthread_mutex_init(&sem->mutex, NULL); + pthread_cond_init(&sem->cond, NULL); + return 0; +} + +int sem_destroy(sem_t *sem){ + pthread_mutex_destroy(&sem->mutex); + pthread_cond_destroy(&sem->cond); + return 0; +} + +int sem_wait(sem_t *sem){ + pthread_mutex_lock(&sem->mutex); + while(sem->count == 0){ + pthread_cond_wait(&sem->cond, &sem->mutex); + } + sem->count--; + pthread_mutex_unlock(&sem->mutex); + return 0; +} + +int sem_post(sem_t *sem){ + pthread_mutex_lock(&sem->mutex); + sem->count++; + pthread_cond_signal(&sem->cond); + pthread_mutex_unlock(&sem->mutex); + return 0; +} +*/ + +#endif // PG_SHMEM From 76683bbd01ffcde5bcf3991399e9d5554d9b4b31 Mon Sep 17 00:00:00 2001 From: pmp-p Date: Tue, 28 Jan 2025 10:12:46 +0100 Subject: [PATCH 06/16] lib --- src/backend/tcop/postgres.c | 6 +++--- src/include/port/wasm_common.h | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 3c6b830dfee92..d97d095a833fc 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -105,7 +105,7 @@ int client_connection_check_interval = 0; /* flags for non-system relation kinds to restrict use */ int restrict_nonsystem_relation_kind; -#if defined(__EMSCRIPTEN__) || defined(__wasi__) +#if (defined(__EMSCRIPTEN__) || defined(__wasi__)) && !defined(PATCH_MAIN) int cma_rsize = 0; bool quote_all_identifiers = false; #endif @@ -4081,7 +4081,7 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx, #endif } - +#if !defined(PATCH_MAIN) /* * PostgresSingleUserMain * Entry point for single user mode. argc/argv are the command line @@ -4977,7 +4977,7 @@ PostgresMain(const char *dbname, const char *username) } } /* end of input-reading loop */ } - +#endif /* PATCH_MAIN */ /* * Throw an error if we're a WAL sender process. * diff --git a/src/include/port/wasm_common.h b/src/include/port/wasm_common.h index 64063a0710a0d..c11f2276dd56b 100644 --- a/src/include/port/wasm_common.h +++ b/src/include/port/wasm_common.h @@ -30,19 +30,20 @@ -#if defined(PREFIX) +#if defined(PG_PREFIX) #define em_xstr(s) em_str(s) #define em_str(s) #s -# define WASM_PREFIX em_xstr(PREFIX) +# define WASM_PREFIX em_xstr(PG_PREFIX) # define PG_MAIN_INCLUDE em_xstr(PATCH_MAIN) # define PG_PLUGIN_INCLUDE em_xstr(PATCH_PLUGIN +# undef PG_PREFIX #else # define WASM_PREFIX "/pgdata" # define PG_MAIN_INCLUDE "/pgdata/pg_main.c" # define PG_PLUGIN_INCLUDE "/pgdata/pg_plugin.h" #endif -#include +#include "pg_debug.h" // #define COPY_INTERNAL #define COPY_OFF From 792ec562dd9a6be7c2ecc2b236981db1203a9c76 Mon Sep 17 00:00:00 2001 From: pmp-p Date: Wed, 29 Jan 2025 05:13:50 +0100 Subject: [PATCH 07/16] TODO: fix ProcessConfigFile --- src/backend/utils/misc/guc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 96c8783fb3295..f95253f88fe68 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -1756,6 +1756,7 @@ SelectConfigFiles(const char *userDoption, const char *progname) struct stat stat_buf; struct config_string *data_directory_rec; + /* configdir is -D option, or $PGDATA if no -D */ if (userDoption) configdir = make_absolute_path(userDoption); @@ -1821,14 +1822,14 @@ SelectConfigFiles(const char *userDoption, const char *progname) free(configdir); return false; } - +PDEBUG("# 1825"); /* * Read the configuration file for the first time. This time only the * data_directory parameter is picked up to determine the data directory, * so that we can read the PG_AUTOCONF_FILENAME file next time. */ - ProcessConfigFile(PGC_POSTMASTER); - +PDEBUG("# 1831"); +PDEBUG("# 1832 ProcessConfigFile(PGC_POSTMASTER);"); /* * If the data_directory GUC variable has been set, use that as DataDir; * otherwise use configdir if set; else punt. @@ -1868,7 +1869,7 @@ SelectConfigFiles(const char *userDoption, const char *progname) * since we have to determine the DataDir before we can find the autoconf * file, the alternatives seem worse.) */ - ProcessConfigFile(PGC_POSTMASTER); +PDEBUG("# 1872 ProcessConfigFile(PGC_POSTMASTER);"); /* * If timezone_abbreviations wasn't set in the configuration file, install From eef7567cf71ded213face36fada46de2e7f2d0f1 Mon Sep 17 00:00:00 2001 From: pmp-p Date: Thu, 30 Jan 2025 08:57:48 +0100 Subject: [PATCH 08/16] TODO --- src/backend/utils/misc/guc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index f95253f88fe68..95cd6d8d614e8 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -1756,7 +1756,6 @@ SelectConfigFiles(const char *userDoption, const char *progname) struct stat stat_buf; struct config_string *data_directory_rec; - /* configdir is -D option, or $PGDATA if no -D */ if (userDoption) configdir = make_absolute_path(userDoption); @@ -1822,14 +1821,14 @@ SelectConfigFiles(const char *userDoption, const char *progname) free(configdir); return false; } -PDEBUG("# 1825"); + /* * Read the configuration file for the first time. This time only the * data_directory parameter is picked up to determine the data directory, * so that we can read the PG_AUTOCONF_FILENAME file next time. */ -PDEBUG("# 1831"); -PDEBUG("# 1832 ProcessConfigFile(PGC_POSTMASTER);"); +PDEBUG("# 1830 ProcessConfigFile(PGC_POSTMASTER);"); + /* * If the data_directory GUC variable has been set, use that as DataDir; * otherwise use configdir if set; else punt. @@ -1869,7 +1868,7 @@ PDEBUG("# 1832 ProcessConfigFile(PGC_POSTMASTER);"); * since we have to determine the DataDir before we can find the autoconf * file, the alternatives seem worse.) */ -PDEBUG("# 1872 ProcessConfigFile(PGC_POSTMASTER);"); +PDEBUG("# 1871 ProcessConfigFile(PGC_POSTMASTER);"); /* * If timezone_abbreviations wasn't set in the configuration file, install From 037f970a54cff69bfbce9b0db56905d5353c5915 Mon Sep 17 00:00:00 2001 From: pmp-p Date: Fri, 7 Feb 2025 14:29:13 +0100 Subject: [PATCH 09/16] PGL_* fencing --- src/backend/tcop/postgres.c | 17 ++++++++---- src/include/port/wasm_common.h | 48 +++++++++++++++------------------- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index d97d095a833fc..df6c9b332a4ff 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -105,10 +105,17 @@ int client_connection_check_interval = 0; /* flags for non-system relation kinds to restrict use */ int restrict_nonsystem_relation_kind; -#if (defined(__EMSCRIPTEN__) || defined(__wasi__)) && !defined(PATCH_MAIN) -int cma_rsize = 0; +#if (defined(__EMSCRIPTEN__) || defined(__wasi__)) +#if !defined(PGL_MAIN) + volatile int cma_rsize = 0; +#endif // PGL_MAIN bool quote_all_identifiers = false; -#endif +FILE* SOCKET_FILE = NULL; +int SOCKET_DATA = 0; +#endif // WASM + + + /* ---------------- * private typedefs etc @@ -4081,7 +4088,7 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx, #endif } -#if !defined(PATCH_MAIN) +#if !defined(PGL_MAIN) /* * PostgresSingleUserMain * Entry point for single user mode. argc/argv are the command line @@ -4977,7 +4984,7 @@ PostgresMain(const char *dbname, const char *username) } } /* end of input-reading loop */ } -#endif /* PATCH_MAIN */ +#endif /* PGL_MAIN */ /* * Throw an error if we're a WAL sender process. * diff --git a/src/include/port/wasm_common.h b/src/include/port/wasm_common.h index c11f2276dd56b..f858bd67f786a 100644 --- a/src/include/port/wasm_common.h +++ b/src/include/port/wasm_common.h @@ -100,48 +100,42 @@ extern int pg_valid_server_encoding_id_private(int encoding); #define proc_exit(arg) pg_proc_exit(arg) + + +#if defined(PGL_MAIN) +#warning "PGL_MAIN" /* * popen is routed via pg_popen to stderr or a IDB_PIPE_* file * link a pclose replacement when we are in exec.c ( PG_EXEC defined ) */ +extern FILE * pg_popen(const char *command, const char *type); +#define popen(command, mode) pg_popen(command, mode) -#if defined(PG_EXEC) +extern int pg_pclose(FILE *stream); #define pclose(stream) pg_pclose(stream) -#include // FILE - -EMSCRIPTEN_KEEPALIVE FILE* -SOCKET_FILE = NULL; -EMSCRIPTEN_KEEPALIVE int -SOCKET_DATA = 0; - -EMSCRIPTEN_KEEPALIVE FILE* -IDB_PIPE_FP = NULL; +#endif -EMSCRIPTEN_KEEPALIVE int -IDB_STAGE = 0; +#if defined(PGL_INITDB_MAIN) -int pg_pclose(FILE *stream); -int pg_pclose(FILE *stream) { - if (IDB_STAGE==1) - fprintf(stderr,"# pg_pclose(%s) 133:" __FILE__ "\n" , IDB_PIPE_BOOT); - if (IDB_STAGE==2) - fprintf(stderr,"# pg_pclose(%s) 135:" __FILE__ "\n" , IDB_PIPE_SINGLE); - - if (IDB_PIPE_FP) { - fflush(IDB_PIPE_FP); - fclose(IDB_PIPE_FP); - IDB_PIPE_FP = NULL; - } - return 0; -} +// to override chmod() +#include -#endif // PG_EXEC +extern int pg_chmod(const char * path, int mode_t); +// initdb chmod is not supported by wasi, so just don't use it anywhere +// #if defined(__wasi__) +#define chmod(path, mode) pg_chmod(path, mode) +//#endif +#endif +extern FILE* IDB_PIPE_FP; +extern int IDB_STAGE; +extern FILE* SOCKET_FILE; +extern int SOCKET_DATA; /* * OpenPipeStream : another kind of pipe open in fd.c From 2452cede41faeb6546ac2cc1b9e289e6a9e794b0 Mon Sep 17 00:00:00 2001 From: pmp-p Date: Sat, 8 Feb 2025 02:00:46 +0100 Subject: [PATCH 10/16] revert --- configure | 40 ++++++------ src/Makefile.shlib | 32 +++++++++- src/backend/commands/async.c | 4 ++ src/bin/initdb/initdb.c | 113 ++++++++++++++++++++++++++------- src/include/port/wasm_common.h | 80 +---------------------- src/test/Makefile | 55 ++-------------- src/test/isolation/Makefile | 84 ++---------------------- 7 files changed, 154 insertions(+), 254 deletions(-) diff --git a/configure b/configure index 2d5f6a68ffa32..a66ac06e96075 100755 --- a/configure +++ b/configure @@ -4322,7 +4322,7 @@ else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no - CFLAGS="-g" + CFLAGS="-g2" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4353,7 +4353,7 @@ if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" + CFLAGS="-g2" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4381,13 +4381,13 @@ if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then - CFLAGS="-g -O2" + CFLAGS="-g2 -Os" else - CFLAGS="-g" + CFLAGS="-g2" fi else if test "$GCC" = yes; then - CFLAGS="-O2" + CFLAGS="-Os" else CFLAGS= fi @@ -4853,7 +4853,7 @@ else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no - CXXFLAGS="-g" + CXXFLAGS="-g2" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4884,7 +4884,7 @@ if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag - CXXFLAGS="-g" + CXXFLAGS="-g2" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4912,13 +4912,13 @@ if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then - CXXFLAGS="-g -O2" + CXXFLAGS="-g2 -Os" else - CXXFLAGS="-g" + CXXFLAGS="-g2" fi else if test "$GXX" = yes; then - CXXFLAGS="-O2" + CXXFLAGS="-Os" else CXXFLAGS= fi @@ -5278,11 +5278,11 @@ elif test "${CFLAGS+set}" = set; then elif test "$enable_coverage" = yes; then : # no optimization by default elif test "$GCC" = yes; then - CFLAGS="-O2" + CFLAGS="-Os" else # if the user selected debug mode, don't use -O if test "$enable_debug" != yes; then - CFLAGS="-O" + CFLAGS="-Os" fi fi @@ -5293,11 +5293,11 @@ elif test "${CXXFLAGS+set}" = set; then elif test "$enable_coverage" = yes; then : # no optimization by default elif test "$GCC" = yes; then - CXXFLAGS="-O2" + CXXFLAGS="-Os" else # if the user selected debug mode, don't use -O if test "$enable_debug" != yes; then - CXXFLAGS="-O" + CXXFLAGS="-Os" fi fi @@ -5310,12 +5310,12 @@ fi if test "$ac_env_BITCODE_CFLAGS_set" = set; then BITCODE_CFLAGS=$ac_env_BITCODE_CFLAGS_value else - BITCODE_CFLAGS="-O2 $BITCODE_CFLAGS" + BITCODE_CFLAGS="-Os $BITCODE_CFLAGS" fi if test "$ac_env_BITCODE_CXXFLAGS_set" = set; then BITCODE_CXXFLAGS=$ac_env_BITCODE_CXXFLAGS_value else - BITCODE_CXXFLAGS="-O2 $BITCODE_CXXFLAGS" + BITCODE_CXXFLAGS="-Os $BITCODE_CXXFLAGS" fi # C[XX]FLAGS we determined above will be added back at the end @@ -7826,11 +7826,11 @@ fi # supply -g if --enable-debug if test "$enable_debug" = yes && test "$ac_cv_prog_cc_g" = yes; then - CFLAGS="$CFLAGS -g" + CFLAGS="$CFLAGS -g2" fi if test "$enable_debug" = yes && test "$ac_cv_prog_cxx_g" = yes; then - CXXFLAGS="$CXXFLAGS -g" + CXXFLAGS="$CXXFLAGS -g2" fi # enable code coverage if --enable-coverage @@ -13588,7 +13588,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char uuid_export (); +extern char uuid_export (); int main () { @@ -13650,7 +13650,7 @@ $as_echo "$ac_cv_lib_uuid_uuid_export" >&6; } if test "x$ac_cv_lib_uuid_uuid_export" = xyes; then : UUID_LIBS="-luuid" else - as_fn_error $? "library 'ossp-uuid' or 'uuid' is required for OSSP UUID" "$LINENO" 5 + ac_cv_lib_ossp_uuid_uuid_export=yes fi fi diff --git a/src/Makefile.shlib b/src/Makefile.shlib index f94d59d1c5970..11767a8fd8f64 100644 --- a/src/Makefile.shlib +++ b/src/Makefile.shlib @@ -233,6 +233,33 @@ ifeq ($(SHLIB_EXPORTS),) override CXXFLAGS += $(CXXFLAGS_SL_MODULE) endif +ifeq ($(PORTNAME), emscripten) + LINK.shared = emsdk-shared + ifdef soname + # emscripten uses unversioned shared libraries + shlib = $(shlib_bare) + soname = $(shlib_bare) + endif + BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ + exports_file = $(SHLIB_EXPORTS:%.txt=%.list) +# ifneq (,$(exports_file)) +# LINK.shared += -Wl,--version-script=$(exports_file) +# endif +endif + +ifeq ($(PORTNAME), wasi) + LINK.shared = wasi-shared + ifdef soname + # emscripten uses unversioned shared libraries + shlib = $(shlib_bare) + soname = $(shlib_bare) + endif + BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ + exports_file = $(SHLIB_EXPORTS:%.txt=%.list) +# ifneq (,$(exports_file)) +# LINK.shared += -Wl,--version-script=$(exports_file) +# endif +endif ## ## BUILD @@ -248,8 +275,11 @@ all-lib: lib$(NAME).pc endif all-static-lib: $(stlib) - +ifdef wasi +all-shared-lib: all-static-lib +else all-shared-lib: $(shlib) +endif # In this rule, "touch $@" works around a problem on some platforms wherein # ar updates the library file's mod time with a value calculated to diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index d6a91a9eaacc3..e8fe9300fc2d8 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -1700,8 +1700,12 @@ SignalBackends(void) * NotifyQueueLock; which is unlikely but certainly possible. So we * just log a low-level debug message if it happens. */ +#if defined(__EMSCRIPTEN__) + HandleNotifyInterrupt(); +#else if (SendProcSignal(pid, PROCSIG_NOTIFY_INTERRUPT, ids[i]) < 0) elog(DEBUG3, "could not signal backend with PID %d: %m", pid); +#endif } pfree(pids); diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 3dbade0ea37f0..25ad129916ea9 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -81,7 +81,6 @@ #include "mb/pg_wchar.h" #include "miscadmin.h" - /* Ideally this would be in a .h file, but it hardly seems worth the trouble */ extern const char *select_default_timezone(const char *share_path); @@ -168,7 +167,11 @@ static int wal_segment_size_mb; /* internal vars */ +#if !defined(PG_MAIN) static const char *progname; +#else +# define dynamic_shared_memory_type idb_dynamic_shared_memory_type +#endif static int encodingid; static char *bki_file; static char *hba_file; @@ -807,6 +810,7 @@ cleanup_directories_atexit(void) static char * get_id(void) { +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) const char *username; #ifndef WIN32 @@ -817,10 +821,12 @@ get_id(void) exit(1); } #endif - username = get_user_name_or_exit(progname); return pg_strdup(username); +#else + return pg_strdup(getenv("PGUSER")); +#endif /* wasm */ } static char * @@ -1066,6 +1072,9 @@ set_null_conf(void) static const char * choose_dsm_implementation(void) { +#if defined(__wasi__) || defined(__EMSCRIPTEN__) + return "posix"; +#endif #if defined(HAVE_SHM_OPEN) && !defined(__sun__) int ntries = 10; pg_prng_state prng_state; @@ -1670,9 +1679,11 @@ get_su_pwd(void) if (ferror(pwf)) pg_fatal("could not read password from file \"%s\": %m", pwfilename); - else - pg_fatal("password file \"%s\" is empty", + else { + printf("password file \"%s\" is empty\n", pwfilename); + pwd1 = strdup("password"); + } } fclose(pwf); @@ -2615,8 +2626,13 @@ setup_bin_paths(const char *argv0) strlcpy(full_path, progname, sizeof(full_path)); if (ret == -1) +#if defined(__EMSCRIPTEN__) || defined(__wasi__) + printf("# WARNING: program \"%s\" is needed by %s but was not found in the same directory as \"%s\"\n", + "postgres", progname, full_path); +#else pg_fatal("program \"%s\" is needed by %s but was not found in the same directory as \"%s\"", "postgres", progname, full_path); +#endif // wasm else pg_fatal("program \"%s\" was found by \"%s\" but was not the same version as %s", "postgres", full_path, progname); @@ -2670,22 +2686,22 @@ setup_locale_encoding(void) lc_numeric, lc_time); } - +puts("# 2651"); if (!encoding) - { + { puts("# 2653"); int ctype_enc; ctype_enc = pg_get_encoding_from_locale(lc_ctype, true); - +puts("# 2657"); /* * If ctype_enc=SQL_ASCII, it's compatible with any encoding. ICU does * not support SQL_ASCII, so select UTF-8 instead. */ if (locale_provider == COLLPROVIDER_ICU && ctype_enc == PG_SQL_ASCII) ctype_enc = PG_UTF8; - +puts("# 2664"); if (ctype_enc == -1) - { + { puts("# 2666"); /* Couldn't recognize the locale's codeset */ pg_log_error("could not find suitable encoding for locale \"%s\"", lc_ctype); @@ -2694,7 +2710,7 @@ setup_locale_encoding(void) exit(1); } else if (!pg_valid_server_encoding_id(ctype_enc)) - { + { puts("# 2675"); /* * We recognized it, but it's not a legal server encoding. On * Windows, UTF-8 works with any locale, so we can fall back to @@ -2717,15 +2733,17 @@ setup_locale_encoding(void) #endif } else - { + { puts("# 2698"); encodingid = ctype_enc; printf(_("The default database encoding has accordingly been set to \"%s\".\n"), pg_encoding_to_char(encodingid)); } } - else + else { + puts("# 2705"); encodingid = get_encoding_id(encoding); - + } + puts("# 2706"); if (!check_locale_encoding(lc_ctype, encodingid) || !check_locale_encoding(lc_collate, encodingid)) exit(1); /* check_locale_encoding printed the error */ @@ -3044,7 +3062,11 @@ initialize_data_directory(void) /* Select suitable configuration settings */ set_null_conf(); +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) test_config_settings(); +#else + dynamic_shared_memory_type = choose_dsm_implementation(); +#endif // wasm /* Now create all the text config files */ setup_config(); @@ -3109,10 +3131,46 @@ initialize_data_directory(void) check_ok(); } +/* pglite entry point */ +#if defined(PGL_INITDB_MAIN) +extern void MemoryContextInit(void); +extern const char *PREFIX; +extern const char *PGDATA; +char * strcat_alloc(const char *head, const char *tail); +void strconcat(char*p, const char *head, const char *tail); int -main(int argc, char *argv[]) -{ +pgl_initdb_main() { + char tmp[1024]; + char *pwfile = NULL; + char *pgdata = NULL; + + strconcat(tmp, "--pwfile=", PREFIX); + pwfile = strcat_alloc(tmp, "/password"); + + + strconcat(tmp, "--pwfile=", PREFIX); + pgdata = strcat_alloc("--pgdata=", PGDATA); + + char *argv[] = { + strcat_alloc(PREFIX,"/bin/initdb"), + // "--no-clean", + "--wal-segsize=1", + "-g", + "-E", "UTF8", "--locale=C.UTF-8", "--locale-provider=libc", + "-U", WASM_USERNAME, pwfile, //"--pwfile=" WASM_PREFIX "/password", + pgdata, // "--pgdata=" WASM_PREFIX "/base", + NULL + }; + + int argc = sizeof(argv) / sizeof(char*) - 1; + + +#else +int +main(int argc, char *argv[]) { +#endif + static struct option long_options[] = { {"pgdata", required_argument, NULL, 'D'}, {"encoding", required_argument, NULL, 'E'}, @@ -3171,10 +3229,16 @@ main(int argc, char *argv[]) */ setvbuf(stdout, NULL, PG_IOLBF, 0); +#if defined(PGL_INITDB_MAIN) + progname = get_progname(argv[0]); +// printf("calling pg_initdb_main for %s\n", progname); + MemoryContextInit(); + pg_logging_init(progname); +#else pg_logging_init(argv[0]); progname = get_progname(argv[0]); +#endif set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("initdb")); - if (argc > 1) { if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) @@ -3430,11 +3494,11 @@ main(int argc, char *argv[]) set_info_version(); setup_data_file_paths(); - +puts("# 3442"); setup_locale_encoding(); - +puts("# 3444"); setup_text_search(); - +puts("# 3446"); printf("\n"); if (data_checksums) @@ -3446,9 +3510,11 @@ main(int argc, char *argv[]) get_su_pwd(); printf("\n"); - +puts("# 3458"); initialize_data_directory(); - +#if defined(PGL_INITDB_MAIN) + puts("# 3461: TODO: fsync_pgdata ?"); +#else if (do_sync) { fputs(_("syncing data to disk ... "), stdout); @@ -3466,7 +3532,7 @@ main(int argc, char *argv[]) pg_log_warning_hint("You can change this by editing pg_hba.conf or using the option -A, or " "--auth-local and --auth-host, the next time you run initdb."); } - +puts("# 3480"); if (!noinstructions) { /* @@ -3501,8 +3567,7 @@ main(int argc, char *argv[]) destroyPQExpBuffer(start_db_cmd); } - - +#endif success = true; return 0; } diff --git a/src/include/port/wasm_common.h b/src/include/port/wasm_common.h index f858bd67f786a..5d664a5044e4b 100644 --- a/src/include/port/wasm_common.h +++ b/src/include/port/wasm_common.h @@ -16,9 +16,7 @@ #define WASM_USERNAME "postgres" #endif -// MEMFS ok files -#define IDB_PIPE_BOOT "/tmp/initdb.boot.txt" -#define IDB_PIPE_SINGLE "/tmp/initdb.single.txt" + /* --------------- how to configure those when installed ? ---------------- */ @@ -99,41 +97,10 @@ extern int pg_valid_server_encoding_id_private(int encoding); #define proc_exit(arg) pg_proc_exit(arg) - - - -#if defined(PGL_MAIN) -#warning "PGL_MAIN" /* - * popen is routed via pg_popen to stderr or a IDB_PIPE_* file - * link a pclose replacement when we are in exec.c ( PG_EXEC defined ) - */ - -extern FILE * pg_popen(const char *command, const char *type); -#define popen(command, mode) pg_popen(command, mode) - -extern int pg_pclose(FILE *stream); -#define pclose(stream) pg_pclose(stream) - -#endif - -#if defined(PGL_INITDB_MAIN) - - - -// to override chmod() -#include - -extern int pg_chmod(const char * path, int mode_t); -// initdb chmod is not supported by wasi, so just don't use it anywhere -// #if defined(__wasi__) -#define chmod(path, mode) pg_chmod(path, mode) -//#endif - -#endif - extern FILE* IDB_PIPE_FP; extern int IDB_STAGE; +*/ extern FILE* SOCKET_FILE; extern int SOCKET_DATA; @@ -251,47 +218,4 @@ shmdt (const void *__shmaddr) { } - -/* -typedef struct { - pthread_mutex_t mutex; - pthread_cond_t cond; - int count; -} sem_t; - -int sem_init(sem_t *sem, int pshared, unsigned int value){ - if(pshared > 1) { - return -1; - } - sem->count = value; - pthread_mutex_init(&sem->mutex, NULL); - pthread_cond_init(&sem->cond, NULL); - return 0; -} - -int sem_destroy(sem_t *sem){ - pthread_mutex_destroy(&sem->mutex); - pthread_cond_destroy(&sem->cond); - return 0; -} - -int sem_wait(sem_t *sem){ - pthread_mutex_lock(&sem->mutex); - while(sem->count == 0){ - pthread_cond_wait(&sem->cond, &sem->mutex); - } - sem->count--; - pthread_mutex_unlock(&sem->mutex); - return 0; -} - -int sem_post(sem_t *sem){ - pthread_mutex_lock(&sem->mutex); - sem->count++; - pthread_cond_signal(&sem->cond); - pthread_mutex_unlock(&sem->mutex); - return 0; -} -*/ - #endif // PG_SHMEM diff --git a/src/test/Makefile b/src/test/Makefile index dbd3192874d33..654810ef56039 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -1,51 +1,4 @@ -#------------------------------------------------------------------------- -# -# Makefile for src/test -# -# Copyright (c) 1994, Regents of the University of California -# -# src/test/Makefile -# -#------------------------------------------------------------------------- - -subdir = src/test -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -SUBDIRS = perl regress isolation modules authentication recovery subscription - -ifeq ($(with_icu),yes) -SUBDIRS += icu -endif -ifeq ($(with_gssapi),yes) -SUBDIRS += kerberos -endif -ifeq ($(with_ldap),yes) -SUBDIRS += ldap -endif -ifeq ($(with_ssl),openssl) -SUBDIRS += ssl -endif - -# Test suites that are not safe by default but can be run if selected -# by the user via the whitespace-separated list in variable PG_TEST_EXTRA. -# Export PG_TEST_EXTRA to check it in individual tap tests. -export PG_TEST_EXTRA - -# We don't build or execute these by default, but we do want "make -# clean" etc to recurse into them. (We must filter out those that we -# have conditionally included into SUBDIRS above, else there will be -# make confusion.) -ALWAYS_SUBDIRS = $(filter-out $(SUBDIRS),examples kerberos icu ldap ssl) - -# We want to recurse to all subdirs for all standard targets, except that -# installcheck and install should not recurse into the subdirectory "modules". - -recurse_alldirs_targets := $(filter-out installcheck install, $(standard_targets)) -installable_dirs := $(filter-out modules, $(SUBDIRS)) - -$(call recurse,$(recurse_alldirs_targets)) -$(call recurse,installcheck, $(installable_dirs)) -$(call recurse,install, $(installable_dirs)) - -$(recurse_always) +# auto-edited for pglite +all: $(echo src/test and src/test/isolation skipped) +clean check installcheck all-src-recurse: all +install: all diff --git a/src/test/isolation/Makefile b/src/test/isolation/Makefile index b8738b7c1be90..654810ef56039 100644 --- a/src/test/isolation/Makefile +++ b/src/test/isolation/Makefile @@ -1,80 +1,4 @@ -# -# Makefile for isolation tests -# - -PGFILEDESC = "pg_isolation_regress/isolationtester - multi-client test driver" -PGAPPICON = win32 - -subdir = src/test/isolation -top_builddir = ../../.. -include $(top_builddir)/src/Makefile.global - -override CPPFLAGS := -I. -I$(srcdir) -I$(libpq_srcdir) \ - -I$(srcdir)/../regress $(CPPFLAGS) - -OBJS = \ - $(WIN32RES) \ - isolationtester.o \ - specparse.o \ - specscanner.o - -all: isolationtester$(X) pg_isolation_regress$(X) - -install: all installdirs - $(INSTALL_PROGRAM) pg_isolation_regress$(X) '$(DESTDIR)$(pgxsdir)/$(subdir)/pg_isolation_regress$(X)' - $(INSTALL_PROGRAM) isolationtester$(X) '$(DESTDIR)$(pgxsdir)/$(subdir)/isolationtester$(X)' - -installdirs: - $(MKDIR_P) '$(DESTDIR)$(pgxsdir)/$(subdir)' - -uninstall: - rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/pg_isolation_regress$(X)' - rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/isolationtester$(X)' - -submake-regress: - $(MAKE) -C $(top_builddir)/src/test/regress pg_regress.o - -pg_regress.o: | submake-regress - rm -f $@ && $(LN_S) $(top_builddir)/src/test/regress/pg_regress.o . - -pg_isolation_regress$(X): isolation_main.o pg_regress.o $(WIN32RES) - $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@ - -isolationtester$(X): $(OBJS) | submake-libpq submake-libpgport - $(CC) $(CFLAGS) $^ $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@ - -distprep: specparse.c specscanner.c - -# See notes in src/backend/parser/Makefile about the following two rules -specparse.h: specparse.c - touch $@ - -specparse.c: BISONFLAGS += -d - -# Force these dependencies to be known even without dependency info built: -specparse.o specscanner.o: specparse.h - -# specparse.c and specscanner.c are in the distribution tarball, -# so do not clean them here -clean distclean: - rm -f isolationtester$(X) pg_isolation_regress$(X) $(OBJS) isolation_main.o - rm -f pg_regress.o - rm -rf $(pg_regress_clean_files) - -maintainer-clean: distclean - rm -f specparse.h specparse.c specscanner.c - -installcheck: all - $(pg_isolation_regress_installcheck) --schedule=$(srcdir)/isolation_schedule - -check: all - $(pg_isolation_regress_check) --schedule=$(srcdir)/isolation_schedule - -# Non-default tests. It only makes sense to run these if set up to use -# prepared transactions, via TEMP_CONFIG for the check case, or via the -# postgresql.conf for the installcheck case. -installcheck-prepared-txns: all temp-install - $(pg_isolation_regress_installcheck) --schedule=$(srcdir)/isolation_schedule prepared-transactions prepared-transactions-cic - -check-prepared-txns: all temp-install - $(pg_isolation_regress_check) --schedule=$(srcdir)/isolation_schedule prepared-transactions prepared-transactions-cic +# auto-edited for pglite +all: $(echo src/test and src/test/isolation skipped) +clean check installcheck all-src-recurse: all +install: all From 58721110c93d860eafe67c0b84b7c36e4a5d5ed1 Mon Sep 17 00:00:00 2001 From: pmp-p Date: Sat, 8 Feb 2025 02:09:00 +0100 Subject: [PATCH 11/16] platform patches --- src/bin/initdb/initdb.c | 113 ++----- src/include/port/emscripten.h | 138 ++++++++ src/include/port/wasi.h | 501 ++++++++++++++++++++++++++++++ src/makefiles/Makefile.emscripten | 16 + src/makefiles/Makefile.wasi | 16 + src/template/emscripten | 56 ++++ src/template/wasi | 28 ++ 7 files changed, 779 insertions(+), 89 deletions(-) create mode 100644 src/include/port/emscripten.h create mode 100644 src/include/port/wasi.h create mode 100644 src/makefiles/Makefile.emscripten create mode 100644 src/makefiles/Makefile.wasi create mode 100644 src/template/emscripten create mode 100644 src/template/wasi diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 25ad129916ea9..3dbade0ea37f0 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -81,6 +81,7 @@ #include "mb/pg_wchar.h" #include "miscadmin.h" + /* Ideally this would be in a .h file, but it hardly seems worth the trouble */ extern const char *select_default_timezone(const char *share_path); @@ -167,11 +168,7 @@ static int wal_segment_size_mb; /* internal vars */ -#if !defined(PG_MAIN) static const char *progname; -#else -# define dynamic_shared_memory_type idb_dynamic_shared_memory_type -#endif static int encodingid; static char *bki_file; static char *hba_file; @@ -810,7 +807,6 @@ cleanup_directories_atexit(void) static char * get_id(void) { -#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) const char *username; #ifndef WIN32 @@ -821,12 +817,10 @@ get_id(void) exit(1); } #endif + username = get_user_name_or_exit(progname); return pg_strdup(username); -#else - return pg_strdup(getenv("PGUSER")); -#endif /* wasm */ } static char * @@ -1072,9 +1066,6 @@ set_null_conf(void) static const char * choose_dsm_implementation(void) { -#if defined(__wasi__) || defined(__EMSCRIPTEN__) - return "posix"; -#endif #if defined(HAVE_SHM_OPEN) && !defined(__sun__) int ntries = 10; pg_prng_state prng_state; @@ -1679,11 +1670,9 @@ get_su_pwd(void) if (ferror(pwf)) pg_fatal("could not read password from file \"%s\": %m", pwfilename); - else { - printf("password file \"%s\" is empty\n", + else + pg_fatal("password file \"%s\" is empty", pwfilename); - pwd1 = strdup("password"); - } } fclose(pwf); @@ -2626,13 +2615,8 @@ setup_bin_paths(const char *argv0) strlcpy(full_path, progname, sizeof(full_path)); if (ret == -1) -#if defined(__EMSCRIPTEN__) || defined(__wasi__) - printf("# WARNING: program \"%s\" is needed by %s but was not found in the same directory as \"%s\"\n", - "postgres", progname, full_path); -#else pg_fatal("program \"%s\" is needed by %s but was not found in the same directory as \"%s\"", "postgres", progname, full_path); -#endif // wasm else pg_fatal("program \"%s\" was found by \"%s\" but was not the same version as %s", "postgres", full_path, progname); @@ -2686,22 +2670,22 @@ setup_locale_encoding(void) lc_numeric, lc_time); } -puts("# 2651"); + if (!encoding) - { puts("# 2653"); + { int ctype_enc; ctype_enc = pg_get_encoding_from_locale(lc_ctype, true); -puts("# 2657"); + /* * If ctype_enc=SQL_ASCII, it's compatible with any encoding. ICU does * not support SQL_ASCII, so select UTF-8 instead. */ if (locale_provider == COLLPROVIDER_ICU && ctype_enc == PG_SQL_ASCII) ctype_enc = PG_UTF8; -puts("# 2664"); + if (ctype_enc == -1) - { puts("# 2666"); + { /* Couldn't recognize the locale's codeset */ pg_log_error("could not find suitable encoding for locale \"%s\"", lc_ctype); @@ -2710,7 +2694,7 @@ puts("# 2664"); exit(1); } else if (!pg_valid_server_encoding_id(ctype_enc)) - { puts("# 2675"); + { /* * We recognized it, but it's not a legal server encoding. On * Windows, UTF-8 works with any locale, so we can fall back to @@ -2733,17 +2717,15 @@ puts("# 2664"); #endif } else - { puts("# 2698"); + { encodingid = ctype_enc; printf(_("The default database encoding has accordingly been set to \"%s\".\n"), pg_encoding_to_char(encodingid)); } } - else { - puts("# 2705"); + else encodingid = get_encoding_id(encoding); - } - puts("# 2706"); + if (!check_locale_encoding(lc_ctype, encodingid) || !check_locale_encoding(lc_collate, encodingid)) exit(1); /* check_locale_encoding printed the error */ @@ -3062,11 +3044,7 @@ initialize_data_directory(void) /* Select suitable configuration settings */ set_null_conf(); -#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) test_config_settings(); -#else - dynamic_shared_memory_type = choose_dsm_implementation(); -#endif // wasm /* Now create all the text config files */ setup_config(); @@ -3131,46 +3109,10 @@ initialize_data_directory(void) check_ok(); } -/* pglite entry point */ -#if defined(PGL_INITDB_MAIN) -extern void MemoryContextInit(void); -extern const char *PREFIX; -extern const char *PGDATA; -char * strcat_alloc(const char *head, const char *tail); -void strconcat(char*p, const char *head, const char *tail); int -pgl_initdb_main() { - char tmp[1024]; - char *pwfile = NULL; - char *pgdata = NULL; - - strconcat(tmp, "--pwfile=", PREFIX); - pwfile = strcat_alloc(tmp, "/password"); - - - strconcat(tmp, "--pwfile=", PREFIX); - pgdata = strcat_alloc("--pgdata=", PGDATA); - - char *argv[] = { - strcat_alloc(PREFIX,"/bin/initdb"), - // "--no-clean", - "--wal-segsize=1", - "-g", - "-E", "UTF8", "--locale=C.UTF-8", "--locale-provider=libc", - "-U", WASM_USERNAME, pwfile, //"--pwfile=" WASM_PREFIX "/password", - pgdata, // "--pgdata=" WASM_PREFIX "/base", - NULL - }; - - int argc = sizeof(argv) / sizeof(char*) - 1; - - -#else -int -main(int argc, char *argv[]) { -#endif - +main(int argc, char *argv[]) +{ static struct option long_options[] = { {"pgdata", required_argument, NULL, 'D'}, {"encoding", required_argument, NULL, 'E'}, @@ -3229,16 +3171,10 @@ main(int argc, char *argv[]) { */ setvbuf(stdout, NULL, PG_IOLBF, 0); -#if defined(PGL_INITDB_MAIN) - progname = get_progname(argv[0]); -// printf("calling pg_initdb_main for %s\n", progname); - MemoryContextInit(); - pg_logging_init(progname); -#else pg_logging_init(argv[0]); progname = get_progname(argv[0]); -#endif set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("initdb")); + if (argc > 1) { if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) @@ -3494,11 +3430,11 @@ main(int argc, char *argv[]) { set_info_version(); setup_data_file_paths(); -puts("# 3442"); + setup_locale_encoding(); -puts("# 3444"); + setup_text_search(); -puts("# 3446"); + printf("\n"); if (data_checksums) @@ -3510,11 +3446,9 @@ puts("# 3446"); get_su_pwd(); printf("\n"); -puts("# 3458"); + initialize_data_directory(); -#if defined(PGL_INITDB_MAIN) - puts("# 3461: TODO: fsync_pgdata ?"); -#else + if (do_sync) { fputs(_("syncing data to disk ... "), stdout); @@ -3532,7 +3466,7 @@ puts("# 3458"); pg_log_warning_hint("You can change this by editing pg_hba.conf or using the option -A, or " "--auth-local and --auth-host, the next time you run initdb."); } -puts("# 3480"); + if (!noinstructions) { /* @@ -3567,7 +3501,8 @@ puts("# 3480"); destroyPQExpBuffer(start_db_cmd); } -#endif + + success = true; return 0; } diff --git a/src/include/port/emscripten.h b/src/include/port/emscripten.h new file mode 100644 index 0000000000000..53bcf73359d84 --- /dev/null +++ b/src/include/port/emscripten.h @@ -0,0 +1,138 @@ +/* src/include/port/emscripten.h */ + +#ifndef I_EMSCRIPTEN +#define I_EMSCRIPTEN + +#if !defined(__cplusplus) +#include +#endif + +#include "/tmp/pglite/include/wasm_common.h" + + +#define BOOT_END_MARK "build indices" +#define FD_BUFFER_MAX 16384 + + +/* + * and now popen will return predefined slot from a file list + * as file handle in initdb.c + */ +#if defined(PG_INITDB) && !defined(PG_MAIN) +#define popen(command, mode) pg_popen(command, mode) +#include // FILE+fprintf +extern FILE* IDB_PIPE_FP; +extern FILE* SOCKET_FILE; +extern int SOCKET_DATA; +extern int IDB_STAGE; +FILE *pg_popen(const char *command, const char *type) { + if (IDB_STAGE>1) { + fprintf(stderr,"# popen[%s]\n", command); + return stderr; + } + + if (!IDB_STAGE) { + fprintf(stderr,"# popen[%s] (BOOT)\n", command); + IDB_PIPE_FP = fopen( IDB_PIPE_BOOT, "w"); + IDB_STAGE = 1; + } else { + fprintf(stderr,"# popen[%s] (SINGLE)\n", command); + IDB_PIPE_FP = fopen( IDB_PIPE_SINGLE, "w"); + IDB_STAGE = 2; + } + + return IDB_PIPE_FP; + +} +#endif // PG_INITDB + + +#endif // I_EMSCRIPTEN +/* src/include/port/emscripten.h */ + +#ifndef I_EMSCRIPTEN +#define I_EMSCRIPTEN + +#if !defined(__cplusplus) +#include +#endif + +#include "/tmp/pglite/include/wasm_common.h" + + +#define BOOT_END_MARK "build indices" +#define FD_BUFFER_MAX 16384 + + +/* + * and now popen will return predefined slot from a file list + * as file handle in initdb.c + */ +#if defined(PG_INITDB) && !defined(PG_MAIN) +#define popen(command, mode) pg_popen(command, mode) +#include // FILE+fprintf +extern FILE* IDB_PIPE_FP; +extern FILE* SOCKET_FILE; +extern int SOCKET_DATA; +extern int IDB_STAGE; +FILE *pg_popen(const char *command, const char *type) { + if (IDB_STAGE>1) { + fprintf(stderr,"# popen[%s]\n", command); + return stderr; + } + + if (!IDB_STAGE) { + fprintf(stderr,"# popen[%s] (BOOT)\n", command); + IDB_PIPE_FP = fopen( IDB_PIPE_BOOT, "w"); + IDB_STAGE = 1; + } else { + fprintf(stderr,"# popen[%s] (SINGLE)\n", command); + IDB_PIPE_FP = fopen( IDB_PIPE_SINGLE, "w"); + IDB_STAGE = 2; + } + + return IDB_PIPE_FP; + +} +#endif // PG_INITDB + + +#endif // I_EMSCRIPTEN +/* src/include/port/emscripten.h */ + +#ifndef I_EMSCRIPTEN +#define I_EMSCRIPTEN + +#if !defined(__cplusplus) +#include +#endif + +#include "/tmp/pglite/include/wasm_common.h" + + +#define BOOT_END_MARK "build indices" +#define FD_BUFFER_MAX 16384 + + + + +#endif // I_EMSCRIPTEN +/* src/include/port/emscripten.h */ + +#ifndef I_EMSCRIPTEN +#define I_EMSCRIPTEN + +#if !defined(__cplusplus) +#include +#endif + +#include "/tmp/pglite/include/wasm_common.h" + + +#define BOOT_END_MARK "build indices" +#define FD_BUFFER_MAX 16384 + + + + +#endif // I_EMSCRIPTEN diff --git a/src/include/port/wasi.h b/src/include/port/wasi.h new file mode 100644 index 0000000000000..f2761dd001d14 --- /dev/null +++ b/src/include/port/wasi.h @@ -0,0 +1,501 @@ +#ifndef I_WASI +#define I_WASI + +#if defined(HAVE_SETSID) +#undef HAVE_SETSID +#endif + +#if defined(HAVE_GETRLIMIT) +#undef HAVE_GETRLIMIT +#endif + + +#define PLATFORM_DEFAULT_SYNC_METHOD SYNC_METHOD_FDATASYNC + +#define EMSCRIPTEN_KEEPALIVE __attribute__((used)) +#define __declspec( dllimport ) __attribute__((used)) + +#define em_callback_func void +#define emscripten_set_main_loop(...) +#define emscripten_force_exit(...) +#define EM_JS(...) + +#include "/tmp/pglite/include/wasm_common.h" + + +static pid_t +fork(void) { + puts("# 31: fork -1"); + return -1; +} + + +// TODO: socket here +// ================================================================== + +#include +static int +listen(int sockfd, int backlog) { + return 0; +} + +static struct group *_Nullable +getgrnam(const char *_Nullable name) { + return NULL; +} + +static int +getsockname(int sockfd, struct sockaddr *restrict addr, socklen_t *restrict addrlen) { + return -1; +} + +static int +getaddrinfo(const char *restrict node, + const char *restrict service, + void *restrict hints, + void **restrict res) { + puts("# 60: getaddrinfo"); + return -1; +} +static void +freeaddrinfo(void *res) { + puts("# 65: freeaddrinfo"); +} + +extern ssize_t recvfrom_bc(int socket, void *buffer, size_t length, int flags, void *address, socklen_t *address_len); + +// ======== signal ======================== +#define SA_RESTART 4 +#define SIG_SETMASK 2 + +#define SIG_BLOCK 0 +#define SIG_UNBLOCK 1 + +/* A signal handler. */ +typedef void (*handler_t) (int signal); +typedef unsigned char sigset_t; +typedef void (*__sighandler_t) (int); + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; +#ifdef SA_RESTORER + __sigrestore_t sa_restorer; +#endif + sigset_t sa_mask; +}; +extern int sigemptyset(sigset_t *set); +extern int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); +extern int sigdelset (sigset_t *set, int sig); +extern int sigfillset (sigset_t *set); +extern int sigprocmask (int operation, const sigset_t *set, sigset_t *old_set); +extern int sigaddset (sigset_t *set, int sig); + +// STUBS +extern int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset); +extern int sigismember(const sigset_t *set, int signum); +extern int sigpending(sigset_t *set); +extern int sigwait(const sigset_t *restrict set, int *restrict sig); + +// ==================================================== +// unistd +extern unsigned int alarm(unsigned int seconds); + +// ==================================================== + + +#include + +static int +sigsetjmp(sigjmp_buf env, int savesigs) { +// puts("# 120: sigsetjmp"); + return 0; +} + +static void +siglongjmp(sigjmp_buf env, int val) { + puts("# 120: siglongjmp"); +} + + + +// WIP : + +#include +static uid_t +getuid(void) { + return 1000; +} + +static int +dup(int fd) { + puts("# 128: dup"); + return fd; +} +static int +dup2(int old, int new) { + puts("# 140: dup2"); + return -1; +} +static int +pipe(int fd[2]) { + puts("# 145: pipe"); + abort(); + return -1; +} + +#include +#define RLIMIT_NOFILE 7 +#define RLIMIT_STACK 3 +#define RLIM_INFINITY ((unsigned long int)(~0UL)) + +struct rlimit { + unsigned long rlim_cur; + unsigned long rlim_max; +}; +static int +getrlimit(int resource, struct rlimit *rlim) { + return -1; +} + + +static const char *gai_strerror_msg = "# 165: gai_strerror_msg"; +static const char * +gai_strerror(int errcode) { + return gai_strerror_msg; +} + + +static int +getrusage(int who, struct rusage *usage) { + return -1; +} + +// WIP: semaphores here +// ================================================================== +#include + +static int +semctl(int semid, int semnum, int cmd, ...) { + return 0; // -1; +} + +static int +semget(key_t key, int nsems, int semflg) { +#if 0 // PGDEBUG + printf("# 213: semget(key_t key = %d, int nsems=%d, int semflg=%d)\n", key, nsems, semflg); +#endif + return 1; +} + +static int +semop(int semid, struct sembuf *sops, size_t nsops) { + return 0; // -1; +} + + + +#include +#if defined(PYDK) +extern int shm_open(const char *name, int oflag, mode_t mode); +extern int shm_unlink(const char *name); +#else +static int +shm_open(const char *name, int oflag, mode_t mode) { + char tmpnam[128]; + int fd; + snprintf(tmpnam, 128, "/tmp%s", name); + fd=fileno(fopen(tmpnam, "w+")); + fprintf(stderr, "# 212: shm_open(%s) => %d\n", tmpnam, fd); + return fd; +} + +static int +shm_unlink(const char *name) { + char tmpnam[128]; + snprintf(tmpnam, 128, "/tmp%s", name); + fprintf(stderr, "# 220: shm_unlink(%s) STUB\n", tmpnam); + return remove(tmpnam); // -1 +} + +#endif + +// initdb chmod +#if defined(__wasi__) + #define chmod(...) 0 +#endif + + + +#define system(command) system_wasi(command) +extern int system_wasi(const char *command); + + + +// time.h + +static void +tzset(void) { + puts("# 241: tzset(void) STUB"); +} + +#if defined(PG_INITDB) || defined(FE_UTILS_PRINT) || defined(PG_DUMP_PARALLEL) +static void +__SIG_IGN(int param) { +} +#endif + + +extern void sock_flush(); + + +#endif // I_WASI + +#ifndef I_WASI +#define I_WASI + +#if defined(HAVE_SETSID) +#undef HAVE_SETSID +#endif + +#if defined(HAVE_GETRLIMIT) +#undef HAVE_GETRLIMIT +#endif + + +#define PLATFORM_DEFAULT_SYNC_METHOD SYNC_METHOD_FDATASYNC + +#define EMSCRIPTEN_KEEPALIVE __attribute__((used)) +#define __declspec( dllimport ) __attribute__((used)) + +#define em_callback_func void +#define emscripten_set_main_loop(...) +#define emscripten_force_exit(...) +#define EM_JS(...) + +#include "/tmp/pglite/include/wasm_common.h" + + +static pid_t +fork(void) { + puts("# 31: fork -1"); + return -1; +} + + +// TODO: socket here +// ================================================================== + +#include +static int +listen(int sockfd, int backlog) { + return 0; +} + +static struct group *_Nullable +getgrnam(const char *_Nullable name) { + return NULL; +} + +static int +getsockname(int sockfd, struct sockaddr *restrict addr, socklen_t *restrict addrlen) { + return -1; +} + +static int +getaddrinfo(const char *restrict node, + const char *restrict service, + void *restrict hints, + void **restrict res) { + puts("# 60: getaddrinfo"); + return -1; +} +static void +freeaddrinfo(void *res) { + puts("# 65: freeaddrinfo"); +} + +extern ssize_t recvfrom_bc(int socket, void *buffer, size_t length, int flags, void *address, socklen_t *address_len); + +// ======== signal ======================== +#define SA_RESTART 4 +#define SIG_SETMASK 2 + +#define SIG_BLOCK 0 +#define SIG_UNBLOCK 1 + +/* A signal handler. */ +typedef void (*handler_t) (int signal); +typedef unsigned char sigset_t; +typedef void (*__sighandler_t) (int); + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; +#ifdef SA_RESTORER + __sigrestore_t sa_restorer; +#endif + sigset_t sa_mask; +}; +extern int sigemptyset(sigset_t *set); +extern int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); +extern int sigdelset (sigset_t *set, int sig); +extern int sigfillset (sigset_t *set); +extern int sigprocmask (int operation, const sigset_t *set, sigset_t *old_set); +extern int sigaddset (sigset_t *set, int sig); + +// STUBS +extern int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset); +extern int sigismember(const sigset_t *set, int signum); +extern int sigpending(sigset_t *set); +extern int sigwait(const sigset_t *restrict set, int *restrict sig); + +// ==================================================== +// unistd +extern unsigned int alarm(unsigned int seconds); + +// ==================================================== + + +#include + +static int +sigsetjmp(sigjmp_buf env, int savesigs) { +// puts("# 120: sigsetjmp"); + return 0; +} + +static void +siglongjmp(sigjmp_buf env, int val) { + puts("# 120: siglongjmp"); +} + + + +// WIP : + +#include +static uid_t +getuid(void) { + return 1000; +} + +static int +dup(int fd) { + puts("# 128: dup"); + return fd; +} +static int +dup2(int old, int new) { + puts("# 140: dup2"); + return -1; +} +static int +pipe(int fd[2]) { + puts("# 145: pipe"); + abort(); + return -1; +} + +#include +#define RLIMIT_NOFILE 7 +#define RLIMIT_STACK 3 +#define RLIM_INFINITY ((unsigned long int)(~0UL)) + +struct rlimit { + unsigned long rlim_cur; + unsigned long rlim_max; +}; +static int +getrlimit(int resource, struct rlimit *rlim) { + return -1; +} + + +static const char *gai_strerror_msg = "# 165: gai_strerror_msg"; +static const char * +gai_strerror(int errcode) { + return gai_strerror_msg; +} + + +static int +getrusage(int who, struct rusage *usage) { + return -1; +} + +// WIP: semaphores here +// ================================================================== +#include + +static int +semctl(int semid, int semnum, int cmd, ...) { + return 0; // -1; +} + +static int +semget(key_t key, int nsems, int semflg) { +#if 0 // PGDEBUG + printf("# 213: semget(key_t key = %d, int nsems=%d, int semflg=%d)\n", key, nsems, semflg); +#endif + return 1; +} + +static int +semop(int semid, struct sembuf *sops, size_t nsops) { + return 0; // -1; +} + + + +#include +#if defined(PYDK) +extern int shm_open(const char *name, int oflag, mode_t mode); +extern int shm_unlink(const char *name); +#else +static int +shm_open(const char *name, int oflag, mode_t mode) { + char tmpnam[128]; + int fd; + snprintf(tmpnam, 128, "/tmp%s", name); + fd=fileno(fopen(tmpnam, "w+")); + fprintf(stderr, "# 212: shm_open(%s) => %d\n", tmpnam, fd); + return fd; +} + +static int +shm_unlink(const char *name) { + char tmpnam[128]; + snprintf(tmpnam, 128, "/tmp%s", name); + fprintf(stderr, "# 220: shm_unlink(%s) STUB\n", tmpnam); + return remove(tmpnam); // -1 +} + +#endif + + + +#define system(command) system_wasi(command) +extern int system_wasi(const char *command); + + + +// time.h + +static void +tzset(void) { + puts("# 241: tzset(void) STUB"); +} + +#if defined(PG_INITDB) || defined(FE_UTILS_PRINT) || defined(PG_DUMP_PARALLEL) +static void +__SIG_IGN(int param) { +} +#endif + + +extern void sock_flush(); + + +#endif // I_WASI + diff --git a/src/makefiles/Makefile.emscripten b/src/makefiles/Makefile.emscripten new file mode 100644 index 0000000000000..3d37d043ad8c4 --- /dev/null +++ b/src/makefiles/Makefile.emscripten @@ -0,0 +1,16 @@ +# Use --enable-new-dtags to generate DT_RUNPATH instead of DT_RPATH. +# This allows LD_LIBRARY_PATH to still work when needed. +rpath = +AROPT = crs + +# Rule for building a shared library from a single .o file +%.so: %.o + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ +# Use --enable-new-dtags to generate DT_RUNPATH instead of DT_RPATH. +# This allows LD_LIBRARY_PATH to still work when needed. +rpath = +AROPT = crs + +# Rule for building a shared library from a single .o file +%.so: %.o + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ diff --git a/src/makefiles/Makefile.wasi b/src/makefiles/Makefile.wasi new file mode 100644 index 0000000000000..3d37d043ad8c4 --- /dev/null +++ b/src/makefiles/Makefile.wasi @@ -0,0 +1,16 @@ +# Use --enable-new-dtags to generate DT_RUNPATH instead of DT_RPATH. +# This allows LD_LIBRARY_PATH to still work when needed. +rpath = +AROPT = crs + +# Rule for building a shared library from a single .o file +%.so: %.o + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ +# Use --enable-new-dtags to generate DT_RUNPATH instead of DT_RPATH. +# This allows LD_LIBRARY_PATH to still work when needed. +rpath = +AROPT = crs + +# 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..da36f9bf30b6f --- /dev/null +++ b/src/template/emscripten @@ -0,0 +1,56 @@ +# 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" + +# 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" + +# 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" + +# 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" + diff --git a/src/template/wasi b/src/template/wasi new file mode 100644 index 0000000000000..dc3dc340ceece --- /dev/null +++ b/src/template/wasi @@ -0,0 +1,28 @@ +# 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" + +# 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 003b2e868922cffafc55ff959e22c84a80bafa73 Mon Sep 17 00:00:00 2001 From: pmp-p Date: Sat, 8 Feb 2025 02:13:43 +0100 Subject: [PATCH 12/16] clean --- src/test/Makefile | 55 ++++++++++++++++++++++-- src/test/isolation/Makefile | 84 +++++++++++++++++++++++++++++++++++-- 2 files changed, 131 insertions(+), 8 deletions(-) diff --git a/src/test/Makefile b/src/test/Makefile index 654810ef56039..dbd3192874d33 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -1,4 +1,51 @@ -# auto-edited for pglite -all: $(echo src/test and src/test/isolation skipped) -clean check installcheck all-src-recurse: all -install: all +#------------------------------------------------------------------------- +# +# Makefile for src/test +# +# Copyright (c) 1994, Regents of the University of California +# +# src/test/Makefile +# +#------------------------------------------------------------------------- + +subdir = src/test +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global + +SUBDIRS = perl regress isolation modules authentication recovery subscription + +ifeq ($(with_icu),yes) +SUBDIRS += icu +endif +ifeq ($(with_gssapi),yes) +SUBDIRS += kerberos +endif +ifeq ($(with_ldap),yes) +SUBDIRS += ldap +endif +ifeq ($(with_ssl),openssl) +SUBDIRS += ssl +endif + +# Test suites that are not safe by default but can be run if selected +# by the user via the whitespace-separated list in variable PG_TEST_EXTRA. +# Export PG_TEST_EXTRA to check it in individual tap tests. +export PG_TEST_EXTRA + +# We don't build or execute these by default, but we do want "make +# clean" etc to recurse into them. (We must filter out those that we +# have conditionally included into SUBDIRS above, else there will be +# make confusion.) +ALWAYS_SUBDIRS = $(filter-out $(SUBDIRS),examples kerberos icu ldap ssl) + +# We want to recurse to all subdirs for all standard targets, except that +# installcheck and install should not recurse into the subdirectory "modules". + +recurse_alldirs_targets := $(filter-out installcheck install, $(standard_targets)) +installable_dirs := $(filter-out modules, $(SUBDIRS)) + +$(call recurse,$(recurse_alldirs_targets)) +$(call recurse,installcheck, $(installable_dirs)) +$(call recurse,install, $(installable_dirs)) + +$(recurse_always) diff --git a/src/test/isolation/Makefile b/src/test/isolation/Makefile index 654810ef56039..b8738b7c1be90 100644 --- a/src/test/isolation/Makefile +++ b/src/test/isolation/Makefile @@ -1,4 +1,80 @@ -# auto-edited for pglite -all: $(echo src/test and src/test/isolation skipped) -clean check installcheck all-src-recurse: all -install: all +# +# Makefile for isolation tests +# + +PGFILEDESC = "pg_isolation_regress/isolationtester - multi-client test driver" +PGAPPICON = win32 + +subdir = src/test/isolation +top_builddir = ../../.. +include $(top_builddir)/src/Makefile.global + +override CPPFLAGS := -I. -I$(srcdir) -I$(libpq_srcdir) \ + -I$(srcdir)/../regress $(CPPFLAGS) + +OBJS = \ + $(WIN32RES) \ + isolationtester.o \ + specparse.o \ + specscanner.o + +all: isolationtester$(X) pg_isolation_regress$(X) + +install: all installdirs + $(INSTALL_PROGRAM) pg_isolation_regress$(X) '$(DESTDIR)$(pgxsdir)/$(subdir)/pg_isolation_regress$(X)' + $(INSTALL_PROGRAM) isolationtester$(X) '$(DESTDIR)$(pgxsdir)/$(subdir)/isolationtester$(X)' + +installdirs: + $(MKDIR_P) '$(DESTDIR)$(pgxsdir)/$(subdir)' + +uninstall: + rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/pg_isolation_regress$(X)' + rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/isolationtester$(X)' + +submake-regress: + $(MAKE) -C $(top_builddir)/src/test/regress pg_regress.o + +pg_regress.o: | submake-regress + rm -f $@ && $(LN_S) $(top_builddir)/src/test/regress/pg_regress.o . + +pg_isolation_regress$(X): isolation_main.o pg_regress.o $(WIN32RES) + $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@ + +isolationtester$(X): $(OBJS) | submake-libpq submake-libpgport + $(CC) $(CFLAGS) $^ $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@ + +distprep: specparse.c specscanner.c + +# See notes in src/backend/parser/Makefile about the following two rules +specparse.h: specparse.c + touch $@ + +specparse.c: BISONFLAGS += -d + +# Force these dependencies to be known even without dependency info built: +specparse.o specscanner.o: specparse.h + +# specparse.c and specscanner.c are in the distribution tarball, +# so do not clean them here +clean distclean: + rm -f isolationtester$(X) pg_isolation_regress$(X) $(OBJS) isolation_main.o + rm -f pg_regress.o + rm -rf $(pg_regress_clean_files) + +maintainer-clean: distclean + rm -f specparse.h specparse.c specscanner.c + +installcheck: all + $(pg_isolation_regress_installcheck) --schedule=$(srcdir)/isolation_schedule + +check: all + $(pg_isolation_regress_check) --schedule=$(srcdir)/isolation_schedule + +# Non-default tests. It only makes sense to run these if set up to use +# prepared transactions, via TEMP_CONFIG for the check case, or via the +# postgresql.conf for the installcheck case. +installcheck-prepared-txns: all temp-install + $(pg_isolation_regress_installcheck) --schedule=$(srcdir)/isolation_schedule prepared-transactions prepared-transactions-cic + +check-prepared-txns: all temp-install + $(pg_isolation_regress_check) --schedule=$(srcdir)/isolation_schedule prepared-transactions prepared-transactions-cic From deb280a94eb51ca9e1e934a3d55b217e73d48819 Mon Sep 17 00:00:00 2001 From: pmp-p Date: Sat, 8 Feb 2025 02:17:43 +0100 Subject: [PATCH 13/16] clean --- configure | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/configure b/configure index a66ac06e96075..2d5f6a68ffa32 100755 --- a/configure +++ b/configure @@ -4322,7 +4322,7 @@ else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no - CFLAGS="-g2" + CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4353,7 +4353,7 @@ if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g2" + CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4381,13 +4381,13 @@ if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then - CFLAGS="-g2 -Os" + CFLAGS="-g -O2" else - CFLAGS="-g2" + CFLAGS="-g" fi else if test "$GCC" = yes; then - CFLAGS="-Os" + CFLAGS="-O2" else CFLAGS= fi @@ -4853,7 +4853,7 @@ else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no - CXXFLAGS="-g2" + CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4884,7 +4884,7 @@ if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag - CXXFLAGS="-g2" + CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4912,13 +4912,13 @@ if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then - CXXFLAGS="-g2 -Os" + CXXFLAGS="-g -O2" else - CXXFLAGS="-g2" + CXXFLAGS="-g" fi else if test "$GXX" = yes; then - CXXFLAGS="-Os" + CXXFLAGS="-O2" else CXXFLAGS= fi @@ -5278,11 +5278,11 @@ elif test "${CFLAGS+set}" = set; then elif test "$enable_coverage" = yes; then : # no optimization by default elif test "$GCC" = yes; then - CFLAGS="-Os" + CFLAGS="-O2" else # if the user selected debug mode, don't use -O if test "$enable_debug" != yes; then - CFLAGS="-Os" + CFLAGS="-O" fi fi @@ -5293,11 +5293,11 @@ elif test "${CXXFLAGS+set}" = set; then elif test "$enable_coverage" = yes; then : # no optimization by default elif test "$GCC" = yes; then - CXXFLAGS="-Os" + CXXFLAGS="-O2" else # if the user selected debug mode, don't use -O if test "$enable_debug" != yes; then - CXXFLAGS="-Os" + CXXFLAGS="-O" fi fi @@ -5310,12 +5310,12 @@ fi if test "$ac_env_BITCODE_CFLAGS_set" = set; then BITCODE_CFLAGS=$ac_env_BITCODE_CFLAGS_value else - BITCODE_CFLAGS="-Os $BITCODE_CFLAGS" + BITCODE_CFLAGS="-O2 $BITCODE_CFLAGS" fi if test "$ac_env_BITCODE_CXXFLAGS_set" = set; then BITCODE_CXXFLAGS=$ac_env_BITCODE_CXXFLAGS_value else - BITCODE_CXXFLAGS="-Os $BITCODE_CXXFLAGS" + BITCODE_CXXFLAGS="-O2 $BITCODE_CXXFLAGS" fi # C[XX]FLAGS we determined above will be added back at the end @@ -7826,11 +7826,11 @@ fi # supply -g if --enable-debug if test "$enable_debug" = yes && test "$ac_cv_prog_cc_g" = yes; then - CFLAGS="$CFLAGS -g2" + CFLAGS="$CFLAGS -g" fi if test "$enable_debug" = yes && test "$ac_cv_prog_cxx_g" = yes; then - CXXFLAGS="$CXXFLAGS -g2" + CXXFLAGS="$CXXFLAGS -g" fi # enable code coverage if --enable-coverage @@ -13588,7 +13588,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -extern char uuid_export (); +char uuid_export (); int main () { @@ -13650,7 +13650,7 @@ $as_echo "$ac_cv_lib_uuid_uuid_export" >&6; } if test "x$ac_cv_lib_uuid_uuid_export" = xyes; then : UUID_LIBS="-luuid" else - ac_cv_lib_ossp_uuid_uuid_export=yes + as_fn_error $? "library 'ossp-uuid' or 'uuid' is required for OSSP UUID" "$LINENO" 5 fi fi From bb66e9c1d9b3f80e81d764312a4072331f053d11 Mon Sep 17 00:00:00 2001 From: pmp-p Date: Sat, 8 Feb 2025 02:22:24 +0100 Subject: [PATCH 14/16] clean --- src/Makefile.shlib | 32 +------------------------------- src/backend/commands/async.c | 4 ---- 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/src/Makefile.shlib b/src/Makefile.shlib index 11767a8fd8f64..f94d59d1c5970 100644 --- a/src/Makefile.shlib +++ b/src/Makefile.shlib @@ -233,33 +233,6 @@ ifeq ($(SHLIB_EXPORTS),) override CXXFLAGS += $(CXXFLAGS_SL_MODULE) endif -ifeq ($(PORTNAME), emscripten) - LINK.shared = emsdk-shared - ifdef soname - # emscripten uses unversioned shared libraries - shlib = $(shlib_bare) - soname = $(shlib_bare) - endif - BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ - exports_file = $(SHLIB_EXPORTS:%.txt=%.list) -# ifneq (,$(exports_file)) -# LINK.shared += -Wl,--version-script=$(exports_file) -# endif -endif - -ifeq ($(PORTNAME), wasi) - LINK.shared = wasi-shared - ifdef soname - # emscripten uses unversioned shared libraries - shlib = $(shlib_bare) - soname = $(shlib_bare) - endif - BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ - exports_file = $(SHLIB_EXPORTS:%.txt=%.list) -# ifneq (,$(exports_file)) -# LINK.shared += -Wl,--version-script=$(exports_file) -# endif -endif ## ## BUILD @@ -275,11 +248,8 @@ all-lib: lib$(NAME).pc endif all-static-lib: $(stlib) -ifdef wasi -all-shared-lib: all-static-lib -else + all-shared-lib: $(shlib) -endif # In this rule, "touch $@" works around a problem on some platforms wherein # ar updates the library file's mod time with a value calculated to diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index e8fe9300fc2d8..d6a91a9eaacc3 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -1700,12 +1700,8 @@ SignalBackends(void) * NotifyQueueLock; which is unlikely but certainly possible. So we * just log a low-level debug message if it happens. */ -#if defined(__EMSCRIPTEN__) - HandleNotifyInterrupt(); -#else if (SendProcSignal(pid, PROCSIG_NOTIFY_INTERRUPT, ids[i]) < 0) elog(DEBUG3, "could not signal backend with PID %d: %m", pid); -#endif } pfree(pids); From 21e0029b2cfebed08843d1e52969fa326395bb1c Mon Sep 17 00:00:00 2001 From: pmp-p Date: Wed, 12 Feb 2025 03:15:42 +0100 Subject: [PATCH 15/16] do not hardcode cma size --- configure | 40 +++++------ src/Makefile.shlib | 32 ++++++++- src/backend/commands/async.c | 4 ++ src/backend/libpq/pqcomm.c | 2 +- src/bin/initdb/initdb.c | 126 +++++++++++++++++++++++++-------- src/include/port/emscripten.h | 121 ------------------------------- src/include/port/wasm_common.h | 15 ++++ src/test/Makefile | 55 ++------------ src/test/isolation/Makefile | 84 ++-------------------- 9 files changed, 177 insertions(+), 302 deletions(-) diff --git a/configure b/configure index 2d5f6a68ffa32..a66ac06e96075 100755 --- a/configure +++ b/configure @@ -4322,7 +4322,7 @@ else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no - CFLAGS="-g" + CFLAGS="-g2" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4353,7 +4353,7 @@ if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" + CFLAGS="-g2" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4381,13 +4381,13 @@ if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then - CFLAGS="-g -O2" + CFLAGS="-g2 -Os" else - CFLAGS="-g" + CFLAGS="-g2" fi else if test "$GCC" = yes; then - CFLAGS="-O2" + CFLAGS="-Os" else CFLAGS= fi @@ -4853,7 +4853,7 @@ else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no - CXXFLAGS="-g" + CXXFLAGS="-g2" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4884,7 +4884,7 @@ if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag - CXXFLAGS="-g" + CXXFLAGS="-g2" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4912,13 +4912,13 @@ if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then - CXXFLAGS="-g -O2" + CXXFLAGS="-g2 -Os" else - CXXFLAGS="-g" + CXXFLAGS="-g2" fi else if test "$GXX" = yes; then - CXXFLAGS="-O2" + CXXFLAGS="-Os" else CXXFLAGS= fi @@ -5278,11 +5278,11 @@ elif test "${CFLAGS+set}" = set; then elif test "$enable_coverage" = yes; then : # no optimization by default elif test "$GCC" = yes; then - CFLAGS="-O2" + CFLAGS="-Os" else # if the user selected debug mode, don't use -O if test "$enable_debug" != yes; then - CFLAGS="-O" + CFLAGS="-Os" fi fi @@ -5293,11 +5293,11 @@ elif test "${CXXFLAGS+set}" = set; then elif test "$enable_coverage" = yes; then : # no optimization by default elif test "$GCC" = yes; then - CXXFLAGS="-O2" + CXXFLAGS="-Os" else # if the user selected debug mode, don't use -O if test "$enable_debug" != yes; then - CXXFLAGS="-O" + CXXFLAGS="-Os" fi fi @@ -5310,12 +5310,12 @@ fi if test "$ac_env_BITCODE_CFLAGS_set" = set; then BITCODE_CFLAGS=$ac_env_BITCODE_CFLAGS_value else - BITCODE_CFLAGS="-O2 $BITCODE_CFLAGS" + BITCODE_CFLAGS="-Os $BITCODE_CFLAGS" fi if test "$ac_env_BITCODE_CXXFLAGS_set" = set; then BITCODE_CXXFLAGS=$ac_env_BITCODE_CXXFLAGS_value else - BITCODE_CXXFLAGS="-O2 $BITCODE_CXXFLAGS" + BITCODE_CXXFLAGS="-Os $BITCODE_CXXFLAGS" fi # C[XX]FLAGS we determined above will be added back at the end @@ -7826,11 +7826,11 @@ fi # supply -g if --enable-debug if test "$enable_debug" = yes && test "$ac_cv_prog_cc_g" = yes; then - CFLAGS="$CFLAGS -g" + CFLAGS="$CFLAGS -g2" fi if test "$enable_debug" = yes && test "$ac_cv_prog_cxx_g" = yes; then - CXXFLAGS="$CXXFLAGS -g" + CXXFLAGS="$CXXFLAGS -g2" fi # enable code coverage if --enable-coverage @@ -13588,7 +13588,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char uuid_export (); +extern char uuid_export (); int main () { @@ -13650,7 +13650,7 @@ $as_echo "$ac_cv_lib_uuid_uuid_export" >&6; } if test "x$ac_cv_lib_uuid_uuid_export" = xyes; then : UUID_LIBS="-luuid" else - as_fn_error $? "library 'ossp-uuid' or 'uuid' is required for OSSP UUID" "$LINENO" 5 + ac_cv_lib_ossp_uuid_uuid_export=yes fi fi diff --git a/src/Makefile.shlib b/src/Makefile.shlib index f94d59d1c5970..11767a8fd8f64 100644 --- a/src/Makefile.shlib +++ b/src/Makefile.shlib @@ -233,6 +233,33 @@ ifeq ($(SHLIB_EXPORTS),) override CXXFLAGS += $(CXXFLAGS_SL_MODULE) endif +ifeq ($(PORTNAME), emscripten) + LINK.shared = emsdk-shared + ifdef soname + # emscripten uses unversioned shared libraries + shlib = $(shlib_bare) + soname = $(shlib_bare) + endif + BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ + exports_file = $(SHLIB_EXPORTS:%.txt=%.list) +# ifneq (,$(exports_file)) +# LINK.shared += -Wl,--version-script=$(exports_file) +# endif +endif + +ifeq ($(PORTNAME), wasi) + LINK.shared = wasi-shared + ifdef soname + # emscripten uses unversioned shared libraries + shlib = $(shlib_bare) + soname = $(shlib_bare) + endif + BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ + exports_file = $(SHLIB_EXPORTS:%.txt=%.list) +# ifneq (,$(exports_file)) +# LINK.shared += -Wl,--version-script=$(exports_file) +# endif +endif ## ## BUILD @@ -248,8 +275,11 @@ all-lib: lib$(NAME).pc endif all-static-lib: $(stlib) - +ifdef wasi +all-shared-lib: all-static-lib +else all-shared-lib: $(shlib) +endif # In this rule, "touch $@" works around a problem on some platforms wherein # ar updates the library file's mod time with a value calculated to diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index d6a91a9eaacc3..e8fe9300fc2d8 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -1700,8 +1700,12 @@ SignalBackends(void) * NotifyQueueLock; which is unlikely but certainly possible. So we * just log a low-level debug message if it happens. */ +#if defined(__EMSCRIPTEN__) + HandleNotifyInterrupt(); +#else if (SendProcSignal(pid, PROCSIG_NOTIFY_INTERRUPT, ids[i]) < 0) elog(DEBUG3, "could not signal backend with PID %d: %m", pid); +#endif } pfree(pids); diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 90c993f159dc8..ed90e89a98714 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -1194,7 +1194,7 @@ pq_startmsgread(void) PqSendPointer = 0; PqSendBuffer_save = PqSendBuffer; PqSendBuffer = 2 + (char*)(cma_rsize); - PqSendBufferSize = (64*1024*1024) - (int)(&PqSendBuffer[0]); + PqSendBufferSize = (CMA_MB*1024*1024) - (int)(&PqSendBuffer[0]); } else { PqRecvBuffer = &PqRecvBuffer_static[0]; if (PqSendBuffer_save) diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 3dbade0ea37f0..e5fe98cb8ca09 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -81,7 +81,6 @@ #include "mb/pg_wchar.h" #include "miscadmin.h" - /* Ideally this would be in a .h file, but it hardly seems worth the trouble */ extern const char *select_default_timezone(const char *share_path); @@ -168,7 +167,11 @@ static int wal_segment_size_mb; /* internal vars */ +#if !defined(PGL_MAIN) static const char *progname; +#else +# define dynamic_shared_memory_type idb_dynamic_shared_memory_type +#endif static int encodingid; static char *bki_file; static char *hba_file; @@ -807,6 +810,7 @@ cleanup_directories_atexit(void) static char * get_id(void) { +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) const char *username; #ifndef WIN32 @@ -817,10 +821,12 @@ get_id(void) exit(1); } #endif - username = get_user_name_or_exit(progname); return pg_strdup(username); +#else + return pg_strdup(getenv("PGUSER")); +#endif /* wasm */ } static char * @@ -1066,6 +1072,9 @@ set_null_conf(void) static const char * choose_dsm_implementation(void) { +#if defined(__wasi__) || defined(__EMSCRIPTEN__) + return "posix"; +#endif #if defined(HAVE_SHM_OPEN) && !defined(__sun__) int ntries = 10; pg_prng_state prng_state; @@ -1598,9 +1607,11 @@ bootstrap_template1(void) PG_CMD_PUTS(*line); free(*line); } - +#if !defined(PGL_INITDB_MAIN) PG_CMD_CLOSE; - +#else + pgl_pclose(cmdfd); +#endif free(bki_lines); check_ok(); @@ -1670,9 +1681,11 @@ get_su_pwd(void) if (ferror(pwf)) pg_fatal("could not read password from file \"%s\": %m", pwfilename); - else - pg_fatal("password file \"%s\" is empty", + else { + printf("password file \"%s\" is empty\n", pwfilename); + pwd1 = strdup("password"); + } } fclose(pwf); @@ -2615,8 +2628,13 @@ setup_bin_paths(const char *argv0) strlcpy(full_path, progname, sizeof(full_path)); if (ret == -1) +#if defined(__EMSCRIPTEN__) || defined(__wasi__) + printf("# WARNING: program \"%s\" is needed by %s but was not found in the same directory as \"%s\"\n", + "postgres", progname, full_path); +#else pg_fatal("program \"%s\" is needed by %s but was not found in the same directory as \"%s\"", "postgres", progname, full_path); +#endif // wasm else pg_fatal("program \"%s\" was found by \"%s\" but was not the same version as %s", "postgres", full_path, progname); @@ -2670,22 +2688,22 @@ setup_locale_encoding(void) lc_numeric, lc_time); } - +puts("# 2651"); if (!encoding) - { + { puts("# 2653"); int ctype_enc; ctype_enc = pg_get_encoding_from_locale(lc_ctype, true); - +puts("# 2657"); /* * If ctype_enc=SQL_ASCII, it's compatible with any encoding. ICU does * not support SQL_ASCII, so select UTF-8 instead. */ if (locale_provider == COLLPROVIDER_ICU && ctype_enc == PG_SQL_ASCII) ctype_enc = PG_UTF8; - +puts("# 2664"); if (ctype_enc == -1) - { + { puts("# 2666"); /* Couldn't recognize the locale's codeset */ pg_log_error("could not find suitable encoding for locale \"%s\"", lc_ctype); @@ -2694,7 +2712,7 @@ setup_locale_encoding(void) exit(1); } else if (!pg_valid_server_encoding_id(ctype_enc)) - { + { puts("# 2675"); /* * We recognized it, but it's not a legal server encoding. On * Windows, UTF-8 works with any locale, so we can fall back to @@ -2717,15 +2735,17 @@ setup_locale_encoding(void) #endif } else - { + { puts("# 2698"); encodingid = ctype_enc; printf(_("The default database encoding has accordingly been set to \"%s\".\n"), pg_encoding_to_char(encodingid)); } } - else + else { + puts("# 2705"); encodingid = get_encoding_id(encoding); - + } + puts("# 2706"); if (!check_locale_encoding(lc_ctype, encodingid) || !check_locale_encoding(lc_collate, encodingid)) exit(1); /* check_locale_encoding printed the error */ @@ -3044,7 +3064,11 @@ initialize_data_directory(void) /* Select suitable configuration settings */ set_null_conf(); +#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) test_config_settings(); +#else + dynamic_shared_memory_type = choose_dsm_implementation(); +#endif // wasm /* Now create all the text config files */ setup_config(); @@ -3104,15 +3128,56 @@ initialize_data_directory(void) make_postgres(cmdfd); +#if !defined(PGL_INITDB_MAIN) PG_CMD_CLOSE; +#else + pgl_pclose(cmdfd); +#endif + check_ok(); } +/* pglite entry point */ +#if defined(PGL_INITDB_MAIN) +extern void MemoryContextInit(void); +extern const char *PREFIX; +extern const char *PGDATA; +char * strcat_alloc(const char *head, const char *tail); +void strconcat(char*p, const char *head, const char *tail); int -main(int argc, char *argv[]) -{ +pgl_initdb_main() { + char tmp[1024]; + char *pwfile = NULL; + char *pgdata = NULL; + + strconcat(tmp, "--pwfile=", PREFIX); + pwfile = strcat_alloc(tmp, "/password"); + + + strconcat(tmp, "--pwfile=", PREFIX); + pgdata = strcat_alloc("--pgdata=", PGDATA); + + char *argv[] = { + strcat_alloc(PREFIX,"/bin/initdb"), + // "--no-clean", + "--wal-segsize=1", + "-g", + "-E", "UTF8", "--locale=C.UTF-8", "--locale-provider=libc", + "-U", WASM_USERNAME, pwfile, //"--pwfile=" WASM_PREFIX "/password", + pgdata, // "--pgdata=" WASM_PREFIX "/base", + NULL + }; + + int argc = sizeof(argv) / sizeof(char*) - 1; + + +#else +int +main(int argc, char *argv[]) { +#endif + static struct option long_options[] = { {"pgdata", required_argument, NULL, 'D'}, {"encoding", required_argument, NULL, 'E'}, @@ -3171,10 +3236,16 @@ main(int argc, char *argv[]) */ setvbuf(stdout, NULL, PG_IOLBF, 0); +#if defined(PGL_INITDB_MAIN) + progname = get_progname(argv[0]); +// printf("calling pg_initdb_main for %s\n", progname); + MemoryContextInit(); + pg_logging_init(progname); +#else pg_logging_init(argv[0]); progname = get_progname(argv[0]); +#endif set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("initdb")); - if (argc > 1) { if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) @@ -3188,7 +3259,7 @@ main(int argc, char *argv[]) exit(0); } } - +puts("# 3255:pgl_initdb_main " __FILE__); /* process command-line options */ while ((c = getopt_long(argc, argv, "A:c:dD:E:gkL:nNsST:U:WX:", @@ -3430,25 +3501,24 @@ main(int argc, char *argv[]) set_info_version(); setup_data_file_paths(); - setup_locale_encoding(); - setup_text_search(); - printf("\n"); if (data_checksums) printf(_("Data page checksums are enabled.\n")); else printf(_("Data page checksums are disabled.\n")); - +puts("# 3505:" __FILE__); if (pwprompt || pwfilename) get_su_pwd(); printf("\n"); - +puts("# 3458:" __FILE__); initialize_data_directory(); - +#if defined(PGL_INITDB_MAIN) + puts("# 3461: TODO: fsync_pgdata ?" __FILE__); +#else if (do_sync) { fputs(_("syncing data to disk ... "), stdout); @@ -3466,7 +3536,7 @@ main(int argc, char *argv[]) pg_log_warning_hint("You can change this by editing pg_hba.conf or using the option -A, or " "--auth-local and --auth-host, the next time you run initdb."); } - +puts("# 3480"); if (!noinstructions) { /* @@ -3501,8 +3571,8 @@ main(int argc, char *argv[]) destroyPQExpBuffer(start_db_cmd); } - - +#endif success = true; +puts("# 3569:" __FILE__); return 0; } diff --git a/src/include/port/emscripten.h b/src/include/port/emscripten.h index 53bcf73359d84..616a4f43f4ab4 100644 --- a/src/include/port/emscripten.h +++ b/src/include/port/emscripten.h @@ -14,125 +14,4 @@ #define FD_BUFFER_MAX 16384 -/* - * and now popen will return predefined slot from a file list - * as file handle in initdb.c - */ -#if defined(PG_INITDB) && !defined(PG_MAIN) -#define popen(command, mode) pg_popen(command, mode) -#include // FILE+fprintf -extern FILE* IDB_PIPE_FP; -extern FILE* SOCKET_FILE; -extern int SOCKET_DATA; -extern int IDB_STAGE; -FILE *pg_popen(const char *command, const char *type) { - if (IDB_STAGE>1) { - fprintf(stderr,"# popen[%s]\n", command); - return stderr; - } - - if (!IDB_STAGE) { - fprintf(stderr,"# popen[%s] (BOOT)\n", command); - IDB_PIPE_FP = fopen( IDB_PIPE_BOOT, "w"); - IDB_STAGE = 1; - } else { - fprintf(stderr,"# popen[%s] (SINGLE)\n", command); - IDB_PIPE_FP = fopen( IDB_PIPE_SINGLE, "w"); - IDB_STAGE = 2; - } - - return IDB_PIPE_FP; - -} -#endif // PG_INITDB - - -#endif // I_EMSCRIPTEN -/* src/include/port/emscripten.h */ - -#ifndef I_EMSCRIPTEN -#define I_EMSCRIPTEN - -#if !defined(__cplusplus) -#include -#endif - -#include "/tmp/pglite/include/wasm_common.h" - - -#define BOOT_END_MARK "build indices" -#define FD_BUFFER_MAX 16384 - - -/* - * and now popen will return predefined slot from a file list - * as file handle in initdb.c - */ -#if defined(PG_INITDB) && !defined(PG_MAIN) -#define popen(command, mode) pg_popen(command, mode) -#include // FILE+fprintf -extern FILE* IDB_PIPE_FP; -extern FILE* SOCKET_FILE; -extern int SOCKET_DATA; -extern int IDB_STAGE; -FILE *pg_popen(const char *command, const char *type) { - if (IDB_STAGE>1) { - fprintf(stderr,"# popen[%s]\n", command); - return stderr; - } - - if (!IDB_STAGE) { - fprintf(stderr,"# popen[%s] (BOOT)\n", command); - IDB_PIPE_FP = fopen( IDB_PIPE_BOOT, "w"); - IDB_STAGE = 1; - } else { - fprintf(stderr,"# popen[%s] (SINGLE)\n", command); - IDB_PIPE_FP = fopen( IDB_PIPE_SINGLE, "w"); - IDB_STAGE = 2; - } - - return IDB_PIPE_FP; - -} -#endif // PG_INITDB - - -#endif // I_EMSCRIPTEN -/* src/include/port/emscripten.h */ - -#ifndef I_EMSCRIPTEN -#define I_EMSCRIPTEN - -#if !defined(__cplusplus) -#include -#endif - -#include "/tmp/pglite/include/wasm_common.h" - - -#define BOOT_END_MARK "build indices" -#define FD_BUFFER_MAX 16384 - - - - -#endif // I_EMSCRIPTEN -/* src/include/port/emscripten.h */ - -#ifndef I_EMSCRIPTEN -#define I_EMSCRIPTEN - -#if !defined(__cplusplus) -#include -#endif - -#include "/tmp/pglite/include/wasm_common.h" - - -#define BOOT_END_MARK "build indices" -#define FD_BUFFER_MAX 16384 - - - - #endif // I_EMSCRIPTEN diff --git a/src/include/port/wasm_common.h b/src/include/port/wasm_common.h index 5d664a5044e4b..74abdcaacd263 100644 --- a/src/include/port/wasm_common.h +++ b/src/include/port/wasm_common.h @@ -103,6 +103,21 @@ extern int IDB_STAGE; */ extern FILE* SOCKET_FILE; extern int SOCKET_DATA; +extern int pgl_pclose(FILE *stream); + +#if !defined(PGL_MAIN) && !defined(PGL_MAIN) +# if !defined(PG_EXEC) +extern int pg_pclose(FILE *stream); +#define pclose(stream) pg_pclose(stream) +# else +#include +int +pg_pclose(FILE *stream) { + puts("# 114:" __FILE__ " int pg_pclose(FILE *stream) STUB"); + return 0; +} +# endif // PG_EXEC +#endif // pgl /* * OpenPipeStream : another kind of pipe open in fd.c diff --git a/src/test/Makefile b/src/test/Makefile index dbd3192874d33..654810ef56039 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -1,51 +1,4 @@ -#------------------------------------------------------------------------- -# -# Makefile for src/test -# -# Copyright (c) 1994, Regents of the University of California -# -# src/test/Makefile -# -#------------------------------------------------------------------------- - -subdir = src/test -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -SUBDIRS = perl regress isolation modules authentication recovery subscription - -ifeq ($(with_icu),yes) -SUBDIRS += icu -endif -ifeq ($(with_gssapi),yes) -SUBDIRS += kerberos -endif -ifeq ($(with_ldap),yes) -SUBDIRS += ldap -endif -ifeq ($(with_ssl),openssl) -SUBDIRS += ssl -endif - -# Test suites that are not safe by default but can be run if selected -# by the user via the whitespace-separated list in variable PG_TEST_EXTRA. -# Export PG_TEST_EXTRA to check it in individual tap tests. -export PG_TEST_EXTRA - -# We don't build or execute these by default, but we do want "make -# clean" etc to recurse into them. (We must filter out those that we -# have conditionally included into SUBDIRS above, else there will be -# make confusion.) -ALWAYS_SUBDIRS = $(filter-out $(SUBDIRS),examples kerberos icu ldap ssl) - -# We want to recurse to all subdirs for all standard targets, except that -# installcheck and install should not recurse into the subdirectory "modules". - -recurse_alldirs_targets := $(filter-out installcheck install, $(standard_targets)) -installable_dirs := $(filter-out modules, $(SUBDIRS)) - -$(call recurse,$(recurse_alldirs_targets)) -$(call recurse,installcheck, $(installable_dirs)) -$(call recurse,install, $(installable_dirs)) - -$(recurse_always) +# auto-edited for pglite +all: $(echo src/test and src/test/isolation skipped) +clean check installcheck all-src-recurse: all +install: all diff --git a/src/test/isolation/Makefile b/src/test/isolation/Makefile index b8738b7c1be90..654810ef56039 100644 --- a/src/test/isolation/Makefile +++ b/src/test/isolation/Makefile @@ -1,80 +1,4 @@ -# -# Makefile for isolation tests -# - -PGFILEDESC = "pg_isolation_regress/isolationtester - multi-client test driver" -PGAPPICON = win32 - -subdir = src/test/isolation -top_builddir = ../../.. -include $(top_builddir)/src/Makefile.global - -override CPPFLAGS := -I. -I$(srcdir) -I$(libpq_srcdir) \ - -I$(srcdir)/../regress $(CPPFLAGS) - -OBJS = \ - $(WIN32RES) \ - isolationtester.o \ - specparse.o \ - specscanner.o - -all: isolationtester$(X) pg_isolation_regress$(X) - -install: all installdirs - $(INSTALL_PROGRAM) pg_isolation_regress$(X) '$(DESTDIR)$(pgxsdir)/$(subdir)/pg_isolation_regress$(X)' - $(INSTALL_PROGRAM) isolationtester$(X) '$(DESTDIR)$(pgxsdir)/$(subdir)/isolationtester$(X)' - -installdirs: - $(MKDIR_P) '$(DESTDIR)$(pgxsdir)/$(subdir)' - -uninstall: - rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/pg_isolation_regress$(X)' - rm -f '$(DESTDIR)$(pgxsdir)/$(subdir)/isolationtester$(X)' - -submake-regress: - $(MAKE) -C $(top_builddir)/src/test/regress pg_regress.o - -pg_regress.o: | submake-regress - rm -f $@ && $(LN_S) $(top_builddir)/src/test/regress/pg_regress.o . - -pg_isolation_regress$(X): isolation_main.o pg_regress.o $(WIN32RES) - $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@ - -isolationtester$(X): $(OBJS) | submake-libpq submake-libpgport - $(CC) $(CFLAGS) $^ $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@ - -distprep: specparse.c specscanner.c - -# See notes in src/backend/parser/Makefile about the following two rules -specparse.h: specparse.c - touch $@ - -specparse.c: BISONFLAGS += -d - -# Force these dependencies to be known even without dependency info built: -specparse.o specscanner.o: specparse.h - -# specparse.c and specscanner.c are in the distribution tarball, -# so do not clean them here -clean distclean: - rm -f isolationtester$(X) pg_isolation_regress$(X) $(OBJS) isolation_main.o - rm -f pg_regress.o - rm -rf $(pg_regress_clean_files) - -maintainer-clean: distclean - rm -f specparse.h specparse.c specscanner.c - -installcheck: all - $(pg_isolation_regress_installcheck) --schedule=$(srcdir)/isolation_schedule - -check: all - $(pg_isolation_regress_check) --schedule=$(srcdir)/isolation_schedule - -# Non-default tests. It only makes sense to run these if set up to use -# prepared transactions, via TEMP_CONFIG for the check case, or via the -# postgresql.conf for the installcheck case. -installcheck-prepared-txns: all temp-install - $(pg_isolation_regress_installcheck) --schedule=$(srcdir)/isolation_schedule prepared-transactions prepared-transactions-cic - -check-prepared-txns: all temp-install - $(pg_isolation_regress_check) --schedule=$(srcdir)/isolation_schedule prepared-transactions prepared-transactions-cic +# auto-edited for pglite +all: $(echo src/test and src/test/isolation skipped) +clean check installcheck all-src-recurse: all +install: all From 4f5087864988ce4a816c7eb26c4091eb65def86d Mon Sep 17 00:00:00 2001 From: pmp-p Date: Wed, 12 Feb 2025 03:18:17 +0100 Subject: [PATCH 16/16] oops --- configure | 40 +++++------ src/Makefile.shlib | 32 +-------- src/backend/commands/async.c | 4 -- src/bin/initdb/initdb.c | 126 ++++++++--------------------------- 4 files changed, 49 insertions(+), 153 deletions(-) diff --git a/configure b/configure index a66ac06e96075..2d5f6a68ffa32 100755 --- a/configure +++ b/configure @@ -4322,7 +4322,7 @@ else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no - CFLAGS="-g2" + CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4353,7 +4353,7 @@ if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g2" + CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4381,13 +4381,13 @@ if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then - CFLAGS="-g2 -Os" + CFLAGS="-g -O2" else - CFLAGS="-g2" + CFLAGS="-g" fi else if test "$GCC" = yes; then - CFLAGS="-Os" + CFLAGS="-O2" else CFLAGS= fi @@ -4853,7 +4853,7 @@ else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no - CXXFLAGS="-g2" + CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4884,7 +4884,7 @@ if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag - CXXFLAGS="-g2" + CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4912,13 +4912,13 @@ if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then - CXXFLAGS="-g2 -Os" + CXXFLAGS="-g -O2" else - CXXFLAGS="-g2" + CXXFLAGS="-g" fi else if test "$GXX" = yes; then - CXXFLAGS="-Os" + CXXFLAGS="-O2" else CXXFLAGS= fi @@ -5278,11 +5278,11 @@ elif test "${CFLAGS+set}" = set; then elif test "$enable_coverage" = yes; then : # no optimization by default elif test "$GCC" = yes; then - CFLAGS="-Os" + CFLAGS="-O2" else # if the user selected debug mode, don't use -O if test "$enable_debug" != yes; then - CFLAGS="-Os" + CFLAGS="-O" fi fi @@ -5293,11 +5293,11 @@ elif test "${CXXFLAGS+set}" = set; then elif test "$enable_coverage" = yes; then : # no optimization by default elif test "$GCC" = yes; then - CXXFLAGS="-Os" + CXXFLAGS="-O2" else # if the user selected debug mode, don't use -O if test "$enable_debug" != yes; then - CXXFLAGS="-Os" + CXXFLAGS="-O" fi fi @@ -5310,12 +5310,12 @@ fi if test "$ac_env_BITCODE_CFLAGS_set" = set; then BITCODE_CFLAGS=$ac_env_BITCODE_CFLAGS_value else - BITCODE_CFLAGS="-Os $BITCODE_CFLAGS" + BITCODE_CFLAGS="-O2 $BITCODE_CFLAGS" fi if test "$ac_env_BITCODE_CXXFLAGS_set" = set; then BITCODE_CXXFLAGS=$ac_env_BITCODE_CXXFLAGS_value else - BITCODE_CXXFLAGS="-Os $BITCODE_CXXFLAGS" + BITCODE_CXXFLAGS="-O2 $BITCODE_CXXFLAGS" fi # C[XX]FLAGS we determined above will be added back at the end @@ -7826,11 +7826,11 @@ fi # supply -g if --enable-debug if test "$enable_debug" = yes && test "$ac_cv_prog_cc_g" = yes; then - CFLAGS="$CFLAGS -g2" + CFLAGS="$CFLAGS -g" fi if test "$enable_debug" = yes && test "$ac_cv_prog_cxx_g" = yes; then - CXXFLAGS="$CXXFLAGS -g2" + CXXFLAGS="$CXXFLAGS -g" fi # enable code coverage if --enable-coverage @@ -13588,7 +13588,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -extern char uuid_export (); +char uuid_export (); int main () { @@ -13650,7 +13650,7 @@ $as_echo "$ac_cv_lib_uuid_uuid_export" >&6; } if test "x$ac_cv_lib_uuid_uuid_export" = xyes; then : UUID_LIBS="-luuid" else - ac_cv_lib_ossp_uuid_uuid_export=yes + as_fn_error $? "library 'ossp-uuid' or 'uuid' is required for OSSP UUID" "$LINENO" 5 fi fi diff --git a/src/Makefile.shlib b/src/Makefile.shlib index 11767a8fd8f64..f94d59d1c5970 100644 --- a/src/Makefile.shlib +++ b/src/Makefile.shlib @@ -233,33 +233,6 @@ ifeq ($(SHLIB_EXPORTS),) override CXXFLAGS += $(CXXFLAGS_SL_MODULE) endif -ifeq ($(PORTNAME), emscripten) - LINK.shared = emsdk-shared - ifdef soname - # emscripten uses unversioned shared libraries - shlib = $(shlib_bare) - soname = $(shlib_bare) - endif - BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ - exports_file = $(SHLIB_EXPORTS:%.txt=%.list) -# ifneq (,$(exports_file)) -# LINK.shared += -Wl,--version-script=$(exports_file) -# endif -endif - -ifeq ($(PORTNAME), wasi) - LINK.shared = wasi-shared - ifdef soname - # emscripten uses unversioned shared libraries - shlib = $(shlib_bare) - soname = $(shlib_bare) - endif - BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ - exports_file = $(SHLIB_EXPORTS:%.txt=%.list) -# ifneq (,$(exports_file)) -# LINK.shared += -Wl,--version-script=$(exports_file) -# endif -endif ## ## BUILD @@ -275,11 +248,8 @@ all-lib: lib$(NAME).pc endif all-static-lib: $(stlib) -ifdef wasi -all-shared-lib: all-static-lib -else + all-shared-lib: $(shlib) -endif # In this rule, "touch $@" works around a problem on some platforms wherein # ar updates the library file's mod time with a value calculated to diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index e8fe9300fc2d8..d6a91a9eaacc3 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -1700,12 +1700,8 @@ SignalBackends(void) * NotifyQueueLock; which is unlikely but certainly possible. So we * just log a low-level debug message if it happens. */ -#if defined(__EMSCRIPTEN__) - HandleNotifyInterrupt(); -#else if (SendProcSignal(pid, PROCSIG_NOTIFY_INTERRUPT, ids[i]) < 0) elog(DEBUG3, "could not signal backend with PID %d: %m", pid); -#endif } pfree(pids); diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index e5fe98cb8ca09..3dbade0ea37f0 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -81,6 +81,7 @@ #include "mb/pg_wchar.h" #include "miscadmin.h" + /* Ideally this would be in a .h file, but it hardly seems worth the trouble */ extern const char *select_default_timezone(const char *share_path); @@ -167,11 +168,7 @@ static int wal_segment_size_mb; /* internal vars */ -#if !defined(PGL_MAIN) static const char *progname; -#else -# define dynamic_shared_memory_type idb_dynamic_shared_memory_type -#endif static int encodingid; static char *bki_file; static char *hba_file; @@ -810,7 +807,6 @@ cleanup_directories_atexit(void) static char * get_id(void) { -#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) const char *username; #ifndef WIN32 @@ -821,12 +817,10 @@ get_id(void) exit(1); } #endif + username = get_user_name_or_exit(progname); return pg_strdup(username); -#else - return pg_strdup(getenv("PGUSER")); -#endif /* wasm */ } static char * @@ -1072,9 +1066,6 @@ set_null_conf(void) static const char * choose_dsm_implementation(void) { -#if defined(__wasi__) || defined(__EMSCRIPTEN__) - return "posix"; -#endif #if defined(HAVE_SHM_OPEN) && !defined(__sun__) int ntries = 10; pg_prng_state prng_state; @@ -1607,11 +1598,9 @@ bootstrap_template1(void) PG_CMD_PUTS(*line); free(*line); } -#if !defined(PGL_INITDB_MAIN) + PG_CMD_CLOSE; -#else - pgl_pclose(cmdfd); -#endif + free(bki_lines); check_ok(); @@ -1681,11 +1670,9 @@ get_su_pwd(void) if (ferror(pwf)) pg_fatal("could not read password from file \"%s\": %m", pwfilename); - else { - printf("password file \"%s\" is empty\n", + else + pg_fatal("password file \"%s\" is empty", pwfilename); - pwd1 = strdup("password"); - } } fclose(pwf); @@ -2628,13 +2615,8 @@ setup_bin_paths(const char *argv0) strlcpy(full_path, progname, sizeof(full_path)); if (ret == -1) -#if defined(__EMSCRIPTEN__) || defined(__wasi__) - printf("# WARNING: program \"%s\" is needed by %s but was not found in the same directory as \"%s\"\n", - "postgres", progname, full_path); -#else pg_fatal("program \"%s\" is needed by %s but was not found in the same directory as \"%s\"", "postgres", progname, full_path); -#endif // wasm else pg_fatal("program \"%s\" was found by \"%s\" but was not the same version as %s", "postgres", full_path, progname); @@ -2688,22 +2670,22 @@ setup_locale_encoding(void) lc_numeric, lc_time); } -puts("# 2651"); + if (!encoding) - { puts("# 2653"); + { int ctype_enc; ctype_enc = pg_get_encoding_from_locale(lc_ctype, true); -puts("# 2657"); + /* * If ctype_enc=SQL_ASCII, it's compatible with any encoding. ICU does * not support SQL_ASCII, so select UTF-8 instead. */ if (locale_provider == COLLPROVIDER_ICU && ctype_enc == PG_SQL_ASCII) ctype_enc = PG_UTF8; -puts("# 2664"); + if (ctype_enc == -1) - { puts("# 2666"); + { /* Couldn't recognize the locale's codeset */ pg_log_error("could not find suitable encoding for locale \"%s\"", lc_ctype); @@ -2712,7 +2694,7 @@ puts("# 2664"); exit(1); } else if (!pg_valid_server_encoding_id(ctype_enc)) - { puts("# 2675"); + { /* * We recognized it, but it's not a legal server encoding. On * Windows, UTF-8 works with any locale, so we can fall back to @@ -2735,17 +2717,15 @@ puts("# 2664"); #endif } else - { puts("# 2698"); + { encodingid = ctype_enc; printf(_("The default database encoding has accordingly been set to \"%s\".\n"), pg_encoding_to_char(encodingid)); } } - else { - puts("# 2705"); + else encodingid = get_encoding_id(encoding); - } - puts("# 2706"); + if (!check_locale_encoding(lc_ctype, encodingid) || !check_locale_encoding(lc_collate, encodingid)) exit(1); /* check_locale_encoding printed the error */ @@ -3064,11 +3044,7 @@ initialize_data_directory(void) /* Select suitable configuration settings */ set_null_conf(); -#if !defined(__EMSCRIPTEN__) && !defined(__wasi__) test_config_settings(); -#else - dynamic_shared_memory_type = choose_dsm_implementation(); -#endif // wasm /* Now create all the text config files */ setup_config(); @@ -3128,56 +3104,15 @@ initialize_data_directory(void) make_postgres(cmdfd); -#if !defined(PGL_INITDB_MAIN) PG_CMD_CLOSE; -#else - pgl_pclose(cmdfd); -#endif - check_ok(); } -/* pglite entry point */ -#if defined(PGL_INITDB_MAIN) -extern void MemoryContextInit(void); -extern const char *PREFIX; -extern const char *PGDATA; -char * strcat_alloc(const char *head, const char *tail); -void strconcat(char*p, const char *head, const char *tail); - -int -pgl_initdb_main() { - char tmp[1024]; - char *pwfile = NULL; - char *pgdata = NULL; - - strconcat(tmp, "--pwfile=", PREFIX); - pwfile = strcat_alloc(tmp, "/password"); - - - strconcat(tmp, "--pwfile=", PREFIX); - pgdata = strcat_alloc("--pgdata=", PGDATA); - - char *argv[] = { - strcat_alloc(PREFIX,"/bin/initdb"), - // "--no-clean", - "--wal-segsize=1", - "-g", - "-E", "UTF8", "--locale=C.UTF-8", "--locale-provider=libc", - "-U", WASM_USERNAME, pwfile, //"--pwfile=" WASM_PREFIX "/password", - pgdata, // "--pgdata=" WASM_PREFIX "/base", - NULL - }; - - int argc = sizeof(argv) / sizeof(char*) - 1; - -#else int -main(int argc, char *argv[]) { -#endif - +main(int argc, char *argv[]) +{ static struct option long_options[] = { {"pgdata", required_argument, NULL, 'D'}, {"encoding", required_argument, NULL, 'E'}, @@ -3236,16 +3171,10 @@ main(int argc, char *argv[]) { */ setvbuf(stdout, NULL, PG_IOLBF, 0); -#if defined(PGL_INITDB_MAIN) - progname = get_progname(argv[0]); -// printf("calling pg_initdb_main for %s\n", progname); - MemoryContextInit(); - pg_logging_init(progname); -#else pg_logging_init(argv[0]); progname = get_progname(argv[0]); -#endif set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("initdb")); + if (argc > 1) { if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) @@ -3259,7 +3188,7 @@ main(int argc, char *argv[]) { exit(0); } } -puts("# 3255:pgl_initdb_main " __FILE__); + /* process command-line options */ while ((c = getopt_long(argc, argv, "A:c:dD:E:gkL:nNsST:U:WX:", @@ -3501,24 +3430,25 @@ puts("# 3255:pgl_initdb_main " __FILE__); set_info_version(); setup_data_file_paths(); + setup_locale_encoding(); + setup_text_search(); + printf("\n"); if (data_checksums) printf(_("Data page checksums are enabled.\n")); else printf(_("Data page checksums are disabled.\n")); -puts("# 3505:" __FILE__); + if (pwprompt || pwfilename) get_su_pwd(); printf("\n"); -puts("# 3458:" __FILE__); + initialize_data_directory(); -#if defined(PGL_INITDB_MAIN) - puts("# 3461: TODO: fsync_pgdata ?" __FILE__); -#else + if (do_sync) { fputs(_("syncing data to disk ... "), stdout); @@ -3536,7 +3466,7 @@ puts("# 3458:" __FILE__); pg_log_warning_hint("You can change this by editing pg_hba.conf or using the option -A, or " "--auth-local and --auth-host, the next time you run initdb."); } -puts("# 3480"); + if (!noinstructions) { /* @@ -3571,8 +3501,8 @@ puts("# 3480"); destroyPQExpBuffer(start_db_cmd); } -#endif + + success = true; -puts("# 3569:" __FILE__); return 0; }