mirror of
https://github.com/urbit/shrub.git
synced 2024-11-28 13:54:20 +03:00
vere: basic MingW compatibility changes
This commit adds code changes, compatibility functions, stubs and a build script to build urbit binaries on MingW64. Some functionality is limited or missing: terminal input and daemon mode is not available, graceful exit does not work, and the binaries are not completely static and use (portable) MingW dlls. To build the binaries, install the MSYS2 environment, check out or copy the urbit repo and pill binaries, open a MingW64 shell and `cd pkg/urbit && ./build-mingw`.
This commit is contained in:
parent
ef0b87a1cb
commit
4d14b410d5
47
nix/sources-mingw.json
Normal file
47
nix/sources-mingw.json
Normal file
@ -0,0 +1,47 @@
|
||||
{
|
||||
"lmdb": {
|
||||
"branch": "mdb.master",
|
||||
"description": "LMDB library",
|
||||
"homepage": "http://www.lmdb.tech/",
|
||||
"mingw": {
|
||||
"strip": 2,
|
||||
"make": "liblmdb.a"
|
||||
},
|
||||
"owner": "LMDB",
|
||||
"repo": "lmdb",
|
||||
"rev": "48a7fed59a8aae623deff415dda27097198ca0c1",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/LMDB/lmdb/archive/48a7fed59a8aae623deff415dda27097198ca0c1.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"secp256k1": {
|
||||
"branch": "master",
|
||||
"description": "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1.",
|
||||
"homepage": null,
|
||||
"mingw": {
|
||||
"include": "include",
|
||||
"lib": ".libs",
|
||||
"prepare": "./autogen.sh && ./configure --enable-module-recovery"
|
||||
},
|
||||
"owner": "bitcoin-core",
|
||||
"repo": "secp256k1",
|
||||
"rev": "26de4dfeb1f1436dae1fcf17f57bdaa43540f940",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/bitcoin-core/secp256k1/archive/26de4dfeb1f1436dae1fcf17f57bdaa43540f940.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"ent": {
|
||||
"mingw": {
|
||||
"prepare": "./configure"
|
||||
}
|
||||
},
|
||||
"ge-additions": {
|
||||
"mingw": {
|
||||
"make": "CFLAGS=-I../ed25519"
|
||||
}
|
||||
},
|
||||
"libaes_siv": {
|
||||
"mingw": {
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,10 @@
|
||||
"branch": "master",
|
||||
"description": "With argon2u. Based off https://github.com/P-H-C/phc-winner-argon2",
|
||||
"homepage": "",
|
||||
"mingw": {
|
||||
"include": ["include", "src/blake2"],
|
||||
"make": "libargon2.a"
|
||||
},
|
||||
"owner": "urbit",
|
||||
"repo": "argon2",
|
||||
"rev": "4da94a611ee62bad87ab2b131ffda3bcc0723d9c",
|
||||
@ -15,6 +19,10 @@
|
||||
"branch": "master",
|
||||
"description": "Submodule included by Urbit",
|
||||
"homepage": null,
|
||||
"mingw": {
|
||||
"strip": 1,
|
||||
"make": "all"
|
||||
},
|
||||
"owner": "urbit",
|
||||
"repo": "ed25519",
|
||||
"rev": "76385f2ebbbc9580a9c236952d68d11d73a6135c",
|
||||
@ -27,12 +35,17 @@
|
||||
"branch": "master",
|
||||
"description": "H2O - the optimized HTTP/1, HTTP/2, HTTP/3 server",
|
||||
"homepage": "https://h2o.examp1e.net",
|
||||
"mingw": {
|
||||
"include": "include",
|
||||
"prepare": "cmake -G\"MSYS Makefiles\" .",
|
||||
"make": "libh2o"
|
||||
},
|
||||
"owner": "h2o",
|
||||
"repo": "h2o",
|
||||
"rev": "v2.2.4",
|
||||
"sha256": "0176x0bzjry19zs074a9i5vhncc842xikmx43wj61jky318nq4w4",
|
||||
"rev": "v2.2.6",
|
||||
"sha256": "0qni676wqvxx0sl0pw9j0ph7zf2krrzqc1zwj73mgpdnsr8rsib7",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/h2o/h2o/archive/v2.2.4.tar.gz",
|
||||
"url": "https://github.com/h2o/h2o/archive/v2.2.6.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"hackage.nix": {
|
||||
@ -63,6 +76,9 @@
|
||||
"branch": "master",
|
||||
"description": null,
|
||||
"homepage": null,
|
||||
"mingw": {
|
||||
"make": "libscrypt.a CFLAGS_EXTRA=-ffast-math"
|
||||
},
|
||||
"owner": "urbit",
|
||||
"repo": "libscrypt",
|
||||
"rev": "029693ff1cbe4f69d3a2da87d0f4f034f92cc0c2",
|
||||
@ -75,6 +91,9 @@
|
||||
"branch": "master",
|
||||
"description": null,
|
||||
"homepage": null,
|
||||
"mingw": {
|
||||
"make": "static"
|
||||
},
|
||||
"owner": "urbit",
|
||||
"repo": "murmur3",
|
||||
"rev": "71a75d57ca4e7ca0f7fc2fd84abd93595b0624ca",
|
||||
@ -111,6 +130,11 @@
|
||||
"branch": "master",
|
||||
"description": null,
|
||||
"homepage": null,
|
||||
"mingw": {
|
||||
"include": "source/include",
|
||||
"lib": "build/Win64-MinGW-w64",
|
||||
"make": "-C build/Win64-MinGW-w64 libsoftfloat3.a"
|
||||
},
|
||||
"owner": "urbit",
|
||||
"repo": "berkeley-softfloat-3",
|
||||
"rev": "ec4c7e31b32e07aad80e52f65ff46ac6d6aad986",
|
||||
|
@ -9,7 +9,17 @@ worker = $(wildcard worker/*.c)
|
||||
tests = $(wildcard tests/*.c)
|
||||
bench = $(wildcard bench/*.c)
|
||||
|
||||
common = $(jets) $(noun) $(ur) $(vere)
|
||||
ifdef use_dumb_terminal
|
||||
vere := $(filter-out vere/io/term.c,$(vere))
|
||||
else
|
||||
vere := $(filter-out vere/io/dumb.c,$(vere))
|
||||
endif
|
||||
|
||||
ifdef compat
|
||||
compat := $(wildcard compat/$(compat)/*.c)
|
||||
endif
|
||||
|
||||
common = $(jets) $(noun) $(ur) $(vere) $(compat)
|
||||
headers = $(shell find include -type f)
|
||||
|
||||
common_objs = $(shell echo $(common) | sed 's/\.c/.o/g')
|
||||
|
61
pkg/urbit/build-mingw
Executable file
61
pkg/urbit/build-mingw
Executable file
@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
function xxd()
|
||||
{
|
||||
cch=0
|
||||
echo "unsigned char $2[] = {"
|
||||
while IFS='' read line
|
||||
do
|
||||
for i in $line
|
||||
do
|
||||
echo -n " 0x$i,"
|
||||
cch=$((cch+1))
|
||||
done
|
||||
echo
|
||||
done < <(od -An -v -tx1 $1)
|
||||
echo "};"
|
||||
echo "unsigned int $2_len = $cch;"
|
||||
}
|
||||
|
||||
case $(uname -s|tr A-Z a-z) in
|
||||
*mingw64*)
|
||||
;;
|
||||
*)
|
||||
echo This script works only on MingW64.
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ ! -e config.mk ]
|
||||
then
|
||||
# ensure required mingw packages are installed
|
||||
mpkgs=(cmake curl gcc jq libsigsegv libuv make wslay)
|
||||
pacman -S --needed autoconf automake-wrapper libtool patch ${mpkgs[@]/#/mingw-w64-x86_64-}
|
||||
|
||||
unset cdirs
|
||||
unset ldirs
|
||||
declare -a cdirs
|
||||
declare -a ldirs
|
||||
. <(jq -sr '
|
||||
add|to_entries|.[]|select(.value.mingw)|.key as $key|(if .value.url then "
|
||||
mkdir -p ../\($key)
|
||||
pushd ../\($key)
|
||||
curl -L \(.value.url)|(tar --strip \(.value.mingw.strip+1) -xzf - || true)" +
|
||||
("../urbit/compat/mingw/\($key).patch"|"
|
||||
[ -e \(.) ] && patch -p 1 <\(.)") else "
|
||||
pushd ../\($key)" end) + "
|
||||
\(.value.mingw.prepare//"")
|
||||
make \(.value.mingw.make//"")
|
||||
popd
|
||||
\(.value.mingw.include//"."|if type == "array" then .[] else . end|"cdirs+=(-I../\($key)/\(.))
|
||||
")\(.value.mingw.lib//"."|if type == "array" then .[] else . end|"ldirs+=(-L../\($key)/\(.))
|
||||
")"' ../../nix/sources.json ../../nix/sources-mingw.json)
|
||||
|
||||
xxd /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt include_ca_bundle_crt >include/ca-bundle.h
|
||||
xxd ../../bin/ivory.pill u3_Ivory_pill >include/ivory.h
|
||||
|
||||
CFLAGS="${CFLAGS-} ${cdirs[@]}" LDFLAGS="${LDFLAGS-} ${ldirs[@]}" PKG_CONFIG=echo ./configure
|
||||
fi
|
||||
|
||||
make build/urbit build/urbit-worker
|
22
pkg/urbit/compat/mingw/argon2u.patch
Executable file
22
pkg/urbit/compat/mingw/argon2u.patch
Executable file
@ -0,0 +1,22 @@
|
||||
diff --git a/src/encoding.c b/src/encoding.c
|
||||
index 73c36f5..753a1e1 100644
|
||||
--- a/src/encoding.c
|
||||
+++ b/src/encoding.c
|
||||
@@ -370,7 +370,7 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
||||
#undef BIN
|
||||
}
|
||||
|
||||
-void itoa(int i, char b[]){
|
||||
+static void encode_decimal(int i, char b[]){
|
||||
#ifdef ARGON2_JS
|
||||
|
||||
// because this generates WASM error:
|
||||
@@ -416,7 +416,7 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
||||
#define SX(x) \
|
||||
do { \
|
||||
char tmp[30]; \
|
||||
- itoa(x, tmp); \
|
||||
+ encode_decimal(x, tmp); \
|
||||
SS(tmp); \
|
||||
} while ((void)0, 0)
|
||||
|
436
pkg/urbit/compat/mingw/compat.c
Normal file
436
pkg/urbit/compat/mingw/compat.c
Normal file
@ -0,0 +1,436 @@
|
||||
#include "c/portable.h"
|
||||
#include <sys/utime.h>
|
||||
#include <windows.h>
|
||||
|
||||
// from https://github.com/git/git/blob/master/compat/mingw.c
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
int err_win_to_posix(DWORD winerr)
|
||||
{
|
||||
int error = ENOSYS;
|
||||
switch(winerr) {
|
||||
case ERROR_ACCESS_DENIED: error = EACCES; break;
|
||||
case ERROR_ACCOUNT_DISABLED: error = EACCES; break;
|
||||
case ERROR_ACCOUNT_RESTRICTION: error = EACCES; break;
|
||||
case ERROR_ALREADY_ASSIGNED: error = EBUSY; break;
|
||||
case ERROR_ALREADY_EXISTS: error = EEXIST; break;
|
||||
case ERROR_ARITHMETIC_OVERFLOW: error = ERANGE; break;
|
||||
case ERROR_BAD_COMMAND: error = EIO; break;
|
||||
case ERROR_BAD_DEVICE: error = ENODEV; break;
|
||||
case ERROR_BAD_DRIVER_LEVEL: error = ENXIO; break;
|
||||
case ERROR_BAD_EXE_FORMAT: error = ENOEXEC; break;
|
||||
case ERROR_BAD_FORMAT: error = ENOEXEC; break;
|
||||
case ERROR_BAD_LENGTH: error = EINVAL; break;
|
||||
case ERROR_BAD_PATHNAME: error = ENOENT; break;
|
||||
case ERROR_BAD_PIPE: error = EPIPE; break;
|
||||
case ERROR_BAD_UNIT: error = ENODEV; break;
|
||||
case ERROR_BAD_USERNAME: error = EINVAL; break;
|
||||
case ERROR_BROKEN_PIPE: error = EPIPE; break;
|
||||
case ERROR_BUFFER_OVERFLOW: error = ENAMETOOLONG; break;
|
||||
case ERROR_BUSY: error = EBUSY; break;
|
||||
case ERROR_BUSY_DRIVE: error = EBUSY; break;
|
||||
case ERROR_CALL_NOT_IMPLEMENTED: error = ENOSYS; break;
|
||||
case ERROR_CANNOT_MAKE: error = EACCES; break;
|
||||
case ERROR_CANTOPEN: error = EIO; break;
|
||||
case ERROR_CANTREAD: error = EIO; break;
|
||||
case ERROR_CANTWRITE: error = EIO; break;
|
||||
case ERROR_CRC: error = EIO; break;
|
||||
case ERROR_CURRENT_DIRECTORY: error = EACCES; break;
|
||||
case ERROR_DEVICE_IN_USE: error = EBUSY; break;
|
||||
case ERROR_DEV_NOT_EXIST: error = ENODEV; break;
|
||||
case ERROR_DIRECTORY: error = EINVAL; break;
|
||||
case ERROR_DIR_NOT_EMPTY: error = ENOTEMPTY; break;
|
||||
case ERROR_DISK_CHANGE: error = EIO; break;
|
||||
case ERROR_DISK_FULL: error = ENOSPC; break;
|
||||
case ERROR_DRIVE_LOCKED: error = EBUSY; break;
|
||||
case ERROR_ENVVAR_NOT_FOUND: error = EINVAL; break;
|
||||
case ERROR_EXE_MARKED_INVALID: error = ENOEXEC; break;
|
||||
case ERROR_FILENAME_EXCED_RANGE: error = ENAMETOOLONG; break;
|
||||
case ERROR_FILE_EXISTS: error = EEXIST; break;
|
||||
case ERROR_FILE_INVALID: error = ENODEV; break;
|
||||
case ERROR_FILE_NOT_FOUND: error = ENOENT; break;
|
||||
case ERROR_GEN_FAILURE: error = EIO; break;
|
||||
case ERROR_HANDLE_DISK_FULL: error = ENOSPC; break;
|
||||
case ERROR_INSUFFICIENT_BUFFER: error = ENOMEM; break;
|
||||
case ERROR_INVALID_ACCESS: error = EACCES; break;
|
||||
case ERROR_INVALID_ADDRESS: error = EFAULT; break;
|
||||
case ERROR_INVALID_BLOCK: error = EFAULT; break;
|
||||
case ERROR_INVALID_DATA: error = EINVAL; break;
|
||||
case ERROR_INVALID_DRIVE: error = ENODEV; break;
|
||||
case ERROR_INVALID_EXE_SIGNATURE: error = ENOEXEC; break;
|
||||
case ERROR_INVALID_FLAGS: error = EINVAL; break;
|
||||
case ERROR_INVALID_FUNCTION: error = ENOSYS; break;
|
||||
case ERROR_INVALID_HANDLE: error = EBADF; break;
|
||||
case ERROR_INVALID_LOGON_HOURS: error = EACCES; break;
|
||||
case ERROR_INVALID_NAME: error = EINVAL; break;
|
||||
case ERROR_INVALID_OWNER: error = EINVAL; break;
|
||||
case ERROR_INVALID_PARAMETER: error = EINVAL; break;
|
||||
case ERROR_INVALID_PASSWORD: error = EPERM; break;
|
||||
case ERROR_INVALID_PRIMARY_GROUP: error = EINVAL; break;
|
||||
case ERROR_INVALID_SIGNAL_NUMBER: error = EINVAL; break;
|
||||
case ERROR_INVALID_TARGET_HANDLE: error = EIO; break;
|
||||
case ERROR_INVALID_WORKSTATION: error = EACCES; break;
|
||||
case ERROR_IO_DEVICE: error = EIO; break;
|
||||
case ERROR_IO_INCOMPLETE: error = EINTR; break;
|
||||
case ERROR_LOCKED: error = EBUSY; break;
|
||||
case ERROR_LOCK_VIOLATION: error = EACCES; break;
|
||||
case ERROR_LOGON_FAILURE: error = EACCES; break;
|
||||
case ERROR_MAPPED_ALIGNMENT: error = EINVAL; break;
|
||||
case ERROR_META_EXPANSION_TOO_LONG: error = E2BIG; break;
|
||||
case ERROR_MORE_DATA: error = EPIPE; break;
|
||||
case ERROR_NEGATIVE_SEEK: error = ESPIPE; break;
|
||||
case ERROR_NOACCESS: error = EFAULT; break;
|
||||
case ERROR_NONE_MAPPED: error = EINVAL; break;
|
||||
case ERROR_NOT_ENOUGH_MEMORY: error = ENOMEM; break;
|
||||
case ERROR_NOT_READY: error = EAGAIN; break;
|
||||
case ERROR_NOT_SAME_DEVICE: error = EXDEV; break;
|
||||
case ERROR_NO_DATA: error = EPIPE; break;
|
||||
case ERROR_NO_MORE_SEARCH_HANDLES: error = EIO; break;
|
||||
case ERROR_NO_PROC_SLOTS: error = EAGAIN; break;
|
||||
case ERROR_NO_SUCH_PRIVILEGE: error = EACCES; break;
|
||||
case ERROR_OPEN_FAILED: error = EIO; break;
|
||||
case ERROR_OPEN_FILES: error = EBUSY; break;
|
||||
case ERROR_OPERATION_ABORTED: error = EINTR; break;
|
||||
case ERROR_OUTOFMEMORY: error = ENOMEM; break;
|
||||
case ERROR_PASSWORD_EXPIRED: error = EACCES; break;
|
||||
case ERROR_PATH_BUSY: error = EBUSY; break;
|
||||
case ERROR_PATH_NOT_FOUND: error = ENOENT; break;
|
||||
case ERROR_PIPE_BUSY: error = EBUSY; break;
|
||||
case ERROR_PIPE_CONNECTED: error = EPIPE; break;
|
||||
case ERROR_PIPE_LISTENING: error = EPIPE; break;
|
||||
case ERROR_PIPE_NOT_CONNECTED: error = EPIPE; break;
|
||||
case ERROR_PRIVILEGE_NOT_HELD: error = EACCES; break;
|
||||
case ERROR_READ_FAULT: error = EIO; break;
|
||||
case ERROR_SEEK: error = EIO; break;
|
||||
case ERROR_SEEK_ON_DEVICE: error = ESPIPE; break;
|
||||
case ERROR_SHARING_BUFFER_EXCEEDED: error = ENFILE; break;
|
||||
case ERROR_SHARING_VIOLATION: error = EACCES; break;
|
||||
case ERROR_STACK_OVERFLOW: error = ENOMEM; break;
|
||||
case ERROR_SUCCESS: error = 0; break;
|
||||
case ERROR_SWAPERROR: error = ENOENT; break;
|
||||
case ERROR_TOO_MANY_MODULES: error = EMFILE; break;
|
||||
case ERROR_TOO_MANY_OPEN_FILES: error = EMFILE; break;
|
||||
case ERROR_UNRECOGNIZED_MEDIA: error = ENXIO; break;
|
||||
case ERROR_UNRECOGNIZED_VOLUME: error = ENODEV; break;
|
||||
case ERROR_WAIT_NO_CHILDREN: error = ECHILD; break;
|
||||
case ERROR_WRITE_FAULT: error = EIO; break;
|
||||
case ERROR_WRITE_PROTECT: error = EROFS; break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
int kill(pid_t pid, int sig)
|
||||
{
|
||||
if (pid > 0 && sig == SIGKILL) {
|
||||
HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
|
||||
|
||||
if (TerminateProcess(h, -1)) {
|
||||
CloseHandle(h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
errno = err_win_to_posix(GetLastError());
|
||||
CloseHandle(h);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: handle signals for self
|
||||
// TODO: send SIGTERM as ctrl-c: https://stackoverflow.com/questions/813086/can-i-send-a-ctrl-c-sigint-to-an-application-on-windows
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static HANDLE timer_event;
|
||||
static HANDLE timer_thread;
|
||||
static int timer_signal;
|
||||
static int timer_interval;
|
||||
static int one_shot;
|
||||
static __p_sig_fn_t timer_fn = SIG_DFL, sigint_fn = SIG_DFL;
|
||||
|
||||
/* The timer works like this:
|
||||
* The thread, ticktack(), is a trivial routine that most of the time
|
||||
* only waits to receive the signal to terminate. The main thread tells
|
||||
* the thread to terminate by setting the timer_event to the signalled
|
||||
* state.
|
||||
* But ticktack() interrupts the wait state after the timer's interval
|
||||
* length to call the signal handler.
|
||||
*/
|
||||
|
||||
static unsigned __stdcall ticktack(void *dummy)
|
||||
{
|
||||
while (WaitForSingleObject(timer_event, timer_interval) == WAIT_TIMEOUT) {
|
||||
raise(timer_signal);
|
||||
if (one_shot)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int error(const char* s, ...)
|
||||
{
|
||||
// TODO
|
||||
va_list ap;
|
||||
va_start(ap, s);
|
||||
vfprintf(stderr, s, ap);
|
||||
va_end(ap);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int start_timer_thread(void)
|
||||
{
|
||||
timer_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (timer_event) {
|
||||
timer_thread = (HANDLE) _beginthreadex(NULL, 0, ticktack, NULL, 0, NULL);
|
||||
if (!timer_thread )
|
||||
return errno = ENOMEM,
|
||||
error("cannot start timer thread");
|
||||
} else
|
||||
return errno = ENOMEM,
|
||||
error("cannot allocate resources for timer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void stop_timer_thread(void)
|
||||
{
|
||||
if (timer_event)
|
||||
SetEvent(timer_event); /* tell thread to terminate */
|
||||
if (timer_thread) {
|
||||
int rc = WaitForSingleObject(timer_thread, 10000);
|
||||
if (rc == WAIT_TIMEOUT)
|
||||
error("timer thread did not terminate timely");
|
||||
else if (rc != WAIT_OBJECT_0)
|
||||
error("waiting for timer thread failed: %lu",
|
||||
GetLastError());
|
||||
CloseHandle(timer_thread);
|
||||
}
|
||||
if (timer_event)
|
||||
CloseHandle(timer_event);
|
||||
timer_event = NULL;
|
||||
timer_thread = NULL;
|
||||
}
|
||||
|
||||
static inline int is_timeval_eq(const struct timeval *i1, const struct timeval *i2)
|
||||
{
|
||||
return i1->tv_sec == i2->tv_sec && i1->tv_usec == i2->tv_usec;
|
||||
}
|
||||
|
||||
int setitimer(int type, struct itimerval *in, struct itimerval *out)
|
||||
{
|
||||
static const struct timeval zero;
|
||||
static int atexit_done;
|
||||
|
||||
if (out != NULL)
|
||||
return errno = EINVAL,
|
||||
error("setitimer param 3 != NULL not implemented");
|
||||
if (!is_timeval_eq(&in->it_interval, &zero) &&
|
||||
!is_timeval_eq(&in->it_interval, &in->it_value))
|
||||
return errno = EINVAL,
|
||||
error("setitimer: it_interval must be zero or eq it_value");
|
||||
|
||||
if (timer_thread)
|
||||
stop_timer_thread();
|
||||
|
||||
if (is_timeval_eq(&in->it_value, &zero) &&
|
||||
is_timeval_eq(&in->it_interval, &zero))
|
||||
return 0;
|
||||
|
||||
timer_signal = type == ITIMER_VIRTUAL ? SIGVTALRM : SIGALRM;
|
||||
timer_interval = in->it_value.tv_sec * 1000 + in->it_value.tv_usec / 1000;
|
||||
one_shot = is_timeval_eq(&in->it_interval, &zero);
|
||||
if (!atexit_done) {
|
||||
atexit(stop_timer_thread);
|
||||
atexit_done = 1;
|
||||
}
|
||||
return start_timer_thread();
|
||||
}
|
||||
|
||||
// from msys2 mingw-packages-dev patches
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
static DWORD __map_mmap_prot_page(const int prot)
|
||||
{
|
||||
DWORD protect = 0;
|
||||
|
||||
if (prot == PROT_NONE)
|
||||
return protect;
|
||||
|
||||
if ((prot & PROT_EXEC) != 0)
|
||||
{
|
||||
protect = ((prot & PROT_WRITE) != 0) ?
|
||||
PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
|
||||
}
|
||||
else
|
||||
{
|
||||
protect = ((prot & PROT_WRITE) != 0) ?
|
||||
PAGE_READWRITE : PAGE_READONLY;
|
||||
}
|
||||
|
||||
return protect;
|
||||
}
|
||||
|
||||
static DWORD __map_mmap_prot_file(const int prot)
|
||||
{
|
||||
DWORD desiredAccess = 0;
|
||||
|
||||
if (prot == PROT_NONE)
|
||||
return desiredAccess;
|
||||
|
||||
if ((prot & PROT_READ) != 0)
|
||||
desiredAccess |= FILE_MAP_READ;
|
||||
if ((prot & PROT_WRITE) != 0)
|
||||
desiredAccess |= FILE_MAP_WRITE;
|
||||
if ((prot & PROT_EXEC) != 0)
|
||||
desiredAccess |= FILE_MAP_EXECUTE;
|
||||
|
||||
return desiredAccess;
|
||||
}
|
||||
|
||||
void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
|
||||
{
|
||||
HANDLE fm, h;
|
||||
|
||||
void * map = MAP_FAILED;
|
||||
|
||||
const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ?
|
||||
(DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
|
||||
const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
|
||||
(DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
|
||||
const DWORD protect = __map_mmap_prot_page(prot);
|
||||
const DWORD desiredAccess = __map_mmap_prot_file(prot);
|
||||
|
||||
errno = 0;
|
||||
|
||||
if (len == 0
|
||||
/* Usupported protection combinations */
|
||||
|| prot == PROT_EXEC)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
if ((flags & MAP_ANON) == 0)
|
||||
{
|
||||
h = (HANDLE)_get_osfhandle(fildes);
|
||||
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
errno = EBADF;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
}
|
||||
else h = INVALID_HANDLE_VALUE;
|
||||
|
||||
fm = CreateFileMapping(h, NULL, protect, 0, len, NULL);
|
||||
|
||||
if (fm == NULL)
|
||||
{
|
||||
errno = err_win_to_posix(GetLastError());
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
map = MapViewOfFileEx(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len, addr);
|
||||
errno = err_win_to_posix(GetLastError());
|
||||
|
||||
CloseHandle(fm);
|
||||
|
||||
if (map == NULL)
|
||||
return MAP_FAILED;
|
||||
|
||||
if ((flags & MAP_FIXED) != 0 && map != addr)
|
||||
{
|
||||
UnmapViewOfFile(map);
|
||||
errno = EEXIST;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
int munmap(void *addr, size_t len)
|
||||
{
|
||||
if (UnmapViewOfFile(addr))
|
||||
return 0;
|
||||
|
||||
errno = err_win_to_posix(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
int msync(void *addr, size_t len, int flags)
|
||||
{
|
||||
if (FlushViewOfFile(addr, len))
|
||||
return 0;
|
||||
|
||||
errno = err_win_to_posix(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
// libgcc built for mingw has included an implementation of mprotect
|
||||
// via VirtualProtect since olden days, but it takes int rather than size_t
|
||||
// and therefore fails or does unexpected things for >2GB blocks on 64-bit
|
||||
// https://github.com/gcc-mirror/gcc/blob/master/libgcc/libgcc2.c
|
||||
int mprotect (void *addr, size_t len, int prot)
|
||||
{
|
||||
DWORD np, op;
|
||||
|
||||
if (prot == (PROT_READ | PROT_WRITE | PROT_EXEC))
|
||||
np = PAGE_EXECUTE_READWRITE;
|
||||
else if (prot == (PROT_READ | PROT_EXEC))
|
||||
np = PAGE_EXECUTE_READ;
|
||||
else if (prot == (PROT_EXEC))
|
||||
np = PAGE_EXECUTE;
|
||||
else if (prot == (PROT_READ | PROT_WRITE))
|
||||
np = PAGE_READWRITE;
|
||||
else if (prot == (PROT_READ))
|
||||
np = PAGE_READONLY;
|
||||
else if (prot == 0)
|
||||
np = PAGE_NOACCESS;
|
||||
else
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (VirtualProtect (addr, len, np, &op))
|
||||
return 0;
|
||||
|
||||
// NB: return code of ntdll!RtlGetLastNtStatus() is useful
|
||||
// for diagnosing obscure VirtualProtect failures
|
||||
errno = err_win_to_posix(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
int utimes(const char *path, const struct timeval times[2])
|
||||
{
|
||||
// TODO: implement in terms of utime
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fdatasync(int fildes)
|
||||
{
|
||||
HANDLE h = (HANDLE)_get_osfhandle(fildes);
|
||||
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (FlushFileBuffers(h))
|
||||
{
|
||||
errno = 0;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = err_win_to_posix(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
char *realpath(const char *path, char *resolved_path)
|
||||
{
|
||||
// TODO
|
||||
return strdup(path);
|
||||
}
|
41
pkg/urbit/compat/mingw/compat.h
Normal file
41
pkg/urbit/compat/mingw/compat.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef _MINGW_IO_H
|
||||
#define _MINGW_IO_H
|
||||
|
||||
// msvcrt setjmp/longjmp are broken on 64-bit systems, use gcc builtins
|
||||
typedef struct jmp_buf {
|
||||
intptr_t buffer[5];
|
||||
int retval;
|
||||
} jmp_buf;
|
||||
|
||||
#define _setjmp setjmp
|
||||
#define _longjmp longjmp
|
||||
#define longjmp(buf, val) {buf.retval = (val); __builtin_longjmp(buf.buffer, 1);}
|
||||
#define setjmp(buf) (__builtin_setjmp(buf.buffer) ? (buf.retval) : 0)
|
||||
|
||||
// no profiling on MingW means signal masks are not used
|
||||
#define sigjmp_buf jmp_buf
|
||||
#define siglongjmp longjmp
|
||||
#define sigsetjmp(A, B) setjmp(A)
|
||||
|
||||
#define mkdir(A, B) mkdir(A)
|
||||
|
||||
char *realpath(const char *path, char *resolved_path);
|
||||
int fdatasync(int fd);
|
||||
int utimes(const char *path, const struct timeval times[2]);
|
||||
|
||||
int kill(pid_t pid, int signum);
|
||||
|
||||
#define SIGALRM 1233
|
||||
#define SIGVTALRM 1234
|
||||
#define SIGINFO 1235
|
||||
#define SIGUSR1 1236
|
||||
#define SIGTSTP 1238
|
||||
|
||||
#define ITIMER_REAL 0
|
||||
#define ITIMER_VIRTUAL 1
|
||||
struct itimerval {
|
||||
struct timeval it_value, it_interval;
|
||||
};
|
||||
int setitimer(int type, struct itimerval *in, struct itimerval *out);
|
||||
|
||||
#endif//_MINGW_IO_H
|
13
pkg/urbit/compat/mingw/ed25519.patch
Normal file
13
pkg/urbit/compat/mingw/ed25519.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/Makefile
|
||||
@@ -0,0 +1,8 @@
|
||||
+.PHONY: all clean
|
||||
+
|
||||
+all: *.c *.h
|
||||
+ $(CC) -c -O3 -Wall -Werror *.c
|
||||
+ $(AR) rcs libed25519.a *.o
|
||||
+
|
||||
+clean:
|
||||
+ rm -f *.o *.a
|
1834
pkg/urbit/compat/mingw/h2o.patch
Executable file
1834
pkg/urbit/compat/mingw/h2o.patch
Executable file
File diff suppressed because it is too large
Load Diff
17
pkg/urbit/compat/mingw/libscrypt.patch
Executable file
17
pkg/urbit/compat/mingw/libscrypt.patch
Executable file
@ -0,0 +1,17 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 783c537..3156ee2 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -12,10 +12,9 @@ LDFLAGS_EXTRA?=-Wl,-z,relro
|
||||
|
||||
all: reference
|
||||
|
||||
-OBJS= crypto_scrypt-nosse.o sha256.o crypto-mcf.o b64.o crypto-scrypt-saltgen.o crypto_scrypt-check.o crypto_scrypt-hash.o slowequals.o
|
||||
+OBJS= crypto_scrypt-nosse.o sha256.o crypto-mcf.o b64.o slowequals.o
|
||||
|
||||
-libscrypt.so.0: $(OBJS)
|
||||
- $(CC) $(LDFLAGS) -shared -o libscrypt.so.0 $(OBJS) -lm -lc
|
||||
+libscrypt.a: $(OBJS)
|
||||
ar rcs libscrypt.a $(OBJS)
|
||||
|
||||
reference: libscrypt.so.0 main.o crypto_scrypt-hexconvert.o
|
74
pkg/urbit/compat/mingw/lmdb.patch
Normal file
74
pkg/urbit/compat/mingw/lmdb.patch
Normal file
@ -0,0 +1,74 @@
|
||||
diff --git a/mdb.c b/mdb.c
|
||||
--- a/mdb.c
|
||||
+++ b/mdb.c
|
||||
@@ -1707,28 +1707,27 @@ static char *const mdb_errstr[] = {
|
||||
"MDB_PROBLEM: Unexpected problem - txn should abort",
|
||||
};
|
||||
|
||||
-char *
|
||||
-mdb_strerror(int err)
|
||||
+void
|
||||
+mdb_logerror(FILE* f, int err, const char* fmt, ...)
|
||||
{
|
||||
-#ifdef _WIN32
|
||||
- /** HACK: pad 4KB on stack over the buf. Return system msgs in buf.
|
||||
- * This works as long as no function between the call to mdb_strerror
|
||||
- * and the actual use of the message uses more than 4K of stack.
|
||||
- */
|
||||
-#define MSGSIZE 1024
|
||||
-#define PADSIZE 4096
|
||||
- char buf[MSGSIZE+PADSIZE], *ptr = buf;
|
||||
-#endif
|
||||
+ va_list ap;
|
||||
+ va_start(ap, fmt);
|
||||
+ vfprintf(f, fmt, ap);
|
||||
+ va_end(ap);
|
||||
+
|
||||
int i;
|
||||
if (!err)
|
||||
- return ("Successful return: 0");
|
||||
+ {
|
||||
+ fprintf(stderr, ": %s\r\n", "Successful return: 0");
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
if (err >= MDB_KEYEXIST && err <= MDB_LAST_ERRCODE) {
|
||||
i = err - MDB_KEYEXIST;
|
||||
- return mdb_errstr[i];
|
||||
+ fprintf(stderr, ": %s\r\n", mdb_errstr[i]);
|
||||
+ return;
|
||||
}
|
||||
|
||||
-#ifdef _WIN32
|
||||
/* These are the C-runtime error codes we use. The comment indicates
|
||||
* their numeric value, and the Win32 error they would correspond to
|
||||
* if the error actually came from a Win32 API. A major mess, we should
|
||||
@@ -1742,18 +1741,20 @@ mdb_strerror(int err)
|
||||
case EBUSY: /* 16, CURRENT_DIRECTORY */
|
||||
case EINVAL: /* 22, BAD_COMMAND */
|
||||
case ENOSPC: /* 28, OUT_OF_PAPER */
|
||||
- return strerror(err);
|
||||
+ fprintf(stderr, ": %s\r\n", strerror(err));
|
||||
default:
|
||||
;
|
||||
}
|
||||
- buf[0] = 0;
|
||||
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
+ LPSTR ptr;
|
||||
+ if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
- NULL, err, 0, ptr, MSGSIZE, (va_list *)buf+MSGSIZE);
|
||||
- return ptr;
|
||||
-#else
|
||||
- return strerror(err);
|
||||
-#endif
|
||||
+ NULL, err, 0, (LPSTR)&ptr, sizeof (LPSTR), NULL))
|
||||
+ {
|
||||
+ fprintf(stderr, ": %s\r\n", ptr);
|
||||
+ LocalFree(ptr);
|
||||
+ } else
|
||||
+ fprintf(stderr, ": <%d>\r\n", err);
|
||||
}
|
||||
|
||||
/** assert(3) variant in cursor context */
|
26
pkg/urbit/compat/mingw/mman.h
Normal file
26
pkg/urbit/compat/mingw/mman.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef _SYS_MMAN_H
|
||||
#define _SYS_MMAN_H
|
||||
|
||||
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
|
||||
int munmap(void *addr, size_t length);
|
||||
int msync(void *addr, size_t length, int flags);
|
||||
int mprotect(void *addr, size_t len, int prot);
|
||||
|
||||
#define PROT_NONE 0x00 /* No access. */
|
||||
#define PROT_READ 0x01 /* Pages can be read. */
|
||||
#define PROT_WRITE 0x02 /* Pages can be written. */
|
||||
#define PROT_EXEC 0x04 /* Pages can be executed. */
|
||||
|
||||
#define MAP_FILE 0x0001 /* Mapped from a file or device. */
|
||||
#define MAP_ANON 0x0002 /* Allocated from anonymous virtual memory. */
|
||||
#define MAP_TYPE 0x000f /* Mask for type field. */
|
||||
#define MAP_SHARED 0x0010 /* Share changes. */
|
||||
#define MAP_PRIVATE 0x0000 /* Changes private; copy pages on write. */
|
||||
#define MAP_FIXED 0x0100 /* Map address must be exactly as requested. */
|
||||
#define MAP_FAILED ((void *) -1)
|
||||
|
||||
#define MS_ASYNC 1 /* Sync memory asynchronously. */
|
||||
#define MS_SYNC 0 /* Synchronous memory sync. */
|
||||
#define MS_INVALIDATE 2 /* Invalidate the caches. */
|
||||
|
||||
#endif//_SYS_MMAN_H
|
13
pkg/urbit/compat/mingw/murmur3.patch
Normal file
13
pkg/urbit/compat/mingw/murmur3.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/makefile b/makefile
|
||||
--- a/makefile
|
||||
+++ b/makefile
|
||||
@@ -12,5 +12,9 @@ shared: murmur3.c murmur3.h
|
||||
$(CC) -fPIC -O3 -c murmur3.c
|
||||
$(CC) -shared -Wl,--export-dynamic murmur3.o -o libmurmur3.so
|
||||
|
||||
+static: murmur3.c murmur3.h
|
||||
+ $(CC) -fPIC -O3 -c murmur3.c
|
||||
+ $(AR) rcs libmurmur3.a murmur3.o
|
||||
+
|
||||
clean:
|
||||
rm -rf example *.o *.so
|
36
pkg/urbit/compat/mingw/softfloat3.patch
Normal file
36
pkg/urbit/compat/mingw/softfloat3.patch
Normal file
@ -0,0 +1,36 @@
|
||||
diff --git a/build/Win64-MinGW-w64/Makefile b/build/Win64-MinGW-w64/Makefile
|
||||
--- a/build/Win64-MinGW-w64/Makefile
|
||||
+++ b/build/Win64-MinGW-w64/Makefile
|
||||
@@ -46,7 +46,8 @@ C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include
|
||||
COMPILE_C = \
|
||||
x86_64-w64-mingw32-gcc -c -Werror-implicit-function-declaration \
|
||||
-DSOFTFLOAT_FAST_INT64 $(SOFTFLOAT_OPTS) $(C_INCLUDES) -O2 -o $@
|
||||
-MAKELIB = x86_64-w64-mingw32-ar crs $@
|
||||
+MAKELIB = x86_64-w64-mingw32-gcc-ar crs $@
|
||||
+LIBNAME = libsoftfloat3
|
||||
|
||||
OBJ = .o
|
||||
LIB = .a
|
||||
@@ -54,7 +55,7 @@ LIB = .a
|
||||
OTHER_HEADERS = $(SOURCE_DIR)/include/opts-GCC.h
|
||||
|
||||
.PHONY: all
|
||||
-all: softfloat$(LIB)
|
||||
+all: $(LIBNAME)$(LIB)
|
||||
|
||||
OBJS_PRIMITIVES = \
|
||||
s_eq128$(OBJ) \
|
||||
@@ -380,11 +381,11 @@ $(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c
|
||||
$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c
|
||||
$(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c
|
||||
|
||||
-softfloat$(LIB): $(OBJS_ALL)
|
||||
+$(LIBNAME)$(LIB): $(OBJS_ALL)
|
||||
$(DELETE) $@
|
||||
$(MAKELIB) $^
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
- $(DELETE) $(OBJS_ALL) softfloat$(LIB)
|
||||
+ $(DELETE) $(OBJS_ALL) $(LIBNAME)$(LIB)
|
||||
|
8
pkg/urbit/compat/mingw/termios.h
Normal file
8
pkg/urbit/compat/mingw/termios.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _TERMIOS_H
|
||||
#define _TERMIOS_H
|
||||
|
||||
struct termios {
|
||||
char _dummy;
|
||||
};
|
||||
|
||||
#endif
|
15
pkg/urbit/configure
vendored
15
pkg/urbit/configure
vendored
@ -6,7 +6,7 @@ URBIT_VERSION="$(cat ./version)"
|
||||
|
||||
deps=" \
|
||||
curl gmp sigsegv argon2 ed25519 ent h2o scrypt uv murmur3 secp256k1 \
|
||||
softfloat3 ssl crypto z lmdb ge-additions aes_siv pthread \
|
||||
softfloat3 aes_siv ssl crypto z lmdb ge-additions pthread \
|
||||
"
|
||||
|
||||
headers=" \
|
||||
@ -58,6 +58,15 @@ esac
|
||||
|
||||
# TODO Determine if the target cpu is little or big endian.
|
||||
case $(tr A-Z a-z <<< $os) in
|
||||
*mingw*)
|
||||
defmacro U3_OS_mingw 1
|
||||
|
||||
# increase default thread stack size and link Windows implibs
|
||||
ldextra="-Wl,--stack,67108864 -lbcrypt -lws2_32"
|
||||
mkextra="use_dumb_terminal = 1"
|
||||
vcompat="compat = mingw"
|
||||
CFLAGS="${CFLAGS-} -DH2O_NO_UNIX_SOCKETS -Icompat/mingw"
|
||||
;;
|
||||
*linux*)
|
||||
defmacro U3_OS_linux 1
|
||||
defmacro U3_OS_PROF 1
|
||||
@ -94,8 +103,10 @@ done
|
||||
|
||||
cat >config.mk <<EOF
|
||||
CFLAGS := ${CFLAGS-} -funsigned-char -ffast-math -fcommon -std=gnu99
|
||||
LDFLAGS := $LDFLAGS
|
||||
LDFLAGS := $LDFLAGS ${ldextra-}
|
||||
CC := ${CC-cc}
|
||||
${vcompat-}
|
||||
${mkextra-}
|
||||
EOF
|
||||
|
||||
echo == config.mk == >&2
|
||||
|
@ -590,6 +590,10 @@ static void _on_boot_completed_cb() {
|
||||
static void
|
||||
_fork_into_background_process()
|
||||
{
|
||||
#if defined(U3_OS_mingw)
|
||||
fprintf(stderr, "Daemon mode is not yet supported on MingW\r\n");
|
||||
exit(1);
|
||||
#else
|
||||
c3_i pipefd[2];
|
||||
|
||||
if ( 0 != pipe(pipefd) ) {
|
||||
@ -618,6 +622,7 @@ _fork_into_background_process()
|
||||
c3_i status;
|
||||
wait(&status);
|
||||
exit(WEXITSTATUS(status));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* _stop_on_boot_completed_cb(): exit gracefully after boot is complete
|
||||
@ -642,7 +647,12 @@ main(c3_i argc,
|
||||
// Set `u3_Host.wrk_c` to the worker executable path.
|
||||
c3_i worker_exe_len = 1 + strlen(argv[0]) + strlen("-worker");
|
||||
u3_Host.wrk_c = c3_malloc(worker_exe_len);
|
||||
#if defined(U3_OS_mingw)
|
||||
strcpy(u3_Host.wrk_c, argv[0]);
|
||||
strcpy(u3_Host.wrk_c + strlen(argv[0]) - 4, "-worker.exe");
|
||||
#else
|
||||
snprintf(u3_Host.wrk_c, worker_exe_len, "%s-worker", argv[0]);
|
||||
#endif
|
||||
|
||||
if ( c3y == u3_Host.ops_u.dem ) {
|
||||
_fork_into_background_process();
|
||||
|
@ -72,6 +72,23 @@
|
||||
# include <sys/resource.h>
|
||||
# include <sys/mman.h>
|
||||
|
||||
# elif defined(U3_OS_mingw)
|
||||
# define _POSIX
|
||||
# include <openssl/opensslv.h>
|
||||
# include <inttypes.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <stdarg.h>
|
||||
# include <unistd.h>
|
||||
# include <stdint.h>
|
||||
# include <assert.h>
|
||||
# include <stdio.h>
|
||||
# include <dirent.h>
|
||||
# include <signal.h>
|
||||
# include <sys/time.h>
|
||||
# include "mman.h"
|
||||
# include "compat.h"
|
||||
|
||||
# else
|
||||
#error "port: headers"
|
||||
# endif
|
||||
@ -101,19 +118,15 @@
|
||||
# define U3_OS_LoomBase 0x36000000
|
||||
# endif
|
||||
# define U3_OS_LoomBits 29 // ie, 2^29 words == 2GB
|
||||
# elif defined(U3_OS_osx)
|
||||
# elif defined(U3_OS_osx) || defined(U3_OS_bsd)
|
||||
# ifdef __LP64__
|
||||
# define U3_OS_LoomBase 0x200000000
|
||||
# else
|
||||
# define U3_OS_LoomBase 0x4000000
|
||||
# endif
|
||||
# define U3_OS_LoomBits 29 // ie, 2^29 words == 2GB
|
||||
# elif defined(U3_OS_bsd)
|
||||
# ifdef __LP64__
|
||||
# define U3_OS_LoomBase 0x200000000
|
||||
# else
|
||||
# define U3_OS_LoomBase 0x4000000
|
||||
# endif
|
||||
# elif defined(U3_OS_mingw)
|
||||
# define U3_OS_LoomBase 0x28000000000
|
||||
# define U3_OS_LoomBits 29 // ie, 2^29 words == 2GB
|
||||
# else
|
||||
# error "port: LoomBase"
|
||||
@ -157,7 +170,7 @@
|
||||
|
||||
/* Byte swapping.
|
||||
*/
|
||||
# if defined(U3_OS_linux) || defined(U3_OS_bsd)
|
||||
# if defined(U3_OS_linux) || defined(U3_OS_bsd) || defined(U3_OS_mingw)
|
||||
# define c3_bswap_16(x) bswap_16(x)
|
||||
# define c3_bswap_32(x) bswap_32(x)
|
||||
# define c3_bswap_64(x) bswap_64(x)
|
||||
@ -171,7 +184,7 @@
|
||||
|
||||
/* Sync.
|
||||
*/
|
||||
# if defined(U3_OS_linux)
|
||||
# if defined(U3_OS_linux) || defined(U3_OS_mingw)
|
||||
# define c3_sync(fd) (fdatasync(fd))
|
||||
# elif defined(U3_OS_osx)
|
||||
# define c3_sync(fd) (fcntl(fd, F_FULLFSYNC, 0))
|
||||
@ -186,7 +199,7 @@
|
||||
# if defined(U3_OS_linux)
|
||||
# include <stdio_ext.h>
|
||||
# define c3_fpurge __fpurge
|
||||
# elif defined(U3_OS_bsd) || defined(U3_OS_osx)
|
||||
# elif defined(U3_OS_bsd) || defined(U3_OS_osx) || defined(U3_OS_mingw)
|
||||
# define c3_fpurge fpurge
|
||||
# else
|
||||
# error "port: fpurge"
|
||||
@ -194,7 +207,7 @@
|
||||
|
||||
/* Stat.
|
||||
*/
|
||||
# if defined(U3_OS_linux)
|
||||
# if defined(U3_OS_linux) || defined(U3_OS_mingw)
|
||||
# define c3_stat_mtime(dp) (u3_time_t_in_ts((dp)->st_mtime))
|
||||
# elif defined(U3_OS_osx)
|
||||
# define c3_stat_mtime(dp) (u3_time_in_ts(&((dp)->st_mtimespec)))
|
||||
|
@ -717,7 +717,7 @@
|
||||
*/
|
||||
u3_atom
|
||||
u3_time_in_ts(struct timespec* tim_ts);
|
||||
#if defined(U3_OS_linux)
|
||||
#if defined(U3_OS_linux) || defined(U3_OS_mingw)
|
||||
/* u3_time_t_in_ts(): urbit time from time_t.
|
||||
*/
|
||||
u3_atom
|
||||
|
@ -1557,6 +1557,10 @@ u3m_wall(u3_noun wol)
|
||||
static void
|
||||
_cm_limits(void)
|
||||
{
|
||||
# ifdef U3_OS_mingw
|
||||
// Windows doesn't have rlimits. Default maximum thread
|
||||
// stack size is set in the executable file header.
|
||||
# else
|
||||
struct rlimit rlm;
|
||||
|
||||
// Moar stack.
|
||||
@ -1604,6 +1608,7 @@ _cm_limits(void)
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
||||
/* _cm_signals(): set up interrupts, etc.
|
||||
|
@ -451,6 +451,7 @@ u3_lmdb_save_meta(MDB_env* env_u,
|
||||
return c3y;
|
||||
}
|
||||
|
||||
#if !defined(U3_OS_mingw)
|
||||
/* mdb_logerror(): writes an error message and lmdb error code to f.
|
||||
*/
|
||||
void mdb_logerror(FILE* f, int err, const char* fmt, ...)
|
||||
@ -461,3 +462,4 @@ void mdb_logerror(FILE* f, int err, const char* fmt, ...)
|
||||
va_end(ap);
|
||||
fprintf(f, ": %s\r\n", mdb_strerror(err));
|
||||
}
|
||||
#endif
|
||||
|
171
pkg/urbit/vere/io/dumb.c
Normal file
171
pkg/urbit/vere/io/dumb.c
Normal file
@ -0,0 +1,171 @@
|
||||
/* vere/dumb.c
|
||||
**
|
||||
*/
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
|
||||
/* u3_term_log_init(): initialize terminal for logging
|
||||
*/
|
||||
void
|
||||
u3_term_log_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* u3_term_log_exit(): clean up terminal.
|
||||
*/
|
||||
void
|
||||
u3_term_log_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* u3_term_start_spinner(): prepare spinner state. RETAIN.
|
||||
*/
|
||||
void
|
||||
u3_term_start_spinner(u3_atom say, c3_o del_o)
|
||||
{
|
||||
}
|
||||
|
||||
/* u3_term_stop_spinner(): reset spinner state and restore input line.
|
||||
*/
|
||||
void
|
||||
u3_term_stop_spinner(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* u3_term_get_blew(): return window size [columns rows].
|
||||
*/
|
||||
u3_noun
|
||||
u3_term_get_blew(c3_l tid_l)
|
||||
{
|
||||
return u3nc(80, 24);
|
||||
}
|
||||
|
||||
/* u3_term_ef_winc(): window change. Just console right now.
|
||||
*/
|
||||
void
|
||||
u3_term_ef_winc(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* u3_term_ef_ctlc(): send ^C on console.
|
||||
*/
|
||||
void
|
||||
u3_term_ef_ctlc(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* u3_term_io_hija(): hijack console for fprintf, returning FILE*.
|
||||
*/
|
||||
FILE*
|
||||
u3_term_io_hija(void)
|
||||
{
|
||||
return stdout;
|
||||
}
|
||||
|
||||
/* u3_term_io_loja(): release console from fprintf.
|
||||
*/
|
||||
void
|
||||
u3_term_io_loja(int x)
|
||||
{
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* u3_term_it_log(): writes a log message
|
||||
*/
|
||||
void
|
||||
u3_term_io_log(c3_c* line)
|
||||
{
|
||||
FILE* stream = u3_term_io_hija();
|
||||
u3_term_io_loja(fprintf(stream, "%s", line));
|
||||
}
|
||||
|
||||
/* _term_ovum_plan(): plan term ovums, configuring spinner.
|
||||
*/
|
||||
static u3_ovum*
|
||||
_term_ovum_plan(u3_auto* car_u, u3_noun wir, u3_noun cad)
|
||||
{
|
||||
u3_ovum* egg_u = u3_auto_plan(car_u, u3_ovum_init(0, c3__d, wir, cad));
|
||||
|
||||
// term events have no spinner label
|
||||
//
|
||||
u3z(egg_u->pin_u.lab);
|
||||
egg_u->pin_u.lab = u3_blip;
|
||||
|
||||
return egg_u;
|
||||
}
|
||||
|
||||
/* _term_io_talk():
|
||||
*/
|
||||
static void
|
||||
_term_io_talk(u3_auto* car_u)
|
||||
{
|
||||
// XX groace hardcoded terminal number
|
||||
//
|
||||
u3_noun wir = u3nt(c3__term, '1', u3_nul);
|
||||
u3_noun cad;
|
||||
|
||||
// send terminal dimensions
|
||||
//
|
||||
{
|
||||
cad = u3nc(c3__blew, u3_term_get_blew(1));
|
||||
_term_ovum_plan(car_u, u3k(wir), cad);
|
||||
}
|
||||
|
||||
// NB, term.c used to also start :dojo
|
||||
//
|
||||
// u3nq(c3__flow, c3__seat, c3__dojo, u3_nul)
|
||||
|
||||
// refresh terminal state
|
||||
//
|
||||
{
|
||||
cad = u3nc(c3__hail, u3_nul);
|
||||
_term_ovum_plan(car_u, wir, cad);
|
||||
}
|
||||
}
|
||||
|
||||
/* _term_io_kick(): apply effects.
|
||||
*/
|
||||
static c3_o
|
||||
_term_io_kick(u3_auto* car_u, u3_noun wir, u3_noun cad)
|
||||
{
|
||||
u3_noun tag, dat, i_wir, t_wir;
|
||||
c3_o ret_o;
|
||||
|
||||
if ( (c3n == u3r_cell(wir, &i_wir, &t_wir))
|
||||
|| (c3n == u3r_cell(cad, &tag, &dat))
|
||||
|| (c3__term != i_wir) )
|
||||
{
|
||||
ret_o = c3n;
|
||||
}
|
||||
else {
|
||||
// eat everything
|
||||
ret_o = c3y;
|
||||
}
|
||||
|
||||
u3z(wir); u3z(cad);
|
||||
return ret_o;
|
||||
}
|
||||
|
||||
/* _term_io_exit(): clean up terminal.
|
||||
*/
|
||||
static void
|
||||
_term_io_exit(u3_auto* car_u)
|
||||
{
|
||||
c3_free(car_u);
|
||||
}
|
||||
|
||||
/* u3_term_io_init(): initialize terminal
|
||||
*/
|
||||
u3_auto*
|
||||
u3_term_io_init(u3_pier* pir_u)
|
||||
{
|
||||
u3_auto* car_u = c3_calloc(sizeof(*car_u));
|
||||
|
||||
car_u->nam_m = c3__term;
|
||||
car_u->liv_o = c3y;
|
||||
car_u->io.talk_f = _term_io_talk;
|
||||
car_u->io.kick_f = _term_io_kick;
|
||||
car_u->io.exit_f = _term_io_exit;
|
||||
|
||||
return car_u;
|
||||
}
|
@ -749,12 +749,16 @@ u3_king_commence()
|
||||
u3C.sign_move_f = _king_sign_move;
|
||||
|
||||
// Ignore SIGPIPE signals.
|
||||
#ifndef U3_OS_mingw
|
||||
{
|
||||
struct sigaction sig_s = {{0}};
|
||||
sigemptyset(&(sig_s.sa_mask));
|
||||
sig_s.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &sig_s, 0);
|
||||
}
|
||||
#else
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
// boot the ivory pill
|
||||
//
|
||||
@ -762,6 +766,7 @@ u3_king_commence()
|
||||
|
||||
// disable core dumps (due to lmdb size)
|
||||
//
|
||||
#ifndef U3_OS_mingw
|
||||
{
|
||||
struct rlimit rlm;
|
||||
|
||||
@ -773,6 +778,7 @@ u3_king_commence()
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// run the loop
|
||||
//
|
||||
|
@ -98,7 +98,7 @@ u3_time_in_ts(struct timespec* tim_ts)
|
||||
return u3_time_in_tv(&tim_tv);
|
||||
}
|
||||
|
||||
#if defined(U3_OS_linux)
|
||||
#if defined(U3_OS_linux) || defined(U3_OS_mingw)
|
||||
/* u3_time_t_in_ts(): urbit time from time_t.
|
||||
*/
|
||||
u3_atom
|
||||
@ -111,7 +111,7 @@ u3_time_t_in_ts(time_t tim)
|
||||
|
||||
return u3_time_in_tv(&tim_tv);
|
||||
}
|
||||
#endif // defined(U3_OS_linux)
|
||||
#endif // defined(U3_OS_linux) || defined(U3_OS_mingw)
|
||||
|
||||
/* u3_time_out_ts(): struct timespec from urbit time.
|
||||
*/
|
||||
|
@ -195,12 +195,16 @@ _cw_serf_commence(c3_i argc, c3_c* argv[])
|
||||
|
||||
// Ignore SIGPIPE signals.
|
||||
//
|
||||
#ifndef U3_OS_mingw
|
||||
{
|
||||
struct sigaction sig_s = {{0}};
|
||||
sigemptyset(&(sig_s.sa_mask));
|
||||
sig_s.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &sig_s, 0);
|
||||
}
|
||||
#else
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
// configure pipe to daemon process
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user