@elixir-playground/git 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/NOTICE.md +15 -0
  2. package/fs/bundles/0.tar +0 -0
  3. package/fs/manifest.json +1 -0
  4. package/git.wasm +0 -0
  5. package/index.d.ts +4 -0
  6. package/index.js +34 -0
  7. package/licenses/git-2.56.0/COPYING +360 -0
  8. package/licenses/git-2.56.0/LGPL-2.1 +511 -0
  9. package/licenses/index.json +51 -0
  10. package/licenses/wasi-compat-playground/LICENSE +18 -0
  11. package/licenses/wasi-libc-2e6fb9d8ee0c/LICENSE +17 -0
  12. package/licenses/wasi-libc-2e6fb9d8ee0c/LICENSE-APACHE +201 -0
  13. package/licenses/wasi-libc-2e6fb9d8ee0c/LICENSE-APACHE-LLVM +220 -0
  14. package/licenses/wasi-libc-2e6fb9d8ee0c/LICENSE-MIT +23 -0
  15. package/licenses/wasi-libc-2e6fb9d8ee0c/cloudlibc-LICENSE +22 -0
  16. package/licenses/wasi-libc-2e6fb9d8ee0c/musl-COPYRIGHT +193 -0
  17. package/licenses/wasi-libc-2e6fb9d8ee0c/musl-fts-COPYING +26 -0
  18. package/licenses/zlib-1.3.2/LICENSE +22 -0
  19. package/package.json +44 -4
  20. package/source/git/README.md +17 -0
  21. package/source/git/git-2.56.0.tar.xz +0 -0
  22. package/source/git/tools/git/build.py +168 -0
  23. package/source/git/tools/git/config.mak +42 -0
  24. package/source/git/tools/git/patches/0001-wasi-spawn.patch +76 -0
  25. package/source/git/tools/git/patches/0002-wasi-async.patch +124 -0
  26. package/source/git/tools/wasi-compat/LICENSE +18 -0
  27. package/source/git/tools/wasi-compat/autoconf.py +158 -0
  28. package/source/git/tools/wasi-compat/config.site +31 -0
  29. package/source/git/tools/wasi-compat/include/grp.h +6 -0
  30. package/source/git/tools/wasi-compat/include/mntent.h +10 -0
  31. package/source/git/tools/wasi-compat/include/netdb.h +7 -0
  32. package/source/git/tools/wasi-compat/include/paths.h +2 -0
  33. package/source/git/tools/wasi-compat/include/pwd.h +5 -0
  34. package/source/git/tools/wasi-compat/include/setjmp.h +17 -0
  35. package/source/git/tools/wasi-compat/include/sys/wait.h +8 -0
  36. package/source/git/tools/wasi-compat/include/syslog.h +7 -0
  37. package/source/git/tools/wasi-compat/include/termios.h +10 -0
  38. package/source/git/tools/wasi-compat/include/wasi-compat.h +38 -0
  39. package/source/git/tools/wasi-compat/include/wasi-posix.h +79 -0
  40. package/source/git/tools/wasi-compat/stubs.c +326 -0
  41. package/source/git/tools/wasi-compat/wrap.c +54 -0
  42. package/source/git/zlib-1.3.2.tar.gz +0 -0
  43. package/README.md +0 -3
@@ -0,0 +1,158 @@
1
+ """A GNU tool (autoconf and gnulib) built to WebAssembly (wasm32-wasip1)
2
+ over tools/wasi-compat/: what tools/sed/build.py and the others like it share
3
+ (docs/tools.md). Each names its release and what to keep:
4
+
5
+ build(HERE, "sed", ("4.10", URL, SHA256), {"sed": "sed/sed"}, ["--disable-acl"])
6
+ # → target/sed/sed.wasm
7
+
8
+ The release tarball by URL and SHA-256, the tool's patches/ applied, its
9
+ own configure --host=wasm32-wasip1 and make in wasi-sdk 33's image (as
10
+ tools/git/build.py's, pinned by digest), -Oz. What WASI lacks is stubs.c's
11
+ (built as git's is, wasi-compat.h forced in), declared by wasi-posix.h,
12
+ which goes at the end of the tool's config.h: gnulib's replacement
13
+ headers want config.h first, and bring their own signals. What configure
14
+ cannot learn when cross-compiling, config.site answers: this directory's
15
+ for stubs.c's functions, then the tool's own.
16
+
17
+ Loaded by path (python3 -I leaves the script's directory off sys.path).
18
+ """
19
+
20
+ import hashlib
21
+ import importlib.util
22
+ import os
23
+ import shutil
24
+ import subprocess
25
+ import tarfile
26
+ import urllib.request
27
+
28
+ # The repository (this file is tools/wasi-compat/autoconf.py).
29
+ ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
30
+ COMPAT = os.path.dirname(os.path.abspath(__file__))
31
+ DOCKER = os.environ.get("DOCKER", "sudo -n docker").split()
32
+ # wasi-sdk 33 (clang 23), as the backend's NIF toolchain and tools/git/build.py.
33
+ IMAGE = "ghcr.io/webassembly/wasi-sdk@sha256:52595085a0ffbaf574d8d678a9aa81305f0b3af81c639291f15bc7713e42848e"
34
+ CC = "/opt/wasi-sdk/bin/clang --target=wasm32-wasip1 --sysroot=/opt/wasi-sdk/share/wasi-sysroot"
35
+ # wasi-libc's emulations (signal, raise, clock, getpid, mmap), as git's.
36
+ EMULATED = ("signal", "process-clocks", "getpid", "mman")
37
+ CFLAGS = "-Oz -I/wasi/include " + " ".join(f"-D_WASI_EMULATED_{e.upper().replace('-', '_')}" for e in EMULATED)
38
+ # wrap.o wraps wasi-libc's fcntl (F_DUPFD by dup) and stat's kin (modes).
39
+ WRAPPED = ("fcntl", "stat", "lstat", "fstat", "fstatat")
40
+ LIBS = ("/wasi/stubs.o /wasi/wrap.o " + " ".join(f"-Wl,--wrap={name}" for name in WRAPPED) + " "
41
+ + " ".join(f"-lwasi-emulated-{e}" for e in EMULATED))
42
+
43
+
44
+ def fetch(source, sha256, path):
45
+ if not os.path.exists(path):
46
+ urllib.request.urlretrieve(source, path + ".part")
47
+ with open(path + ".part", "rb") as f:
48
+ got = hashlib.sha256(f.read()).hexdigest()
49
+ if got != sha256:
50
+ raise SystemExit(f"{source}: sha256 {got}, not {sha256}")
51
+ os.rename(path + ".part", path)
52
+
53
+
54
+ def stamp(here, release, configure):
55
+ """What the build is made from: the image, the release, the options,
56
+ the tool's files and this directory's (not .py files)."""
57
+ hashed = hashlib.sha256("\0".join([IMAGE, release[2], *configure, ""]).encode())
58
+ for top in (here, COMPAT):
59
+ for directory, _, names in sorted(os.walk(top)):
60
+ for name in sorted(names):
61
+ if name.endswith(".py") or name == "__pycache__":
62
+ continue
63
+ path = os.path.join(directory, name)
64
+ with open(path, "rb") as f:
65
+ hashed.update(os.path.relpath(path, ROOT).encode() + b"\0" + f.read())
66
+ return hashed.hexdigest()
67
+
68
+
69
+ def licensed(here, name, release, made):
70
+ """target/NAME/licenses (tools/licenses.py) and, the tool being GPL,
71
+ target/NAME/source: the release, its patches and the build's files."""
72
+ spec = importlib.util.spec_from_file_location("licenses", os.path.join(ROOT, "tools", "licenses.py"))
73
+ licenses = importlib.util.module_from_spec(spec)
74
+ spec.loader.exec_module(licenses)
75
+ out = os.path.join(ROOT, "target", name)
76
+ if licenses.current(out, made):
77
+ return
78
+ version, source, sha256 = release
79
+ archive = os.path.join(out, os.path.basename(source))
80
+ fetch(source, sha256, archive)
81
+ tool = os.path.relpath(here, ROOT)
82
+ sources = {os.path.basename(source): archive, f"{tool}/build.py": os.path.join(here, "build.py"),
83
+ "tools/wasi-compat": COMPAT}
84
+ for extra in ("patches", "config.site"):
85
+ if os.path.exists(os.path.join(here, extra)):
86
+ sources[f"{tool}/{extra}"] = os.path.join(here, extra)
87
+ inventory = licenses.c_tool(out, name, version, "GPL-3.0-or-later", f"https://www.gnu.org/software/{name}/",
88
+ archive, ["COPYING"], sources, f"{tool}/build.py")
89
+ licenses.finish(inventory, out, made)
90
+
91
+
92
+ def build(here, name, release, programs, configure=()):
93
+ """`name`'s `release` (version, URL, SHA-256) built; `programs` maps
94
+ each wasm to keep (target/NAME/KEY.wasm) to what make builds (a path
95
+ in the source tree, its make target too)."""
96
+ out = os.path.join(ROOT, "target", name)
97
+ os.makedirs(out, exist_ok=True)
98
+ built = os.path.join(out, "stamp")
99
+ wasm = {key: os.path.join(out, f"{key}.wasm") for key in programs}
100
+ made = stamp(here, release, configure)
101
+ if all(map(os.path.exists, wasm.values())) and os.path.exists(built):
102
+ with open(built) as f:
103
+ if f.read() == made:
104
+ return licensed(here, name, release, made)
105
+ version, source, sha256 = release
106
+ archive = os.path.join(out, os.path.basename(source))
107
+ fetch(source, sha256, archive)
108
+ src = os.path.join(out, "src")
109
+ shutil.rmtree(src, ignore_errors=True)
110
+ with tarfile.open(archive) as tar:
111
+ tar.extractall(out, filter="data")
112
+ os.rename(os.path.join(out, f"{name}-{version}"), src)
113
+ patches = os.path.join(here, "patches")
114
+ for patch in sorted(os.listdir(patches)) if os.path.isdir(patches) else ():
115
+ subprocess.run(["patch", "-p1", "-s", "-d", src, "-i", os.path.join(patches, patch)], check=True)
116
+ wasi = os.path.join(out, "wasi")
117
+ shutil.rmtree(wasi, ignore_errors=True)
118
+ shutil.copytree(COMPAT, wasi, ignore=shutil.ignore_patterns("*.py", "__pycache__"))
119
+ sites = "/wasi/config.site" + (" /tool/config.site" if os.path.exists(os.path.join(here, "config.site")) else "")
120
+ script = (
121
+ f"{CC} {CFLAGS} -include /wasi/include/wasi-compat.h -c /wasi/stubs.c -o /wasi/stubs.o\n"
122
+ f"{CC} {CFLAGS} -c /wasi/wrap.c -o /wasi/wrap.o\n"
123
+ "cd /src\n"
124
+ f"CONFIG_SITE='{sites}' ./configure --host=wasm32-wasip1 --disable-nls {' '.join(configure)} "
125
+ f"CC='{CC}' CFLAGS='{CFLAGS}' LIBS='{LIBS}' >configure.out 2>&1 "
126
+ "|| { tail -20 configure.out; tail -40 config.log; exit 1; }\n"
127
+ # After config.h, whose #defines gnulib's headers want first.
128
+ # (config.h, or lib/config.h: diffutils'.)
129
+ "header=$(ls config.h lib/config.h 2>/dev/null | head -n 1)\n"
130
+ "echo '#include <wasi-posix.h>' >> ${header:?configure made no config.h}\n"
131
+ # The programs alone (gnulib-tests/ does not build for WASI), after
132
+ # what automake makes first for `all` (gnulib's generated headers).
133
+ "printf 'built-sources: $(BUILT_SOURCES)\\n' > built-sources.mk\n"
134
+ "make -s -j$(nproc) -f Makefile -f built-sources.mk built-sources >/dev/null\n"
135
+ # A recursive tree (grep's, diffutils': lib/, src/) makes gnulib's
136
+ # lib/ (gawk's support/; findutils' gl/lib/, then its own lib/)
137
+ # first, then each program in its directory; a flat one (sed's)
138
+ # each from the top.
139
+ "for lib in gl/lib lib support; do\n"
140
+ " if [ -f $lib/Makefile ]; then make -s -j$(nproc) -C $lib >/dev/null; fi\n"
141
+ "done\n"
142
+ f"for program in {' '.join(programs.values())}; do\n"
143
+ " dir=${program%/*}\n"
144
+ " if [ -f $dir/Makefile ]; then make -s -j$(nproc) -C $dir ${program##*/} >/dev/null\n"
145
+ " else make -s -j$(nproc) $program >/dev/null; fi\n"
146
+ "done\n"
147
+ )
148
+ subprocess.run(DOCKER + [
149
+ "run", "--rm", "--user", f"{os.getuid()}:{os.getgid()}", "-v", f"{src}:/src", "-v", f"{wasi}:/wasi",
150
+ "-v", f"{here}:/tool:ro", IMAGE, "sh", "-ec", script,
151
+ ], check=True)
152
+ for key, path in programs.items():
153
+ shutil.copy(os.path.join(src, path), wasm[key])
154
+ with open(built, "w") as f:
155
+ f.write(made)
156
+ licensed(here, name, release, made)
157
+ for path in wasm.values():
158
+ print(f"{path}: {os.path.getsize(path) / 1e3:.0f} KB")
@@ -0,0 +1,31 @@
1
+ # Answers for a tool's configure (CONFIG_SITE, before the tool's own):
2
+ # what wasi-posix.h declares and stubs.c defines is there and declared.
3
+ # configure's checks see neither header (the build appends it to
4
+ # config.h), so they would take each for missing and have gnulib replace
5
+ # it, or not use it at all. Not fork and exec, which stubs.c has fail:
6
+ # without them a tool starts programs by popen and system (diff3's diff,
7
+ # sdiff's editor, diff --paginate's pr).
8
+ ac_cv_func_fork=no
9
+ ac_cv_func_fork_works=no
10
+ ac_cv_func_vfork=no
11
+ ac_cv_func_vfork_works=no
12
+ for ac_func in getuid geteuid getgid getegid getgroups getppid getpgid getpgrp \
13
+ setsid tcgetpgrp umask chmod fchmod chown fchown dup dup2 pipe kill alarm getdtablesize getpass \
14
+ mkdtemp mkstemp popen pclose system sigaction sigemptyset sigfillset sigaddset sigdelset sigismember \
15
+ sigprocmask tzset setmntent getmntent endmntent hasmntopt; do
16
+ eval "ac_cv_func_$ac_func=yes"
17
+ eval "ac_cv_have_decl_$ac_func=yes"
18
+ done
19
+ # The mount table: mntent.h's (empty), as Linux's getmntent.
20
+ ac_cv_header_mntent_h=yes
21
+ fu_cv_sys_mounted_getmntent1=yes
22
+ # getgroups: no supplementary groups (stubs.c), as gid_t.
23
+ gl_cv_func_getgroups_works=yes
24
+ ac_cv_type_getgroups=gid_t
25
+ # Its sigset_t and struct sigaction (wasi-posix.h's), not wasi-libc's.
26
+ gl_cv_type_sigset_t=yes
27
+ ac_cv_type_sigset_t=yes
28
+ ac_cv_member_struct_sigaction_sa_sigaction=no
29
+ # sys/wait.h's macros are tools/wasi-compat/include's; configure's check also
30
+ # calls wait(), which is not (the host waits for a pid).
31
+ ac_cv_header_sys_wait_h=yes
@@ -0,0 +1,6 @@
1
+ #pragma once
2
+ #include <sys/types.h>
3
+ struct group { char *gr_name; char *gr_passwd; gid_t gr_gid; char **gr_mem; };
4
+ struct group *getgrgid(gid_t);
5
+ struct group *getgrnam(const char *);
6
+ int initgroups(const char *, gid_t);
@@ -0,0 +1,10 @@
1
+ /* The mount table, for gnulib's mountlist (find -fstype): WASI has none
2
+ to list, so it reads as empty (stubs.c: setmntent opens /dev/null). */
3
+ #pragma once
4
+ #include <stdio.h>
5
+ #define MOUNTED "/etc/mtab"
6
+ struct mntent { char *mnt_fsname; char *mnt_dir; char *mnt_type; char *mnt_opts; int mnt_freq; int mnt_passno; };
7
+ FILE *setmntent(const char *, const char *);
8
+ struct mntent *getmntent(FILE *);
9
+ int endmntent(FILE *);
10
+ char *hasmntopt(const struct mntent *, const char *);
@@ -0,0 +1,7 @@
1
+ #pragma once
2
+ #include <sys/socket.h>
3
+ struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list; };
4
+ #define h_addr h_addr_list[0]
5
+ struct hostent *gethostbyname(const char *);
6
+ const char *hstrerror(int);
7
+ extern int h_errno;
@@ -0,0 +1,2 @@
1
+ #pragma once
2
+ #define _PATH_DEFPATH "/usr/bin:/bin"
@@ -0,0 +1,5 @@
1
+ #pragma once
2
+ #include <sys/types.h>
3
+ struct passwd { char *pw_name; char *pw_passwd; uid_t pw_uid; gid_t pw_gid; char *pw_gecos; char *pw_dir; char *pw_shell; };
4
+ struct passwd *getpwuid(uid_t);
5
+ struct passwd *getpwnam(const char *);
@@ -0,0 +1,17 @@
1
+ /* setjmp without the jump: WASI has none without wasm's exception
2
+ handling (wasi-libc's setjmp.h refuses). setjmp returns 0; a longjmp,
3
+ which the tools here take only where WASI never leads them (gawk's
4
+ debugger, diff -r's failing strcoll), ends the program saying so. */
5
+ #pragma once
6
+ #include <stdio.h>
7
+ #include <stdlib.h>
8
+ typedef int jmp_buf[1];
9
+ typedef int sigjmp_buf[1];
10
+ #define setjmp(env) 0
11
+ #define sigsetjmp(env, save) 0
12
+ #define longjmp(env, val) wasi_longjmp()
13
+ #define siglongjmp(env, val) wasi_longjmp()
14
+ static inline _Noreturn void wasi_longjmp(void) {
15
+ fputs("longjmp: not on WASI (no exception handling)\n", stderr);
16
+ exit(70);
17
+ }
@@ -0,0 +1,8 @@
1
+ #pragma once
2
+ #include <sys/types.h>
3
+ #define WNOHANG 1
4
+ #define WIFEXITED(s) (((s) & 0x7f) == 0)
5
+ #define WEXITSTATUS(s) (((s) >> 8) & 0xff)
6
+ #define WIFSIGNALED(s) (((s) & 0x7f) != 0 && ((s) & 0x7f) != 0x7f)
7
+ #define WTERMSIG(s) ((s) & 0x7f)
8
+ pid_t waitpid(pid_t, int *, int);
@@ -0,0 +1,7 @@
1
+ #pragma once
2
+ #define LOG_ERR 3
3
+ #define LOG_INFO 6
4
+ #define LOG_PID 1
5
+ #define LOG_DAEMON (3<<3)
6
+ static inline void openlog(const char *i, int o, int f) { (void)i; (void)o; (void)f; }
7
+ static inline void syslog(int p, const char *f, ...) { (void)p; (void)f; }
@@ -0,0 +1,10 @@
1
+ #pragma once
2
+ typedef unsigned tcflag_t; typedef unsigned char cc_t;
3
+ struct termios { tcflag_t c_iflag, c_oflag, c_cflag, c_lflag; cc_t c_cc[32]; };
4
+ #define ECHO 8
5
+ #define ICANON 2
6
+ #define VMIN 6
7
+ #define VTIME 5
8
+ #define TCSAFLUSH 2
9
+ int tcgetattr(int, struct termios *);
10
+ int tcsetattr(int, int, const struct termios *);
@@ -0,0 +1,38 @@
1
+ /* What git asks of POSIX that WASI preview 1 lacks, forced into each of
2
+ its files (config.mak's -include): wasi-posix.h's declarations, and
3
+ what git wants of stat, timers and sockets beyond them. A tool built
4
+ with autoconf and gnulib takes wasi-posix.h alone, after its config.h
5
+ (gnulib's replacement headers want config.h first). */
6
+ #pragma once
7
+ #include "wasi-posix.h"
8
+ /* stat, lstat and fstat with a mode's permission bits (stubs.c): WASI's
9
+ have the type alone, and git takes a mode of S_IFDIR alone for a sparse
10
+ index's directory, not a directory (a submodule's gitlink). Function-like,
11
+ so that `struct stat` stays itself. */
12
+ struct stat;
13
+ int wasi_stat(const char *, struct stat *);
14
+ int wasi_lstat(const char *, struct stat *);
15
+ int wasi_fstat(int, struct stat *);
16
+ #define stat(path, st) wasi_stat(path, st)
17
+ #define lstat(path, st) wasi_lstat(path, st)
18
+ #define fstat(fd, st) wasi_fstat(fd, st)
19
+ /* The host's coroutines for start_async (run-command.c's WASI branch):
20
+ one runs wasi_run_async(async) on a stack of its own (*stack, for the
21
+ caller to free once it waited for the pid); the async that runs now
22
+ (NULL: git's own); and ending it. */
23
+ pid_t wasi_async_start(void *async, void **stack);
24
+ void *wasi_async_current(void);
25
+ _Noreturn void wasi_async_exit(int code);
26
+
27
+ /* Signals beyond wasi-posix.h's (whose sigset_t signal.h then takes). */
28
+ #include <signal.h>
29
+ #define ITIMER_REAL 0
30
+
31
+ /* Sockets: none (git://, ssh go through the host or not at all). */
32
+ #include <sys/socket.h>
33
+ #define SO_KEEPALIVE 9
34
+ struct servent { char *s_name; char **s_aliases; int s_port; char *s_proto; };
35
+ struct servent *getservbyname(const char *, const char *);
36
+ int socket(int, int, int);
37
+ int connect(int, const struct sockaddr *, socklen_t);
38
+ int setsockopt(int, int, int, const void *, socklen_t);
@@ -0,0 +1,79 @@
1
+ /* What a C tool asks of POSIX that WASI preview 1 lacks: declarations of
2
+ what stubs.c defines (wasi-libc declares some of them, defines none).
3
+ Processes are the host's (wasi_spawn and the `processes` imports);
4
+ users, modes and terminals answer as one user's would. Declarations
5
+ only, so that a tool's own portability layer (gnulib) keeps its
6
+ types: an autoconf build appends `#include <wasi-posix.h>` to its
7
+ config.h, git's wasi-compat.h includes it. */
8
+ #pragma once
9
+ #include <stdio.h>
10
+ #include <sys/types.h>
11
+ pid_t fork(void);
12
+ int execv(const char *, char *const []);
13
+ int execvp(const char *, char *const []);
14
+ int execve(const char *, char *const [], char *const []);
15
+ int execl(const char *, const char *, ...);
16
+ int execlp(const char *, const char *, ...);
17
+ uid_t getuid(void); uid_t geteuid(void); gid_t getgid(void); gid_t getegid(void);
18
+ int getgroups(int, gid_t []);
19
+ pid_t getppid(void);
20
+ pid_t getpgid(pid_t);
21
+ pid_t getpgrp(void);
22
+ pid_t setsid(void);
23
+ pid_t tcgetpgrp(int);
24
+ mode_t umask(mode_t);
25
+ int chmod(const char *, mode_t);
26
+ int fchmod(int, mode_t);
27
+ int chown(const char *, uid_t, gid_t);
28
+ int fchown(int, uid_t, gid_t);
29
+ int dup(int); int dup2(int, int);
30
+ int pipe(int [2]);
31
+ int kill(pid_t, int);
32
+ unsigned alarm(unsigned);
33
+ int getdtablesize(void);
34
+ char *getpass(const char *);
35
+ char *mkdtemp(char *);
36
+ int mkstemp(char *);
37
+ /* The host's spawn: argv[0] found by name as the shell finds it, in `dir`
38
+ (NULL: here), its standard streams our descriptors in, out and err; its
39
+ pid, or -1 (errno ENOENT: no such program). */
40
+ pid_t wasi_spawn(const char **argv, char **env, const char *dir, int in, int out, int err);
41
+ /* sh -c COMMAND (brush, a process of the host's) over wasi_spawn. */
42
+ FILE *popen(const char *, const char *);
43
+ int pclose(FILE *);
44
+ int system(const char *);
45
+
46
+ /* Signals: wasi-libc emulates signal() and raise() (-D_WASI_EMULATED_SIGNAL),
47
+ and its sigset_t is a placeholder of one byte. Sets of 64 signals,
48
+ masks kept and never applied (no signal arrives but raise()'s and the
49
+ host's kill, which ends a process), sigaction over signal() (stubs.c).
50
+ As POSIX's, gnulib has no blocking of its own to emulate (its emulation
51
+ wants NSIG <= 32; wasi-libc's is 65). */
52
+ #include <__typedef_sigset_t.h>
53
+ typedef unsigned long long wasi_sigset_t;
54
+ #define sigset_t wasi_sigset_t
55
+ #define SIG_BLOCK 0
56
+ #define SIG_UNBLOCK 1
57
+ #define SIG_SETMASK 2
58
+ #define SA_RESTART 0x10000000
59
+ struct sigaction { void (*sa_handler)(int); sigset_t sa_mask; int sa_flags; };
60
+ int sigaction(int, const struct sigaction *, struct sigaction *);
61
+ int sigemptyset(sigset_t *);
62
+ int sigfillset(sigset_t *);
63
+ int sigaddset(sigset_t *, int);
64
+ int sigdelset(sigset_t *, int);
65
+ int sigismember(const sigset_t *, int);
66
+ int sigprocmask(int, const sigset_t *, sigset_t *);
67
+
68
+ /* No time zones (WASI has no tables): UTC, and tzset does nothing. */
69
+ void tzset(void);
70
+
71
+ /* wasi-libc has an opendirat(fd, path) of its own; gnulib's (fts, for
72
+ grep -r and find) takes four arguments, so is gnulib's by another name
73
+ from here on. */
74
+ #include <dirent.h>
75
+ #define opendirat gnulib_opendirat
76
+
77
+ /* wasi-libc has qsort_r (GNU's signature) and declares it only within its
78
+ `#ifdef` for wait, which WASI lacks. */
79
+ void qsort_r(void *, size_t, size_t, int (*)(const void *, const void *, void *), void *);