mirror of
				https://github.com/jart/cosmopolitan.git
				synced 2025-10-25 18:50:57 +00:00 
			
		
		
		
	Delete LIBC_CALLS_HEFTY
- fork() no longer requires malloc() - readdir() moved to LIBC_STDIO - Custom APIs moved to LIBC_X
This commit is contained in:
		
							parent
							
								
									c843243322
								
							
						
					
					
						commit
						23a14b537c
					
				
					 44 changed files with 95 additions and 168 deletions
				
			
		
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -116,7 +116,6 @@ include libc/zipos/zipos.mk			# │ | |||
| include third_party/gdtoa/gdtoa.mk		# │
 | ||||
| include libc/time/time.mk			# │
 | ||||
| include libc/alg/alg.mk				# │
 | ||||
| include libc/calls/hefty/hefty.mk		# │
 | ||||
| include libc/stdio/stdio.mk			# │
 | ||||
| include third_party/f2c/f2c.mk			# │
 | ||||
| include third_party/blas/blas.mk		# │
 | ||||
|  | @ -252,7 +251,6 @@ COSMOPOLITAN_OBJECTS =		\ | |||
| 	APE_LIB			\
 | ||||
| 	THIRD_PARTY_MUSL	\
 | ||||
| 	LIBC_STDIO		\
 | ||||
| 	LIBC_CALLS_HEFTY	\
 | ||||
| 	THIRD_PARTY_REGEX	\
 | ||||
| 	LIBC_ALG		\
 | ||||
| 	LIBC_MEM		\
 | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ | |||
| ╚─────────────────────────────────────────────────────────────────*/ | ||||
| #endif | ||||
| #include "libc/calls/calls.h" | ||||
| #include "libc/calls/hefty/copyfile.h" | ||||
| #include "libc/calls/copyfile.h" | ||||
| #include "libc/errno.h" | ||||
| #include "libc/fmt/conv.h" | ||||
| #include "libc/fmt/fmt.h" | ||||
|  |  | |||
|  | @ -44,7 +44,6 @@ EXAMPLES_DIRECTDEPS =						\ | |||
| 	LIBC_ALG						\
 | ||||
| 	LIBC_BITS						\
 | ||||
| 	LIBC_CALLS						\
 | ||||
| 	LIBC_CALLS_HEFTY					\
 | ||||
| 	LIBC_FMT						\
 | ||||
| 	LIBC_INTRIN						\
 | ||||
| 	LIBC_LOG						\
 | ||||
|  |  | |||
|  | @ -154,7 +154,6 @@ static bool resized_; | |||
| static size_t vtsize_; | ||||
| static bool artifacts_; | ||||
| static long tyn_, txn_; | ||||
| static const char* ffplay_; | ||||
| static struct Frame vf_[2]; | ||||
| static struct Audio audio_; | ||||
| static const char* inputfn_; | ||||
|  | @ -1685,6 +1684,7 @@ int PlayGame(const char* romfile, const char* opt_tasfile) { | |||
|   FILE* fp; | ||||
|   int devnull; | ||||
|   int pipefds[2]; | ||||
|   const char* ffplay; | ||||
|   inputfn_ = opt_tasfile; | ||||
| 
 | ||||
|   if (!(fp = fopen(romfile, "rb"))) { | ||||
|  | @ -1701,7 +1701,7 @@ int PlayGame(const char* romfile, const char* opt_tasfile) { | |||
| 
 | ||||
|   // open speaker
 | ||||
|   // todo: this needs plenty of work
 | ||||
|   if ((ffplay_ = commandvenv("FFPLAY", "ffplay"))) { | ||||
|   if ((ffplay = commandvenv("FFPLAY", "ffplay"))) { | ||||
|     devnull = open("/dev/null", O_WRONLY | O_CLOEXEC); | ||||
|     pipe2(pipefds, O_CLOEXEC); | ||||
|     if (!(playpid_ = vfork())) { | ||||
|  | @ -1713,7 +1713,7 @@ int PlayGame(const char* romfile, const char* opt_tasfile) { | |||
|       dup2(pipefds[0], 0); | ||||
|       dup2(devnull, 1); | ||||
|       dup2(devnull, 2); | ||||
|       execv(ffplay_, (char* const*)args); | ||||
|       execv(ffplay, (char* const*)args); | ||||
|       abort(); | ||||
|     } | ||||
|     close(pipefds[0]); | ||||
|  |  | |||
|  | @ -94,6 +94,4 @@ LIBC_CALLS_OBJS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_OBJS)) | |||
| LIBC_CALLS_TESTS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_TESTS)) | ||||
| 
 | ||||
| .PHONY: o/$(MODE)/libc/calls | ||||
| o/$(MODE)/libc/calls:					\ | ||||
| 		o/$(MODE)/libc/calls/hefty		\
 | ||||
| 		$(LIBC_CALLS_CHECKS) | ||||
| o/$(MODE)/libc/calls: $(LIBC_CALLS_CHECKS) | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ | |||
| │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │ | ||||
| │ PERFORMANCE OF THIS SOFTWARE.                                                │ | ||||
| ╚─────────────────────────────────────────────────────────────────────────────*/ | ||||
| #include "libc/calls/hefty/copyfile.h" | ||||
| #include "libc/calls/copyfile.h" | ||||
| #include "libc/calls/internal.h" | ||||
| #include "libc/calls/struct/stat.h" | ||||
| #include "libc/dce.h" | ||||
|  | @ -1,5 +1,5 @@ | |||
| #ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_COPYFILE_H_ | ||||
| #define COSMOPOLITAN_LIBC_CALLS_HEFTY_COPYFILE_H_ | ||||
| #ifndef COSMOPOLITAN_LIBC_CALLS_COPYFILE_H_ | ||||
| #define COSMOPOLITAN_LIBC_CALLS_COPYFILE_H_ | ||||
| 
 | ||||
| #define COPYFILE_NOCLOBBER           1 | ||||
| #define COPYFILE_PRESERVE_OWNER      2 | ||||
|  | @ -12,4 +12,4 @@ int copyfile(const char *, const char *, int) paramsnonnull(); | |||
| 
 | ||||
| COSMOPOLITAN_C_END_ | ||||
| #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ | ||||
| #endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_COPYFILE_H_ */ | ||||
| #endif /* COSMOPOLITAN_LIBC_CALLS_COPYFILE_H_ */ | ||||
|  | @ -47,7 +47,7 @@ textwindows int execve$nt(const char *program, char *const argv[], | |||
|       close(i); | ||||
|     } | ||||
|   } | ||||
|   rc = ntspawn(program, argv, envp, NULL, NULL, true, 0, NULL, &startinfo, | ||||
|   rc = ntspawn(program, argv, envp, NULL, NULL, NULL, true, 0, NULL, &startinfo, | ||||
|                &procinfo); | ||||
|   if (rc == -1) return -1; | ||||
|   CloseHandle(procinfo.hThread); | ||||
|  |  | |||
|  | @ -16,10 +16,7 @@ | |||
| │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │ | ||||
| │ PERFORMANCE OF THIS SOFTWARE.                                                │ | ||||
| ╚─────────────────────────────────────────────────────────────────────────────*/ | ||||
| #include "libc/bits/bits.h" | ||||
| #include "libc/bits/safemacros.h" | ||||
| #include "libc/runtime/runtime.h" | ||||
| #include "libc/str/str.h" | ||||
| 
 | ||||
| /**
 | ||||
|  * Returns value of environment variable, or NULL if not found. | ||||
|  |  | |||
|  | @ -1,72 +0,0 @@ | |||
| #-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
 | ||||
| #───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
 | ||||
| #
 | ||||
| # SYNOPSIS
 | ||||
| #
 | ||||
| #   Cosmopolitan System Call Compatibility Layer
 | ||||
| #
 | ||||
| # DESCRIPTION
 | ||||
| #
 | ||||
| #   This subpackage exports functions traditionally understood as system
 | ||||
| #   calls that Cosmopolitan needs to wrap in a nontrivial way, requiring
 | ||||
| #   things like dynamic memory allocation.
 | ||||
| 
 | ||||
| PKGS += LIBC_CALLS_HEFTY | ||||
| 
 | ||||
| LIBC_CALLS_HEFTY_ARTIFACTS += LIBC_CALLS_HEFTY_A | ||||
| LIBC_CALLS_HEFTY = $(LIBC_CALLS_HEFTY_A_DEPS) $(LIBC_CALLS_HEFTY_A) | ||||
| LIBC_CALLS_HEFTY_A = o/$(MODE)/libc/calls/hefty/hefty.a | ||||
| LIBC_CALLS_HEFTY_A_FILES := $(wildcard libc/calls/hefty/*) | ||||
| LIBC_CALLS_HEFTY_A_HDRS = $(filter %.h,$(LIBC_CALLS_HEFTY_A_FILES)) | ||||
| LIBC_CALLS_HEFTY_A_SRCS_S = $(filter %.S,$(LIBC_CALLS_HEFTY_A_FILES)) | ||||
| LIBC_CALLS_HEFTY_A_SRCS_C = $(filter %.c,$(LIBC_CALLS_HEFTY_A_FILES)) | ||||
| 
 | ||||
| LIBC_CALLS_HEFTY_A_SRCS =				\
 | ||||
| 	$(LIBC_CALLS_HEFTY_A_SRCS_S)			\
 | ||||
| 	$(LIBC_CALLS_HEFTY_A_SRCS_C) | ||||
| 
 | ||||
| LIBC_CALLS_HEFTY_A_OBJS =				\
 | ||||
| 	$(LIBC_CALLS_HEFTY_A_SRCS_S:%.S=o/$(MODE)/%.o)	\
 | ||||
| 	$(LIBC_CALLS_HEFTY_A_SRCS_C:%.c=o/$(MODE)/%.o) | ||||
| 
 | ||||
| LIBC_CALLS_HEFTY_A_CHECKS =				\
 | ||||
| 	$(LIBC_CALLS_HEFTY_A).pkg			\
 | ||||
| 	$(LIBC_CALLS_HEFTY_A_HDRS:%=o/$(MODE)/%.ok) | ||||
| 
 | ||||
| LIBC_CALLS_HEFTY_A_DIRECTDEPS =				\
 | ||||
| 	LIBC_ALG					\
 | ||||
| 	LIBC_CALLS					\
 | ||||
| 	LIBC_FMT					\
 | ||||
| 	LIBC_INTRIN					\
 | ||||
| 	LIBC_MEM					\
 | ||||
| 	LIBC_NEXGEN32E					\
 | ||||
| 	LIBC_NT_KERNEL32				\
 | ||||
| 	LIBC_RUNTIME					\
 | ||||
| 	LIBC_STR					\
 | ||||
| 	LIBC_STUBS					\
 | ||||
| 	LIBC_SYSV					\
 | ||||
| 	LIBC_SYSV_CALLS | ||||
| 
 | ||||
| LIBC_CALLS_HEFTY_A_DEPS :=				\
 | ||||
| 	$(call uniq,$(foreach x,$(LIBC_CALLS_HEFTY_A_DIRECTDEPS),$($(x)))) | ||||
| 
 | ||||
| $(LIBC_CALLS_HEFTY_A):					\ | ||||
| 		libc/calls/hefty/			\
 | ||||
| 		$(LIBC_CALLS_HEFTY_A).pkg		\
 | ||||
| 		$(LIBC_CALLS_HEFTY_A_OBJS) | ||||
| 
 | ||||
| $(LIBC_CALLS_HEFTY_A).pkg:				\ | ||||
| 		$(LIBC_CALLS_HEFTY_A_OBJS)		\
 | ||||
| 		$(foreach x,$(LIBC_CALLS_HEFTY_A_DIRECTDEPS),$($(x)_A).pkg) | ||||
| 
 | ||||
| LIBC_CALLS_HEFTY_LIBS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x))) | ||||
| LIBC_CALLS_HEFTY_SRCS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_SRCS)) | ||||
| LIBC_CALLS_HEFTY_HDRS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_HDRS)) | ||||
| LIBC_CALLS_HEFTY_BINS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_BINS)) | ||||
| LIBC_CALLS_HEFTY_CHECKS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_CHECKS)) | ||||
| LIBC_CALLS_HEFTY_OBJS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_OBJS)) | ||||
| LIBC_CALLS_HEFTY_TESTS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_TESTS)) | ||||
| $(LIBC_CALLS_HEFTY_OBJS): $(BUILD_FILES) libc/calls/hefty/hefty.mk | ||||
| 
 | ||||
| .PHONY: o/$(MODE)/libc/calls/hefty | ||||
| o/$(MODE)/libc/calls/hefty: $(LIBC_CALLS_HEFTY_CHECKS) | ||||
|  | @ -25,6 +25,7 @@ | |||
| 
 | ||||
| /**
 | ||||
|  * Controls settings on device. | ||||
|  * @vforksafe | ||||
|  */ | ||||
| int(ioctl)(int fd, uint64_t request, void *memory) { | ||||
|   __IOCTL_DISPATCH(EQUAL, fd, request, memory); | ||||
|  |  | |||
|  | @ -51,18 +51,23 @@ static void SortStrings(char **a, size_t n) { | |||
|  * | ||||
|  * This is designed to meet the requirements of CreateProcess(). | ||||
|  * | ||||
|  * @param envvars receives sorted double-NUL terminated string list | ||||
|  * @param envp is an a NULL-terminated array of UTF-8 strings | ||||
|  * @return freshly allocated lpEnvironment or NULL w/ errno | ||||
|  * @param extravar is a VAR=val string we consider part of envp or NULL | ||||
|  * @return 0 on success, or -1 w/ errno | ||||
|  * @error E2BIG if total number of shorts exceeded ARG_MAX (0x8000) | ||||
|  */ | ||||
| textwindows int mkntenvblock(char16_t envvars[ARG_MAX], char *const envp[]) { | ||||
| textwindows int mkntenvblock(char16_t envvars[ARG_MAX], char *const envp[], | ||||
|                              const char *extravar) { | ||||
|   axdx_t rc; | ||||
|   uint64_t w; | ||||
|   char **vars; | ||||
|   wint_t x, y; | ||||
|   size_t i, j, k, n, m; | ||||
|   for (n = 0; envp[n];) n++; | ||||
|   vars = alloca(n * sizeof(char *)); | ||||
|   vars = alloca((n + 1) * sizeof(char *)); | ||||
|   memcpy(vars, envp, n * sizeof(char *)); | ||||
|   if (extravar) vars[n++] = extravar; | ||||
|   SortStrings(vars, n); | ||||
|   for (k = i = 0; i < n; ++i) { | ||||
|     j = 0; | ||||
|  |  | |||
|  | @ -48,6 +48,7 @@ struct SpawnBlock { | |||
|  *     don't need to be passed in sorted order; however, this function | ||||
|  *     goes faster the closer they are to sorted | ||||
|  * @param envp[m-1] is NULL | ||||
|  * @param extravar is added to envp to avoid setenv() in caller | ||||
|  * @param bInheritHandles means handles already marked inheritable will | ||||
|  *     be inherited; which, assuming the System V wrapper functions are | ||||
|  *     being used, should mean (1) all files and sockets that weren't | ||||
|  | @ -59,7 +60,7 @@ struct SpawnBlock { | |||
|  */ | ||||
| textwindows int ntspawn( | ||||
|     const char *prog, char *const argv[], char *const envp[], | ||||
|     struct NtSecurityAttributes *opt_lpProcessAttributes, | ||||
|     const char *extravar, struct NtSecurityAttributes *opt_lpProcessAttributes, | ||||
|     struct NtSecurityAttributes *opt_lpThreadAttributes, bool32 bInheritHandles, | ||||
|     uint32_t dwCreationFlags, const char16_t *opt_lpCurrentDirectory, | ||||
|     const struct NtStartupInfo *lpStartupInfo, | ||||
|  | @ -81,7 +82,7 @@ textwindows int ntspawn( | |||
|            MapViewOfFileExNuma(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0, | ||||
|                                blocksize, NULL, kNtNumaNoPreferredNode))) { | ||||
|     if (mkntcmdline(block->cmdline, prog, argv) != -1 && | ||||
|         mkntenvblock(block->envvars, envp) != -1) { | ||||
|         mkntenvblock(block->envvars, envp, extravar) != -1) { | ||||
|       if (CreateProcess(NULL, block->cmdline, opt_lpProcessAttributes, | ||||
|                         opt_lpThreadAttributes, bInheritHandles, | ||||
|                         dwCreationFlags | kNtCreateUnicodeEnvironment, | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| #ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_ | ||||
| #define COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_ | ||||
| #ifndef COSMOPOLITAN_LIBC_CALLS_NTSPAWN_H_ | ||||
| #define COSMOPOLITAN_LIBC_CALLS_NTSPAWN_H_ | ||||
| #include "libc/nt/struct/processinformation.h" | ||||
| #include "libc/nt/struct/securityattributes.h" | ||||
| #include "libc/nt/struct/startupinfo.h" | ||||
|  | @ -7,12 +7,12 @@ | |||
| COSMOPOLITAN_C_START_ | ||||
| 
 | ||||
| int mkntcmdline(char16_t[ARG_MAX], const char *, char *const[]) hidden; | ||||
| int mkntenvblock(char16_t[ARG_MAX], char *const[]) hidden; | ||||
| int ntspawn(const char *, char *const[], char *const[], | ||||
| int mkntenvblock(char16_t[ARG_MAX], char *const[], const char *) hidden; | ||||
| int ntspawn(const char *, char *const[], char *const[], const char *, | ||||
|             struct NtSecurityAttributes *, struct NtSecurityAttributes *, | ||||
|             bool32, uint32_t, const char16_t *, const struct NtStartupInfo *, | ||||
|             struct NtProcessInformation *) hidden; | ||||
| 
 | ||||
| COSMOPOLITAN_C_END_ | ||||
| #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ | ||||
| #endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_ */ | ||||
| #endif /* COSMOPOLITAN_LIBC_CALLS_NTSPAWN_H_ */ | ||||
|  |  | |||
|  | @ -37,6 +37,7 @@ | |||
|  *     ignored if O_CREAT or O_TMPFILE weren't passed | ||||
|  * @return number needing close(), or -1 w/ errno | ||||
|  * @asyncsignalsafe | ||||
|  * @vforksafe | ||||
|  */ | ||||
| nodiscard int openat(int dirfd, const char *file, int flags, ...) { | ||||
|   va_list va; | ||||
|  | @ -47,11 +48,9 @@ nodiscard int openat(int dirfd, const char *file, int flags, ...) { | |||
|   va_end(va); | ||||
|   if (!file) return efault(); | ||||
|   if (weaken(__zipos_open) && weaken(__zipos_parseuri)(file, &zipname) != -1) { | ||||
|     if (dirfd == AT_FDCWD) { | ||||
|     if (__vforked) return einval(); | ||||
|     if (dirfd != AT_FDCWD) return einval(); | ||||
|     return weaken(__zipos_open)(&zipname, flags, mode); | ||||
|     } else { | ||||
|       return eopnotsupp(); /* TODO */ | ||||
|     } | ||||
|   } else if (!IsWindows()) { | ||||
|     return openat$sysv(dirfd, file, flags, mode); | ||||
|   } else { | ||||
|  |  | |||
|  | @ -118,6 +118,7 @@ static void sigaction$native2cosmo(union metasigaction *sa) { | |||
|  * | ||||
|  * @see xsigaction() for a much better api | ||||
|  * @asyncsignalsafe | ||||
|  * @vforksafe | ||||
|  */ | ||||
| int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) { | ||||
|   _Static_assert(sizeof(struct sigaction) > sizeof(struct sigaction$linux) && | ||||
|  |  | |||
|  | @ -48,7 +48,6 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) { | |||
|   struct Garbages *garbage; | ||||
|   sigset_t chldmask, savemask; | ||||
|   const struct StackFrame *frame; | ||||
|   struct sigaction ignore, saveint, savequit; | ||||
|   const char *debugbin, *p1, *p2, *p3, *addr2line; | ||||
|   char buf[kBacktraceBufSize], *argv[kBacktraceMaxFrames]; | ||||
|   if (IsOpenbsd()) return -1; | ||||
|  | @ -77,18 +76,11 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) { | |||
|     j += uint64toarray_radix16(addr - 1, buf + j) + 1; | ||||
|   } | ||||
|   argv[i++] = NULL; | ||||
|   ignore.sa_flags = 0; | ||||
|   ignore.sa_handler = SIG_IGN; | ||||
|   sigemptyset(&ignore.sa_mask); | ||||
|   sigaction(SIGINT, &ignore, &saveint); | ||||
|   sigaction(SIGQUIT, &ignore, &savequit); | ||||
|   sigemptyset(&chldmask); | ||||
|   sigaddset(&chldmask, SIGCHLD); | ||||
|   sigprocmask(SIG_BLOCK, &chldmask, &savemask); | ||||
|   pipe(pipefds); | ||||
|   if (!(pid = vfork())) { | ||||
|     sigaction(SIGINT, &saveint, NULL); | ||||
|     sigaction(SIGQUIT, &savequit, NULL); | ||||
|     sigprocmask(SIG_SETMASK, &savemask, NULL); | ||||
|     dup2(pipefds[1], 1); | ||||
|     close(pipefds[0]); | ||||
|  | @ -124,8 +116,6 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) { | |||
|     if (errno == EINTR) continue; | ||||
|     return -1; | ||||
|   } | ||||
|   sigaction(SIGINT, &saveint, NULL); | ||||
|   sigaction(SIGQUIT, &savequit, NULL); | ||||
|   sigprocmask(SIG_SETMASK, &savemask, NULL); | ||||
|   if (WIFEXITED(ws) && !WEXITSTATUS(ws)) { | ||||
|     return 0; | ||||
|  |  | |||
|  | @ -25,19 +25,30 @@ | |||
| 
 | ||||
| /**
 | ||||
|  * Finds full executable path in overridable way. | ||||
|  * | ||||
|  * This is a higher level version of the commandv() function. Programs | ||||
|  * that spawn subprocesses can use this function to determine the path | ||||
|  * at startup. | ||||
|  * | ||||
|  * @param var is environment variable which may be used to override | ||||
|  *     PATH search, and it can force a NULL result if it's empty | ||||
|  * @param cmd is name of program, which is returned asap if it's an | ||||
|  *     absolute path | ||||
|  * @return pointer to exe path string, or NULL if it couldn't be found | ||||
|  *     or the environment variable was empty; noting that the caller | ||||
|  *     should copy this string before saving it | ||||
|  */ | ||||
| nodiscard char *commandvenv(const char *var, const char *cmd) { | ||||
| const char *commandvenv(const char *var, const char *cmd) { | ||||
|   const char *exepath; | ||||
|   char pathbuf[PATH_MAX]; | ||||
|   static char pathbuf[PATH_MAX]; | ||||
|   if (*cmd == '/' || *cmd == '\\') return cmd; | ||||
|   if ((exepath = getenv(var))) { | ||||
|     if (!isempty(exepath) && access(exepath, X_OK) != -1) { | ||||
|       return strdup(exepath); | ||||
|     if (isempty(exepath)) return NULL; | ||||
|     if (access(exepath, X_OK) != -1) { | ||||
|       return exepath; | ||||
|     } else { | ||||
|       return NULL; | ||||
|     } | ||||
|   } else if ((exepath = commandv(cmd, pathbuf))) { | ||||
|     return strdup(exepath); | ||||
|   } else { | ||||
|     return NULL; | ||||
|   } | ||||
|   return commandv(cmd, pathbuf); | ||||
| } | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ void memsummary(int);                  /* light version of same thing */ | |||
| uint16_t getttycols(uint16_t); | ||||
| int getttysize(int, struct winsize *) paramsnonnull(); | ||||
| bool IsTerminalInarticulate(void) nosideeffect; | ||||
| char *commandvenv(const char *, const char *) nodiscard; | ||||
| const char *commandvenv(const char *, const char *); | ||||
| const char *GetAddr2linePath(void); | ||||
| const char *GetGdbPath(void); | ||||
| 
 | ||||
|  |  | |||
|  | @ -28,7 +28,6 @@ LIBC_LOG_A_CHECKS =					\ | |||
| LIBC_LOG_A_DIRECTDEPS =					\
 | ||||
| 	LIBC_ALG					\
 | ||||
| 	LIBC_CALLS					\
 | ||||
| 	LIBC_CALLS_HEFTY				\
 | ||||
| 	LIBC_ELF					\
 | ||||
| 	LIBC_FMT					\
 | ||||
| 	LIBC_INTRIN					\
 | ||||
|  |  | |||
|  | @ -46,13 +46,14 @@ | |||
| #include "libc/sysv/consts/sig.h" | ||||
| #include "libc/sysv/errfuns.h" | ||||
| 
 | ||||
| static textwindows int64_t ParseInt(char16_t **p) { | ||||
|   uint64_t x = 0; | ||||
|   while ('0' <= **p && **p <= '9') { | ||||
|     x *= 10; | ||||
|     x += *(*p)++ - '0'; | ||||
| static textwindows char16_t *ParseInt(char16_t *p, int64_t *x) { | ||||
|   *x = 0; | ||||
|   while (*p == ' ') p++; | ||||
|   while ('0' <= *p && *p <= '9') { | ||||
|     *x *= 10; | ||||
|     *x += *p++ - '0'; | ||||
|   } | ||||
|   return x; | ||||
|   return p; | ||||
| } | ||||
| 
 | ||||
| static noinline textwindows void ForkIo(int64_t h, void *buf, size_t n, | ||||
|  | @ -74,32 +75,28 @@ static noinline textwindows void ReadAll(int64_t h, void *buf, size_t n) { | |||
| } | ||||
| 
 | ||||
| textwindows void WinMainForked(void) { | ||||
|   int64_t h; | ||||
|   void *addr; | ||||
|   jmp_buf jb; | ||||
|   char16_t *p; | ||||
|   uint64_t size; | ||||
|   uint32_t i, varlen; | ||||
|   struct DirectMap dm; | ||||
|   int64_t reader, writer; | ||||
|   char16_t var[21 + 1 + 21 + 1]; | ||||
|   varlen = GetEnvironmentVariable(u"_FORK", var, ARRAYLEN(var)); | ||||
|   if (!varlen) return; | ||||
|   if (varlen >= ARRAYLEN(var)) ExitProcess(123); | ||||
|   SetEnvironmentVariable(u"_FORK", NULL); | ||||
|   if (!varlen || varlen >= ARRAYLEN(var)) return; | ||||
|   p = var; | ||||
|   h = ParseInt(&p); | ||||
|   if (*p++ == ' ') CloseHandle(ParseInt(&p)); | ||||
|   ReadAll(h, jb, sizeof(jb)); | ||||
|   ReadAll(h, &_mmi.i, sizeof(_mmi.i)); | ||||
|   ParseInt(ParseInt(var, &reader), &writer); | ||||
|   ReadAll(reader, jb, sizeof(jb)); | ||||
|   ReadAll(reader, &_mmi.i, sizeof(_mmi.i)); | ||||
|   for (i = 0; i < _mmi.i; ++i) { | ||||
|     ReadAll(h, &_mmi.p[i], sizeof(_mmi.p[i])); | ||||
|     ReadAll(reader, &_mmi.p[i], sizeof(_mmi.p[i])); | ||||
|     addr = (void *)((uint64_t)_mmi.p[i].x << 16); | ||||
|     size = ((uint64_t)(_mmi.p[i].y - _mmi.p[i].x) << 16) + FRAMESIZE; | ||||
|     if (_mmi.p[i].flags & MAP_PRIVATE) { | ||||
|       CloseHandle(_mmi.p[i].h); | ||||
|       _mmi.p[i].h = | ||||
|           __mmap$nt(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC, -1, 0) | ||||
|               .maphandle; | ||||
|       ReadAll(h, addr, size); | ||||
|       _mmi.p[i].h = __mmap$nt(addr, size, _mmi.p[i].prot, -1, 0).maphandle; | ||||
|       ReadAll(reader, addr, size); | ||||
|     } else { | ||||
|       MapViewOfFileExNuma( | ||||
|           _mmi.p[i].h, | ||||
|  | @ -109,9 +106,9 @@ textwindows void WinMainForked(void) { | |||
|           0, 0, size, addr, kNtNumaNoPreferredNode); | ||||
|     } | ||||
|   } | ||||
|   ReadAll(h, _edata, _end - _edata); | ||||
|   CloseHandle(h); | ||||
|   unsetenv("_FORK"); | ||||
|   ReadAll(reader, _edata, _end - _edata); | ||||
|   CloseHandle(reader); | ||||
|   CloseHandle(writer); | ||||
|   if (weaken(__wincrash$nt)) { | ||||
|     AddVectoredExceptionHandler(1, (void *)weaken(__wincrash$nt)); | ||||
|   } | ||||
|  | @ -123,17 +120,16 @@ textwindows int fork$nt(void) { | |||
|   int i, rc, pid; | ||||
|   char exe[PATH_MAX]; | ||||
|   int64_t reader, writer; | ||||
|   char *p, buf[21 + 1 + 21 + 1]; | ||||
|   char *p, forkvar[6 + 21 + 1 + 21 + 1]; | ||||
|   struct NtStartupInfo startinfo; | ||||
|   struct NtProcessInformation procinfo; | ||||
|   if ((pid = __getemptyfd()) == -1) return -1; | ||||
|   if (!setjmp(jb)) { | ||||
|     if (CreatePipe(&reader, &writer, &kNtIsInheritable, 0)) { | ||||
|       p = buf; | ||||
|       p = stpcpy(forkvar, "_FORK="); | ||||
|       p += uint64toarray_radix10(reader, p); | ||||
|       *p++ = ' '; | ||||
|       p += uint64toarray_radix10(writer, p); | ||||
|       setenv("_FORK", buf, true); | ||||
|       memset(&startinfo, 0, sizeof(startinfo)); | ||||
|       startinfo.cb = sizeof(struct NtStartupInfo); | ||||
|       startinfo.dwFlags = kNtStartfUsestdhandles; | ||||
|  | @ -141,8 +137,8 @@ textwindows int fork$nt(void) { | |||
|       startinfo.hStdOutput = g_fds.p[1].handle; | ||||
|       startinfo.hStdError = g_fds.p[2].handle; | ||||
|       GetModuleFileNameA(0, exe, ARRAYLEN(exe)); | ||||
|       if (ntspawn(exe, g_argv, environ, &kNtIsInheritable, NULL, true, 0, NULL, | ||||
|                   &startinfo, &procinfo) != -1) { | ||||
|       if (ntspawn(exe, g_argv, environ, forkvar, &kNtIsInheritable, NULL, true, | ||||
|                   0, NULL, &startinfo, &procinfo) != -1) { | ||||
|         CloseHandle(reader); | ||||
|         CloseHandle(procinfo.hThread); | ||||
|         if (weaken(__sighandrvas) && | ||||
|  | @ -167,7 +163,6 @@ textwindows int fork$nt(void) { | |||
|       } else { | ||||
|         rc = -1; | ||||
|       } | ||||
|       unsetenv("_FORK"); | ||||
|       rc = pid; | ||||
|     } else { | ||||
|       rc = __winerr(); | ||||
|  | @ -27,7 +27,6 @@ LIBC_STDIO_A_DIRECTDEPS =				\ | |||
| 	LIBC_ALG					\
 | ||||
| 	LIBC_BITS					\
 | ||||
| 	LIBC_CALLS					\
 | ||||
| 	LIBC_CALLS_HEFTY				\
 | ||||
| 	LIBC_FMT					\
 | ||||
| 	LIBC_INTRIN					\
 | ||||
| 	LIBC_MEM					\
 | ||||
|  |  | |||
|  | @ -34,7 +34,6 @@ LIBC_X_A_CHECKS =				\ | |||
| 
 | ||||
| LIBC_X_A_DIRECTDEPS =				\
 | ||||
| 	LIBC_CALLS				\
 | ||||
| 	LIBC_CALLS_HEFTY			\
 | ||||
| 	LIBC_FMT				\
 | ||||
| 	LIBC_INTRIN				\
 | ||||
| 	LIBC_MEM				\
 | ||||
|  |  | |||
|  | @ -24,13 +24,13 @@ char16_t envvars[ARG_MAX]; | |||
| 
 | ||||
| TEST(mkntenvblock, emptyList_onlyOutputsDoubleNulStringTerminator) { | ||||
|   char *envp[] = {NULL}; | ||||
|   ASSERT_NE(-1, mkntenvblock(envvars, envp)); | ||||
|   ASSERT_NE(-1, mkntenvblock(envvars, envp, NULL)); | ||||
|   ASSERT_BINEQ(u"  ", envvars); | ||||
| } | ||||
| 
 | ||||
| TEST(mkntenvblock, envp_becomesSortedDoubleNulTerminatedUtf16String) { | ||||
|   char *envp[] = {"u=b", "c=d", "韩=非", "uh=d", "hduc=d", NULL}; | ||||
|   ASSERT_NE(-1, mkntenvblock(envvars, envp)); | ||||
|   ASSERT_NE(-1, mkntenvblock(envvars, envp, NULL)); | ||||
|   ASSERT_BINEQ(u"c = d   " | ||||
|                u"h d u c = d   " | ||||
|                u"u = b   " | ||||
|  | @ -39,3 +39,16 @@ TEST(mkntenvblock, envp_becomesSortedDoubleNulTerminatedUtf16String) { | |||
|                u"  ", | ||||
|                envvars); | ||||
| } | ||||
| 
 | ||||
| TEST(mkntenvblock, extraVar_getsAdded) { | ||||
|   char *envp[] = {"u=b", "c=d", "韩=非", "uh=d", "hduc=d", NULL}; | ||||
|   ASSERT_NE(-1, mkntenvblock(envvars, envp, "a=a")); | ||||
|   ASSERT_BINEQ(u"a = a   " | ||||
|                u"c = d   " | ||||
|                u"h d u c = d   " | ||||
|                u"u = b   " | ||||
|                u"u h = d   " | ||||
|                u"Θù= ^ù  " | ||||
|                u"  ", | ||||
|                envvars); | ||||
| } | ||||
|  |  | |||
|  | @ -4,8 +4,7 @@ | |||
| PKGS += TEST_LIBC_CALLS | ||||
| 
 | ||||
| TEST_LIBC_CALLS_SRCS :=					\
 | ||||
| 	$(wildcard test/libc/calls/*.c)			\
 | ||||
| 	$(wildcard test/libc/calls/hefty/*.c) | ||||
| 	$(wildcard test/libc/calls/*.c) | ||||
| TEST_LIBC_CALLS_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_CALLS_SRCS)) | ||||
| 
 | ||||
| TEST_LIBC_CALLS_OBJS =					\
 | ||||
|  | @ -26,13 +25,13 @@ TEST_LIBC_CALLS_CHECKS =				\ | |||
| 
 | ||||
| TEST_LIBC_CALLS_DIRECTDEPS =				\
 | ||||
| 	LIBC_CALLS					\
 | ||||
| 	LIBC_CALLS_HEFTY				\
 | ||||
| 	LIBC_FMT					\
 | ||||
| 	LIBC_INTRIN					\
 | ||||
| 	LIBC_LOG					\
 | ||||
| 	LIBC_MEM					\
 | ||||
| 	LIBC_NEXGEN32E					\
 | ||||
| 	LIBC_RAND					\
 | ||||
| 	LIBC_STDIO					\
 | ||||
| 	LIBC_RUNTIME					\
 | ||||
| 	LIBC_STR					\
 | ||||
| 	LIBC_STUBS					\
 | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ TEST_LIBC_STDIO_DIRECTDEPS =				\ | |||
| 	LIBC_INTRIN					\
 | ||||
| 	LIBC_MEM					\
 | ||||
| 	LIBC_NEXGEN32E					\
 | ||||
| 	LIBC_RAND					\
 | ||||
| 	LIBC_RUNTIME					\
 | ||||
| 	LIBC_STDIO					\
 | ||||
| 	LIBC_STR					\
 | ||||
|  |  | |||
							
								
								
									
										1
									
								
								third_party/chibicc/chibicc.mk
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								third_party/chibicc/chibicc.mk
									
										
									
									
										vendored
									
									
								
							|  | @ -51,7 +51,6 @@ THIRD_PARTY_CHIBICC_A_DIRECTDEPS =					\ | |||
| 	LIBC_ALG							\
 | ||||
| 	LIBC_BITS							\
 | ||||
| 	LIBC_CALLS							\
 | ||||
| 	LIBC_CALLS_HEFTY						\
 | ||||
| 	LIBC_FMT							\
 | ||||
| 	LIBC_INTRIN							\
 | ||||
| 	LIBC_LOG							\
 | ||||
|  |  | |||
							
								
								
									
										1
									
								
								third_party/musl/musl.mk
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								third_party/musl/musl.mk
									
										
									
									
										vendored
									
									
								
							|  | @ -19,7 +19,6 @@ THIRD_PARTY_MUSL_A_OBJS =				\ | |||
| THIRD_PARTY_MUSL_A_DIRECTDEPS =				\
 | ||||
| 	LIBC_ALG					\
 | ||||
| 	LIBC_CALLS					\
 | ||||
| 	LIBC_CALLS_HEFTY				\
 | ||||
| 	LIBC_INTRIN					\
 | ||||
| 	LIBC_MEM					\
 | ||||
| 	LIBC_NEXGEN32E					\
 | ||||
|  |  | |||
|  | @ -28,7 +28,6 @@ TOOL_BUILD_DIRECTDEPS =					\ | |||
| 	LIBC_ALG					\
 | ||||
| 	LIBC_BITS					\
 | ||||
| 	LIBC_CALLS					\
 | ||||
| 	LIBC_CALLS_HEFTY				\
 | ||||
| 	LIBC_DNS					\
 | ||||
| 	LIBC_ELF					\
 | ||||
| 	LIBC_FMT					\
 | ||||
|  |  | |||
|  | @ -27,7 +27,6 @@ TOOL_BUILD_LIB_A_DIRECTDEPS =				\ | |||
| 	LIBC_ALG					\
 | ||||
| 	LIBC_BITS					\
 | ||||
| 	LIBC_CALLS					\
 | ||||
| 	LIBC_CALLS_HEFTY				\
 | ||||
| 	LIBC_ELF					\
 | ||||
| 	LIBC_FMT					\
 | ||||
| 	LIBC_INTRIN					\
 | ||||
|  |  | |||
|  | @ -22,7 +22,6 @@ TOOL_NET_DIRECTDEPS =						\ | |||
| 	LIBC_ALG						\
 | ||||
| 	LIBC_BITS						\
 | ||||
| 	LIBC_CALLS						\
 | ||||
| 	LIBC_CALLS_HEFTY					\
 | ||||
| 	LIBC_DNS						\
 | ||||
| 	LIBC_FMT						\
 | ||||
| 	LIBC_INTRIN						\
 | ||||
|  |  | |||
|  | @ -1473,8 +1473,8 @@ int main(int argc, char *argv[]) { | |||
|   if (!tuned_) PickDefaults(); | ||||
|   if (optind == argc) PrintUsage(EX_USAGE, stderr); | ||||
|   patharg_ = argv[optind]; | ||||
|   sox_ = commandvenv("SOX", "sox"); | ||||
|   ffplay_ = commandvenv("FFPLAY", "ffplay"); | ||||
|   sox_ = strdup(commandvenv("SOX", "sox")); | ||||
|   ffplay_ = strdup(commandvenv("FFPLAY", "ffplay")); | ||||
|   infd_ = STDIN_FILENO; | ||||
|   outfd_ = STDOUT_FILENO; | ||||
|   if (!setjmp(jb_)) { | ||||
|  |  | |||
|  | @ -22,7 +22,6 @@ TOOL_VIZ_DIRECTDEPS =				\ | |||
| 	DSP_TTY					\
 | ||||
| 	LIBC_BITS				\
 | ||||
| 	LIBC_CALLS				\
 | ||||
| 	LIBC_CALLS_HEFTY			\
 | ||||
| 	LIBC_DNS				\
 | ||||
| 	LIBC_FMT				\
 | ||||
| 	LIBC_INTRIN				\
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue