diff --git a/Makefile b/Makefile
index 4cfa46c9b..e84903db8 100644
--- a/Makefile
+++ b/Makefile
@@ -83,7 +83,6 @@ o/$(MODE): \
.STRICT = 1
.UNVEIL = \
- rwcx:o/tmp \
libc/integral \
libc/disclaimer.inc \
rx:build/bootstrap \
diff --git a/build/bootstrap/make.com b/build/bootstrap/make.com
index 76c624c5d..b46d31429 100755
Binary files a/build/bootstrap/make.com and b/build/bootstrap/make.com differ
diff --git a/libc/calls/mkntpath.c b/libc/calls/mkntpath.c
index 2dfa14f46..f3ad69e04 100644
--- a/libc/calls/mkntpath.c
+++ b/libc/calls/mkntpath.c
@@ -103,6 +103,20 @@ textwindows int __mkntpath2(const char *path,
q += 3;
z -= 7;
x = 7;
+ } else if (IsSlash(q[0]) && IsAlpha(q[1]) && !q[2]) {
+ z = MIN(32767, PATH_MAX);
+ // turn "\c" into "\\?\c:\"
+ p[0] = '\\';
+ p[1] = '\\';
+ p[2] = '?';
+ p[3] = '\\';
+ p[4] = q[1];
+ p[5] = ':';
+ p[6] = '\\';
+ p += 7;
+ q += 2;
+ z -= 7;
+ x = 7;
} else if (IsSlash(q[0]) && IsAlpha(q[1]) && IsSlash(q[2])) {
z = MIN(32767, PATH_MAX);
// turn "c:\foo" into "\\?\c:\foo"
diff --git a/libc/calls/symlinkat.c b/libc/calls/symlinkat.c
index 6f14274ef..cbe3b9af7 100644
--- a/libc/calls/symlinkat.c
+++ b/libc/calls/symlinkat.c
@@ -51,6 +51,6 @@ int symlinkat(const char *target, int newdirfd, const char *linkpath) {
rc = sys_symlinkat_nt(target, newdirfd, linkpath);
}
STRACE("symlinkat(%#s, %s, %#s) → %d% m", target, DescribeDirfd(newdirfd),
- linkpath);
+ linkpath, rc);
return rc;
}
diff --git a/libc/sock/nointernet.c b/libc/sock/nointernet.c
index f9accce18..73a3a6083 100644
--- a/libc/sock/nointernet.c
+++ b/libc/sock/nointernet.c
@@ -249,19 +249,12 @@ static int WaitForTrace(int main) {
// eintr isn't possible since we're blocking all signals
ORDIE(pid = waitpid(-1, &ws, __WALL));
LogProcessEvent(main, pid, ws);
- // once main child exits or dies, we exit / die the same way. we're
- // not currently tracking pids, so it's important that a child does
- // not exit before its children. otherwise the grandchildren get in
- // a permanently stopped state. to address that, we'll send sigterm
- // to the process group which we defined earlier.
if (WIFEXITED(ws)) {
if (pid == main) {
- kill(-getpid(), SIGTERM);
_Exit(WEXITSTATUS(ws));
}
} else if (WIFSIGNALED(ws)) {
if (pid == main) {
- kill(-getpid(), SIGTERM);
Raise(WTERMSIG(ws));
}
} else if (WIFSTOPPED(ws)) {
@@ -294,12 +287,6 @@ int nointernet(void) {
return enosys();
}
- // ensure we're at the root of a process group, so we're able to
- // broadcast a termination signal later on that catches dangling
- // subprocesss our child forgot to destroy. without calling this
- // subprocesses could end up permanently stopped if monitor dies
- setpgrp();
-
// prevent crash handlers from intercepting sigsegv
ORDIE(sigfillset(&set));
ORDIE(sigprocmask(SIG_SETMASK, &set, &old));
diff --git a/libc/str/strcasecmp.c b/libc/str/strcasecmp.c
index 29f6d3274..9dfcf80f4 100644
--- a/libc/str/strcasecmp.c
+++ b/libc/str/strcasecmp.c
@@ -16,15 +16,10 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
+#include "libc/dce.h"
+#include "libc/intrin/asan.internal.h"
#include "libc/str/str.h"
-static inline noasan uint64_t UncheckedAlignedRead64(const char *p) {
- return (uint64_t)(255 & p[7]) << 070 | (uint64_t)(255 & p[6]) << 060 |
- (uint64_t)(255 & p[5]) << 050 | (uint64_t)(255 & p[4]) << 040 |
- (uint64_t)(255 & p[3]) << 030 | (uint64_t)(255 & p[2]) << 020 |
- (uint64_t)(255 & p[1]) << 010 | (uint64_t)(255 & p[0]) << 000;
-}
-
/**
* Compares NUL-terminated strings ascii case-insensitively.
*
@@ -33,7 +28,7 @@ static inline noasan uint64_t UncheckedAlignedRead64(const char *p) {
* @return is <0, 0, or >0 based on tolower(uint8_t) comparison
* @asyncsignalsafe
*/
-int strcasecmp(const char *a, const char *b) {
+noasan int strcasecmp(const char *a, const char *b) {
int x, y;
size_t i = 0;
uint64_t v, w, d;
@@ -41,13 +36,17 @@ int strcasecmp(const char *a, const char *b) {
if (((uintptr_t)a & 7) == ((uintptr_t)b & 7)) {
for (; (uintptr_t)(a + i) & 7; ++i) {
CheckEm:
+ if (IsAsan()) {
+ __asan_verify(a, i + 1);
+ __asan_verify(b, i + 1);
+ }
if ((x = kToLower[a[i] & 255]) != (y = kToLower[b[i] & 255]) || !y) {
return x - y;
}
}
for (;; i += 8) {
- v = UncheckedAlignedRead64(a + i);
- w = UncheckedAlignedRead64(b + i);
+ v = *(uint64_t *)(a + i);
+ w = *(uint64_t *)(b + i);
w = (v ^ w) | (~v & (v - 0x0101010101010101) & 0x8080808080808080);
if (w) {
i += (unsigned)__builtin_ctzll(w) >> 3;
@@ -56,6 +55,10 @@ int strcasecmp(const char *a, const char *b) {
}
} else {
while ((x = kToLower[a[i] & 255]) == (y = kToLower[b[i] & 255]) && y) ++i;
+ if (IsAsan()) {
+ __asan_verify(a, i + 1);
+ __asan_verify(b, i + 1);
+ }
return x - y;
}
}
diff --git a/libc/str/strcmp.c b/libc/str/strcmp.c
index a13789931..58f1d5146 100644
--- a/libc/str/strcmp.c
+++ b/libc/str/strcmp.c
@@ -17,12 +17,9 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dce.h"
+#include "libc/intrin/asan.internal.h"
#include "libc/str/str.h"
-static inline noasan uint64_t UncheckedAlignedRead64(const char *p) {
- return *(uint64_t *)p;
-}
-
/**
* Compares NUL-terminated strings.
*
@@ -31,7 +28,7 @@ static inline noasan uint64_t UncheckedAlignedRead64(const char *p) {
* @return is <0, 0, or >0 based on uint8_t comparison
* @asyncsignalsafe
*/
-int strcmp(const char *a, const char *b) {
+noasan int strcmp(const char *a, const char *b) {
int c;
size_t i = 0;
uint64_t v, w, d;
@@ -44,16 +41,20 @@ int strcmp(const char *a, const char *b) {
}
}
for (;; i += 8) {
- v = UncheckedAlignedRead64(a + i);
- w = UncheckedAlignedRead64(b + i);
+ v = *(uint64_t *)(a + i);
+ w = *(uint64_t *)(b + i);
w = (v ^ w) | (~v & (v - 0x0101010101010101) & 0x8080808080808080);
if (w) {
i += (unsigned)__builtin_ctzll(w) >> 3;
- return (a[i] & 255) - (b[i] & 255);
+ break;
}
}
} else {
while (a[i] == b[i] && b[i]) ++i;
- return (a[i] & 255) - (b[i] & 255);
}
+ if (IsAsan()) {
+ __asan_verify(a, i + 1);
+ __asan_verify(b, i + 1);
+ }
+ return (a[i] & 255) - (b[i] & 255);
}
diff --git a/libc/testlib/testrunner.c b/libc/testlib/testrunner.c
index e06d17bc2..c75117db5 100644
--- a/libc/testlib/testrunner.c
+++ b/libc/testlib/testrunner.c
@@ -17,8 +17,6 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
-#include "libc/intrin/atomic.h"
-#include "libc/intrin/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/strace.internal.h"
@@ -29,8 +27,10 @@
#include "libc/errno.h"
#include "libc/fmt/fmt.h"
#include "libc/fmt/itoa.h"
+#include "libc/intrin/atomic.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/spinlock.h"
+#include "libc/intrin/weaken.h"
#include "libc/log/check.h"
#include "libc/log/internal.h"
#include "libc/macros.internal.h"
@@ -88,7 +88,7 @@ wontreturn void testlib_abort(void) {
static void SetupTmpDir(void) {
char *p = g_testlib_tmpdir;
- p = stpcpy(p, "o/tmp/");
+ p = stpcpy(p, kTmpPath);
p = stpcpy(p, program_invocation_short_name), *p++ = '.';
p = FormatInt64(p, getpid()), *p++ = '.';
p = FormatInt64(p, x++);
diff --git a/libc/tinymath/fmod.S b/libc/tinymath/fmod-tiny.S
similarity index 98%
rename from libc/tinymath/fmod.S
rename to libc/tinymath/fmod-tiny.S
index 5762bcbd1..4ad6ff8ba 100644
--- a/libc/tinymath/fmod.S
+++ b/libc/tinymath/fmod-tiny.S
@@ -17,6 +17,7 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.internal.h"
+#ifdef TINY
// fmod [sic] does (𝑥 rem 𝑦) w/ round()-style rounding.
//
@@ -28,3 +29,5 @@
fmod: ezlea fmodl,ax
jmp _d2ld2
.endfn fmod,globl
+
+#endif /* TINY */
diff --git a/libc/tinymath/fmod.c b/libc/tinymath/fmod.c
new file mode 100644
index 000000000..27e89f986
--- /dev/null
+++ b/libc/tinymath/fmod.c
@@ -0,0 +1,105 @@
+/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
+│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
+╚──────────────────────────────────────────────────────────────────────────────╝
+│ │
+│ Musl Libc │
+│ Copyright © 2005-2014 Rich Felker, et al. │
+│ │
+│ Permission is hereby granted, free of charge, to any person obtaining │
+│ a copy of this software and associated documentation files (the │
+│ "Software"), to deal in the Software without restriction, including │
+│ without limitation the rights to use, copy, modify, merge, publish, │
+│ distribute, sublicense, and/or sell copies of the Software, and to │
+│ permit persons to whom the Software is furnished to do so, subject to │
+│ the following conditions: │
+│ │
+│ The above copyright notice and this permission notice shall be │
+│ included in all copies or substantial portions of the Software. │
+│ │
+│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
+│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
+│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
+│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
+│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
+│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
+│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
+│ │
+╚─────────────────────────────────────────────────────────────────────────────*/
+#include "third_party/libcxx/math.h"
+
+asm(".ident\t\"\\n\\n\
+Musl libc (MIT License)\\n\
+Copyright 2005-2014 Rich Felker, et. al.\"");
+asm(".include \"libc/disclaimer.inc\"");
+// clang-format off
+
+/**
+ * Does (𝑥 rem 𝑦) w/ round()-style rounding.
+ * @return remainder ∈ (-|𝑦|,|𝑦|) in %xmm0
+ * @define 𝑥-trunc(𝑥/𝑦)*𝑦
+ */
+double fmod(double x, double y)
+{
+ union {double f; uint64_t i;} ux = {x}, uy = {y};
+ int ex = ux.i>>52 & 0x7ff;
+ int ey = uy.i>>52 & 0x7ff;
+ int sx = ux.i>>63;
+ uint64_t i;
+
+ /* in the followings uxi should be ux.i, but then gcc wrongly adds */
+ /* float load/store to inner loops ruining performance and code size */
+ uint64_t uxi = ux.i;
+
+ if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff)
+ return (x*y)/(x*y);
+ if (uxi<<1 <= uy.i<<1) {
+ if (uxi<<1 == uy.i<<1)
+ return 0*x;
+ return x;
+ }
+
+ /* normalize x and y */
+ if (!ex) {
+ for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1);
+ uxi <<= -ex + 1;
+ } else {
+ uxi &= -1ULL >> 12;
+ uxi |= 1ULL << 52;
+ }
+ if (!ey) {
+ for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1);
+ uy.i <<= -ey + 1;
+ } else {
+ uy.i &= -1ULL >> 12;
+ uy.i |= 1ULL << 52;
+ }
+
+ /* x mod y */
+ for (; ex > ey; ex--) {
+ i = uxi - uy.i;
+ if (i >> 63 == 0) {
+ if (i == 0)
+ return 0*x;
+ uxi = i;
+ }
+ uxi <<= 1;
+ }
+ i = uxi - uy.i;
+ if (i >> 63 == 0) {
+ if (i == 0)
+ return 0*x;
+ uxi = i;
+ }
+ for (; uxi>>52 == 0; uxi <<= 1, ex--);
+
+ /* scale result */
+ if (ex > 0) {
+ uxi -= 1ULL << 52;
+ uxi |= (uint64_t)ex << 52;
+ } else {
+ uxi >>= -ex + 1;
+ }
+ uxi |= (uint64_t)sx << 63;
+ ux.i = uxi;
+ return ux.f;
+}
diff --git a/libc/x/rmrf.c b/libc/x/rmrf.c
index b84d78191..257920356 100644
--- a/libc/x/rmrf.c
+++ b/libc/x/rmrf.c
@@ -58,6 +58,8 @@ static int rmrfdir(const char *dirpath) {
/**
* Recursively removes file or directory.
+ *
+ * @return 0 on success, or -1 w/ errno
*/
int rmrf(const char *path) {
int e;
diff --git a/test/libc/calls/mkntpath_test.c b/test/libc/calls/mkntpath_test.c
index 06baab1f6..5da2e10c2 100644
--- a/test/libc/calls/mkntpath_test.c
+++ b/test/libc/calls/mkntpath_test.c
@@ -50,3 +50,8 @@ TEST(mkntpath, testRemoveDoubleSlash) {
EXPECT_EQ(8, __mkntpath("\\\\?\\doge", p));
EXPECT_STREQ(u"\\\\?\\doge", p);
}
+
+TEST(mkntpath, testJustC) {
+ EXPECT_EQ(7, __mkntpath("/C", p));
+ EXPECT_STREQ(u"\\\\?\\C:\\", p);
+}
diff --git a/test/libc/str/strcmp_test.c b/test/libc/str/strcmp_test.c
index c17b2a064..eb953c56e 100644
--- a/test/libc/str/strcmp_test.c
+++ b/test/libc/str/strcmp_test.c
@@ -534,8 +534,8 @@ void longstringislong_dupe(size_t size, char data[size], char dupe[size]) {
BENCH(bench_00_strcmp, bench) {
size_t size;
char *dupe, *data;
- size = ROUNDDOWN(MAX(FRAMESIZE, getcachesize(kCpuCacheTypeData, 1)) / 2,
- PAGESIZE);
+
+ size = 14139;
data = gc(malloc(size));
dupe = gc(malloc(size));
@@ -576,8 +576,7 @@ BENCH(bench_00_strcmp, bench) {
BENCH(bench_01_strcasecmp, bench) {
size_t size;
char *dupe, *data;
- size = ROUNDDOWN(MAX(FRAMESIZE, getcachesize(kCpuCacheTypeData, 1)) / 2,
- PAGESIZE);
+ size = 141393;
data = gc(malloc(size));
dupe = gc(malloc(size));
diff --git a/test/libc/tinymath/fmod_test.c b/test/libc/tinymath/fmod_test.c
index 0bcfad25d..a9d9ddff0 100644
--- a/test/libc/tinymath/fmod_test.c
+++ b/test/libc/tinymath/fmod_test.c
@@ -17,8 +17,8 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/math.h"
-#include "libc/stdio/rand.h"
#include "libc/runtime/gc.internal.h"
+#include "libc/stdio/rand.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
@@ -67,7 +67,19 @@ TEST(fmodf, test) {
EXPECT_STREQ("8e+20", gc(xdtoaf(fmodf(8e20, 32e20))));
}
-BENCH(fmod, bench) {
- EZBENCH2("fmod eze", donothing, fmodl(8, 32));
- EZBENCH2("fmod big", donothing, fmodl(5.319372648326541e+255, M_2_PI));
+BENCH(fmodf, bench) {
+ EZBENCH2("fmodf eze", donothing, fmodf(8, 32));
+ EZBENCH2("fmodf big", donothing, fmodf(5.319372648326541e+255, M_2_PI));
+}
+
+BENCH(fmod, bench) {
+ // fmod-tiny.S goes slow in the average case, fast for big case
+ EZBENCH2("fmod eze", donothing, fmod(8, 32));
+ // fmod.c goes fast for the average case very slow for big case
+ EZBENCH2("fmod big", donothing, fmod(5.319372648326541e+255, M_2_PI));
+}
+
+BENCH(fmodl, bench) {
+ EZBENCH2("fmodl eze", donothing, fmodl(8, 32));
+ EZBENCH2("fmodl big", donothing, fmodl(5.319372648326541e+255, M_2_PI));
}
diff --git a/test/tool/net/lunix_test.lua b/test/tool/net/lunix_test.lua
index b6509fa51..4bb8bd688 100644
--- a/test/tool/net/lunix_test.lua
+++ b/test/tool/net/lunix_test.lua
@@ -14,7 +14,7 @@
-- PERFORMANCE OF THIS SOFTWARE.
gotsigusr1 = false
-tmpdir = "o/tmp/lunix_test.%d" % {unix.getpid()}
+tmpdir = "%s/o/tmp/lunix_test.%d" % {os.getenv('TMPDIR'), unix.getpid()}
function string.starts(String,Start)
return string.sub(String,1,string.len(Start))==Start
diff --git a/test/tool/net/slurp_test.lua b/test/tool/net/slurp_test.lua
index 75d481968..4721c48e2 100644
--- a/test/tool/net/slurp_test.lua
+++ b/test/tool/net/slurp_test.lua
@@ -13,7 +13,7 @@
-- TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
-tmpdir = "o/tmp/lunix_test.%d" % {unix.getpid()}
+tmpdir = "%s/o/tmp/lunix_test.%d" % {os.getenv('TMPDIR'), unix.getpid()}
local function Path(name)
return tmpdir .. '/' .. name
diff --git a/third_party/make/config.h b/third_party/make/config.h
index 14385ed0b..16f429cfa 100644
--- a/third_party/make/config.h
+++ b/third_party/make/config.h
@@ -620,7 +620,7 @@
/* #undef HAVE__SET_INVALID_PARAMETER_HANDLER */
/* Build host information. */
-#define MAKE_HOST "x86_64-pc-cosmopolitan"
+#define MAKE_HOST "x86_64-cosmopolitan"
/* Define to 1 to enable job server support in GNU make. */
/* TODO(jart): make it work */
diff --git a/third_party/make/debug.h b/third_party/make/debug.h
index a6363ff01..84440f107 100644
--- a/third_party/make/debug.h
+++ b/third_party/make/debug.h
@@ -15,6 +15,8 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see . */
+#include "libc/intrin/likely.h"
+
#define DB_NONE (0x000)
#define DB_BASIC (0x001)
#define DB_VERBOSE (0x002)
@@ -26,7 +28,7 @@ this program. If not, see . */
extern int db_level;
-#define ISDB(_l) ((_l)&db_level)
+#define ISDB(_l) UNLIKELY((_l)&db_level)
/* When adding macros to this list be sure to update the value of
XGETTEXT_OPTIONS in the po/Makevars file. */
diff --git a/third_party/make/getloadavg.c b/third_party/make/getloadavg.c
deleted file mode 100644
index 24b53edb4..000000000
--- a/third_party/make/getloadavg.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/* clang-format off */
-/* Get the system load averages.
-
- Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2020 Free Software
- Foundation, Inc.
-
- NOTE: The canonical source of this file is maintained with gnulib.
- Bugs can be reported to bug-gnulib@gnu.org.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see . */
-
-/* Compile-time symbols that this file uses:
-
- HAVE_PSTAT_GETDYNAMIC Define this if your system has the
- pstat_getdynamic function. I think it
- is unique to HPUX9. The best way to get the
- definition is through the AC_FUNC_GETLOADAVG
- macro that comes with autoconf 2.13 or newer.
- If that isn't an option, then just put
- AC_CHECK_FUNCS(pstat_getdynamic) in your
- configure.ac file.
- HAVE_LIBPERFSTAT Define this if your system has the
- perfstat_cpu_total function in libperfstat (AIX).
- FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist.
- KERNEL_FILE Name of the kernel file to nlist.
- LDAV_CVT() Scale the load average from the kernel.
- Returns a double.
- LDAV_SYMBOL Name of kernel symbol giving load average.
- LOAD_AVE_TYPE Type of the load average array in the kernel.
- Must be defined unless one of
- apollo, DGUX, NeXT, or UMAX is defined;
- or we have libkstat;
- otherwise, no load average is available.
- HAVE_NLIST_H nlist.h is available. NLIST_STRUCT defaults
- to this.
- NLIST_STRUCT Include nlist.h, not a.out.h.
- N_NAME_POINTER The nlist n_name element is a pointer,
- not an array.
- HAVE_STRUCT_NLIST_N_UN_N_NAME 'n_un.n_name' is member of 'struct nlist'.
- LINUX_LDAV_FILE [__linux__, __ANDROID__, __CYGWIN__]: File
- containing load averages.
-
- Specific system predefines this file uses, aside from setting
- default values if not emacs:
-
- apollo
- BSD Real BSD, not just BSD-like.
- DGUX
- eunice UNIX emulator under VMS.
- hpux
- __MSDOS__ No-op for MSDOS.
- NeXT
- sgi
- UMAX
- UMAX4_3
- VMS
- _WIN32 Native Windows (possibly also defined on Cygwin)
- __linux__, __ANDROID__ Linux: assumes /proc file system mounted.
- Support from Michael K. Johnson.
- __CYGWIN__ Cygwin emulates linux /proc/loadavg.
- __NetBSD__ NetBSD: assumes /kern file system mounted.
-
- In addition, to avoid nesting many #ifdefs, we internally set
- LDAV_DONE to indicate that the load average has been computed.
-
- We also #define LDAV_PRIVILEGED if a program will require
- special installation to be able to call getloadavg. */
-
-#include "libc/sysv/consts/o.h"
-#include "libc/errno.h"
-#include "libc/dce.h"
-#include "libc/dce.h"
-#include "libc/dce.h"
-#include "libc/sysv/errfuns.h"
-#include "libc/stdio/stdio.h"
-#include "third_party/make/config.h"
-#include "third_party/make/intprops.h"
-
-/* Put the 1 minute, 5 minute and 15 minute load averages
- into the first NELEM elements of LOADAVG.
- Return the number written (never more than 3, but may be less than NELEM),
- or -1 (setting errno) if an error occurred. */
-
-int
-getloadavg (double loadavg[], int nelem)
-{
- int elem = 0; /* Return value. */
- if (IsLinux()) {
- char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")];
- char const *ptr = ldavgbuf;
- int fd, count, saved_errno;
- fd = open ("/proc/loadavg", O_RDONLY);
- if (fd == -1)
- return -1;
- count = read (fd, ldavgbuf, sizeof ldavgbuf - 1);
- saved_errno = errno;
- (void) close (fd);
- errno = saved_errno;
- if (count <= 0)
- return -1;
- ldavgbuf[count] = '\0';
- for (elem = 0; elem < nelem; elem++)
- {
- double numerator = 0;
- double denominator = 1;
- while (*ptr == ' ')
- ptr++;
- /* Finish if this number is missing, and report an error if all
- were missing. */
- if (! ('0' <= *ptr && *ptr <= '9'))
- {
- if (elem == 0)
- return enotsup();
- break;
- }
- while ('0' <= *ptr && *ptr <= '9')
- numerator = 10 * numerator + (*ptr++ - '0');
- if (*ptr == '.')
- for (ptr++; '0' <= *ptr && *ptr <= '9'; ptr++)
- numerator = 10 * numerator + (*ptr - '0'), denominator *= 10;
- loadavg[elem++] = numerator / denominator;
- }
- } else if (IsNetbsd()) {
- unsigned long int load_ave[3], scale;
- int count;
- FILE *fp;
- fp = fopen ("/kern/loadavg", "r");
- if (fp == NULL)
- return -1;
- count = fscanf (fp, "%lu %lu %lu %lu\n",
- &load_ave[0], &load_ave[1], &load_ave[2],
- &scale);
- fclose (fp);
- if (count != 4)
- return enotsup();
- for (elem = 0; elem < nelem; elem++)
- loadavg[elem] = (double) load_ave[elem] / (double) scale;
- } else if (IsWindows()) {
- for ( ; elem < nelem; elem++)
- loadavg[elem] = 0.0;
- } else {
- errno = ENOSYS;
- elem = -1;
- }
- return elem;
-}
diff --git a/third_party/make/job.c b/third_party/make/job.c
index a571b7497..3852add06 100644
--- a/third_party/make/job.c
+++ b/third_party/make/job.c
@@ -1,4 +1,3 @@
-/* clang-format off */
/* Job execution and handling for GNU Make.
Copyright (C) 1988-2020 Free Software Foundation, Inc.
This file is part of GNU Make.
@@ -21,55 +20,40 @@ this program. If not, see . */
#include "third_party/make/filedef.h"
#include "third_party/make/job.h"
/**/
-#include "third_party/make/commands.h"
-#include "third_party/make/os.h"
-#include "third_party/make/variable.h"
-#include "libc/log/log.h"
-#include "libc/runtime/stack.h"
-#include "libc/calls/calls.h"
-#include "libc/x/x.h"
-#include "libc/intrin/safemacros.internal.h"
-#include "libc/x/x.h"
-#include "libc/runtime/runtime.h"
-#include "libc/intrin/safemacros.internal.h"
-#include "libc/elf/struct/ehdr.h"
-#include "libc/intrin/bits.h"
-#include "libc/intrin/kprintf.h"
-#include "libc/intrin/kprintf.h"
-#include "libc/intrin/safemacros.internal.h"
-#include "libc/runtime/runtime.h"
-#include "libc/elf/def.h"
-#include "libc/intrin/kprintf.h"
-#include "libc/elf/struct/phdr.h"
-#include "libc/elf/def.h"
-#include "libc/elf/elf.h"
-#include "libc/calls/calls.h"
-#include "libc/sysv/consts/prot.h"
-#include "libc/sysv/consts/map.h"
-#include "libc/intrin/kprintf.h"
-#include "libc/sysv/consts/o.h"
-#include "libc/calls/struct/timeval.h"
-#include "libc/x/x.h"
-#include "libc/intrin/kprintf.h"
-#include "libc/time/time.h"
-#include "libc/calls/calls.h"
-#include "libc/intrin/kprintf.h"
#include "libc/assert.h"
-#include "libc/sysv/consts/pr.h"
+#include "libc/calls/calls.h"
#include "libc/calls/struct/bpf.h"
#include "libc/calls/struct/filter.h"
#include "libc/calls/struct/seccomp.h"
-#include "libc/calls/struct/filter.h"
-#include "libc/sysv/consts/pr.h"
-#include "libc/sysv/consts/pr.h"
-#include "libc/sysv/consts/audit.h"
-#include "libc/sysv/consts/nrlinux.h"
-#include "libc/macros.internal.h"
+#include "libc/calls/struct/timeval.h"
+#include "libc/elf/def.h"
+#include "libc/elf/elf.h"
+#include "libc/elf/struct/ehdr.h"
+#include "libc/elf/struct/phdr.h"
+#include "libc/fmt/fmt.h"
+#include "libc/intrin/bits.h"
+#include "libc/intrin/safemacros.internal.h"
+#include "libc/log/backtrace.internal.h"
+#include "libc/log/log.h"
#include "libc/log/rop.h"
-#include "libc/intrin/kprintf.h"
+#include "libc/macros.internal.h"
+#include "libc/runtime/runtime.h"
+#include "libc/runtime/stack.h"
#include "libc/sock/sock.h"
-#include "libc/intrin/kprintf.h"
+#include "libc/str/str.h"
+#include "libc/sysv/consts/audit.h"
+#include "libc/sysv/consts/map.h"
+#include "libc/sysv/consts/nrlinux.h"
+#include "libc/sysv/consts/o.h"
+#include "libc/sysv/consts/pr.h"
+#include "libc/sysv/consts/prot.h"
+#include "libc/time/time.h"
+#include "libc/x/x.h"
+#include "third_party/make/commands.h"
#include "third_party/make/dep.h"
+#include "third_party/make/os.h"
+#include "third_party/make/variable.h"
+// clang-format off
#define GOTO_SLOW \
do { \
@@ -391,6 +375,134 @@ child_error (struct child *child,
}
+/* [jart] manage temporary directories per rule */
+
+const char *
+get_tmpdir (struct file *file)
+{
+ const struct variable *var;
+ if ((var = lookup_variable_in_set (STRING_SIZE_TUPLE("TMPDIR"),
+ file->variables->set)) ||
+ (file->pat_variables &&
+ (var = lookup_variable_in_set (STRING_SIZE_TUPLE("TMPDIR"),
+ file->pat_variables->set))) ||
+ (var = lookup_variable (STRING_SIZE_TUPLE("TMPDIR"))))
+ return variable_expand (var->value);
+ else
+ return kTmpPath;
+}
+
+char *
+new_tmpdir (const char *tmp, struct file *file)
+{
+ const char *s;
+ int c, e, i, j;
+ char *dir, *tmpdir;
+ char cwd[PATH_MAX];
+ char path[PATH_MAX];
+
+ /* create temporary directory in tmp */
+ i = 0;
+
+ /* ensure tmpdir will be absolute */
+ if (tmp[0] != '/')
+ {
+ if (getcwd(cwd, sizeof(cwd)))
+ {
+ for (j = 0; cwd[j]; ++j)
+ if (i < PATH_MAX)
+ path[i++] = cwd[j];
+ if (i && path[i - 1] != '/')
+ if (i < PATH_MAX)
+ path[i++] = '/';
+ }
+ else
+ DB (DB_JOBS, (_("Failed to get current directory\n")));
+ }
+
+ /* copy old tmpdir */
+ for (j = 0; tmp[j]; ++j)
+ if (i < PATH_MAX)
+ path[i++] = tmp[j];
+
+ /* append slash */
+ if (i && path[i - 1] != '/')
+ if (i < PATH_MAX)
+ path[i++] = '/';
+
+ /* append target name safely */
+ for (j = 0; (c = file->name[j]); ++j)
+ {
+ if (isalnum(c))
+ c = tolower(c);
+ else
+ c = '_';
+ if (i < PATH_MAX)
+ path[i++] = c;
+ }
+
+ /* copy random template */
+ s = ".XXXXXX";
+ for (j = 0; s[j]; ++j)
+ if (i < PATH_MAX)
+ path[i++] = s[j];
+
+ /* add nul terminator */
+ if (i + 11 < PATH_MAX)
+ path[i] = 0;
+ else
+ {
+ DB (DB_JOBS, (_("Creating TMPDIR in %s for %s is too long\n"),
+ tmp, file->name));
+ return 0;
+ }
+
+ /* create temp directory with random data */
+ e = errno;
+ if (!(tmpdir = mkdtemp (path)) && errno == ENOENT)
+ {
+ /* create parent directories if necessary */
+ char *dir;
+ errno = e;
+ dir = xstrdup (path);
+ if (!makedirs (dirname (dir), 0700))
+ tmpdir = mkdtemp (path);
+ free (dir);
+ }
+
+ /* returned string must be free'd */
+ if (tmpdir)
+ {
+ tmpdir = xstrdup (tmpdir);
+ DB (DB_JOBS, (_("Created TMPDIR %s\n"), path));
+ }
+ else
+ DB (DB_JOBS, (_("Creating TMPDIR %s failed %s\n"),
+ path, strerror (errno)));
+
+ return tmpdir;
+}
+
+void
+delete_tmpdir (struct child *c)
+{
+ if (!c->tmpdir) return;
+
+ DB (DB_JOBS, (_("Deleting TMPDIR %s\n"), c->tmpdir));
+
+ if (!isdirectory (c->tmpdir))
+ DB (DB_JOBS, (_("Warning TMPDIR %s doesn't exist\n"), c->tmpdir));
+
+ errno = 0;
+ if (rmrf (c->tmpdir))
+ DB (DB_JOBS, (_("Deleting TMPDIR %s failed %s\n"),
+ c->tmpdir, strerror(errno)));
+
+ free (c->tmpdir);
+ c->tmpdir = 0;
+}
+
+
/* Handle a dead child. This handler may or may not ever be installed.
If we're using the jobserver feature without pselect(), we need it.
@@ -642,6 +754,7 @@ reap_children (int block, int err)
}
if (exit_sig != 0 || delete_on_error)
delete_child_targets (c);
+ delete_tmpdir (c);
}
else
{
@@ -693,10 +806,13 @@ reap_children (int block, int err)
delete_child_targets (c);
}
else
- /* There are no more commands. We got through them all
- without an unignored error. Now the target has been
- successfully updated. */
- c->file->update_status = us_success;
+ {
+ /* There are no more commands. We got through them all
+ without an unignored error. Now the target has been
+ successfully updated. */
+ c->file->update_status = us_success;
+ delete_tmpdir (c);
+ }
}
/* When we get here, all the commands for c->file are finished. */
@@ -800,6 +916,7 @@ free_child (struct child *child)
free (child->environment);
}
+ free (child->tmpdir);
free (child->cmd_name);
free (child);
}
@@ -1133,10 +1250,12 @@ start_waiting_job (struct child *c)
void
new_job (struct file *file)
{
+
struct commands *cmds = file->cmds;
+ struct variable *var;
struct child *c;
- char **lines;
unsigned int i;
+ char **lines;
/* Let any previously decided-upon jobs that are waiting
for the load to go down start before this new one. */
@@ -1157,6 +1276,14 @@ new_job (struct file *file)
c->file = file;
c->sh_batch_file = NULL;
+ /* [jart] manage temporary directories per rule */
+ if ((c->tmpdir = new_tmpdir (get_tmpdir (file), file)))
+ {
+ var = define_variable_for_file ("TMPDIR", 6, c->tmpdir,
+ o_override, 0, file);
+ var->export = v_export;
+ }
+
/* Cache dontcare flag because file->dontcare can be changed once we
return. Check dontcare inheritance mechanism for details. */
c->dontcare = file->dontcare;
@@ -1473,83 +1600,12 @@ load_too_high (void)
OK, I'm not sure exactly how to handle that, but for sure we need to
clamp this value at the number of cores before this can be enabled.
*/
-#define PROC_FD_INIT -1
- static int proc_fd = PROC_FD_INIT;
-
double load, guess;
time_t now;
-#ifdef WINDOWS32
- /* sub_proc.c is limited in the number of objects it can wait for. */
- if (process_table_full ())
- return 1;
-#endif
-
if (max_load_average < 0)
return 0;
- /* If we haven't tried to open /proc/loadavg, try now. */
-#define LOADAVG "/proc/loadavg"
- if (proc_fd == -2)
- {
- EINTRLOOP (proc_fd, open (LOADAVG, O_RDONLY));
- if (proc_fd < 0)
- DB (DB_JOBS, ("Using system load detection method.\n"));
- else
- {
- DB (DB_JOBS, ("Using " LOADAVG " load detection method.\n"));
- fd_noinherit (proc_fd);
- }
- }
-
- /* Try to read /proc/loadavg if we managed to open it. */
- if (proc_fd >= 0)
- {
- int r;
-
- EINTRLOOP (r, lseek (proc_fd, 0, SEEK_SET));
- if (r >= 0)
- {
-#define PROC_LOADAVG_SIZE 64
- char avg[PROC_LOADAVG_SIZE+1];
-
- EINTRLOOP (r, read (proc_fd, avg, PROC_LOADAVG_SIZE));
- if (r >= 0)
- {
- const char *p;
-
- /* The syntax of /proc/loadavg is:
- <1m> <5m> <15m> /
- The load is considered too high if there are more jobs
- running than the requested average. */
-
- avg[r] = '\0';
- p = strchr (avg, ' ');
- if (p)
- p = strchr (p+1, ' ');
- if (p)
- p = strchr (p+1, ' ');
-
- if (p && ISDIGIT(p[1]))
- {
- int cnt = atoi (p+1);
- DB (DB_JOBS, ("Running: system = %d / make = %u (max requested = %f)\n",
- cnt, job_slots_used, max_load_average));
- return (double)cnt > max_load_average;
- }
-
- DB (DB_JOBS, ("Failed to parse " LOADAVG ": %s\n", avg));
- }
- }
-
- /* If we 𝑔𝑜𝑡 𝑒𝑟𝑒, something went wrong. Give up on this method. */
- if (r < 0)
- DB (DB_JOBS, ("Failed to read " LOADAVG ": %s\n", strerror (errno)));
-
- close (proc_fd);
- proc_fd = -1;
- }
-
/* Find the real system load average. */
make_access ();
if (getloadavg (&load, 1) != 1)
@@ -1622,7 +1678,7 @@ start_waiting_jobs (void)
bool
-GetPermPrefix (const char *path, char out_perm[5], const char **out_path)
+get_perm_prefix (const char *path, char out_perm[5], const char **out_path)
{
int c, n;
for (n = 0;;)
@@ -1656,7 +1712,7 @@ Unveil (const char *path, const char *perm)
char permprefix[5];
/* if path is like `rwcx:o/tmp` then `rwcx` will override perm */
- if (path && GetPermPrefix (path, permprefix, &path))
+ if (path && get_perm_prefix (path, permprefix, &path))
perm = permprefix;
fp[0] = 0;
@@ -1665,6 +1721,8 @@ Unveil (const char *path, const char *perm)
(fp[1] = tilde_expand ((fp[0] = xstrdup (path)))))
path = fp[1];
+ DB (DB_JOBS, (_("Unveiling %s with permissions %s\n"), path, perm));
+
e = errno;
if (unveil (path, perm) != -1)
{
@@ -1690,7 +1748,7 @@ Unveil (const char *path, const char *perm)
}
int
-UnveilVariable (const struct variable *var)
+unveil_variable (const struct variable *var)
{
char *val, *tok, *state, *start;
if (!var) return 0;
@@ -1759,7 +1817,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
if (fderr != FD_STDERR)
EINTRLOOP (r, dup2 (fderr, FD_STDERR));
- g_strict = Vartoi (lookup_variable (STRING_SIZE_TUPLE(".STRICT")));
+ g_strict = Vartoi (lookup_variable (STRING_SIZE_TUPLE (".STRICT")));
intptr_t loc = (intptr_t)child; /* we can cast if it's on the heap ;_; */
if (!(GetStackAddr() < loc && loc < GetStackAddr() + GetStackSize())) {
@@ -1798,6 +1856,8 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
errno = 0;
if (sandboxed)
{
+ DB (DB_JOBS, (_("Sandboxing %s\n"), c->file->name));
+
if (!g_strict && argv[0][0] == '/' && IsDynamicExecutable (argv[0]))
{
/*
@@ -1854,10 +1914,14 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
/* unveil executable */
RETURN_ON_ERROR (Unveil (argv[0], "rx"));
+ /* unveil temporary directory */
+ if (c->tmpdir)
+ RETURN_ON_ERROR (Unveil (c->tmpdir, "rwcx"));
+
+ /* unveil lazy mode files */
if (!g_strict)
{
RETURN_ON_ERROR (Unveil ("/tmp", "rwc"));
- RETURN_ON_ERROR (Unveil ("o/tmp", "rwcx"));
RETURN_ON_ERROR (Unveil ("/dev/zero", "r"));
RETURN_ON_ERROR (Unveil ("/dev/null", "rw"));
RETURN_ON_ERROR (Unveil ("/dev/full", "rw"));
@@ -1893,6 +1957,8 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
c->file->name, strerror (errno));
return -1;
}
+ DB (DB_JOBS, (_("Unveiling %s with permissions %s\n"),
+ c->file->name, "rwx"));
if (unveil (c->file->name, "rwx") && errno != ENOSYS)
{
OSS (error, NILF, "%s: unveil target failed %s",
@@ -1915,17 +1981,17 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
/* unveil explicit .UNVEIL entries */
RETURN_ON_ERROR
- (UnveilVariable
+ (unveil_variable
(lookup_variable
(STRING_SIZE_TUPLE (".UNVEIL"))));
RETURN_ON_ERROR
- (UnveilVariable
+ (unveil_variable
(lookup_variable_in_set
(STRING_SIZE_TUPLE (".UNVEIL"),
c->file->variables->set)));
if (c->file->pat_variables)
RETURN_ON_ERROR
- (UnveilVariable
+ (unveil_variable
(lookup_variable_in_set
(STRING_SIZE_TUPLE (".UNVEIL"),
c->file->pat_variables->set)));
diff --git a/third_party/make/job.h b/third_party/make/job.h
index 870d0b98a..1219258a6 100644
--- a/third_party/make/job.h
+++ b/third_party/make/job.h
@@ -41,6 +41,7 @@ struct child
struct file *file; /* File being remade. */
+ char *tmpdir; /* Temporary directory */
char *sh_batch_file; /* Script file for shell commands */
char **command_lines; /* Array of variable-expanded cmd lines. */
char *command_ptr; /* Ptr into command_lines[command_line]. */
diff --git a/third_party/make/main.c b/third_party/make/main.c
index faab247fa..5071c7c4a 100644
--- a/third_party/make/main.c
+++ b/third_party/make/main.c
@@ -45,6 +45,8 @@ this program. If not, see . */
#include "libc/runtime/runtime.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/runtime.h"
+#include "libc/log/log.h"
+#include "libc/log/log.h"
#include "third_party/make/getopt.h"
STATIC_STACK_SIZE(0x200000); // 2mb stack
@@ -355,6 +357,10 @@ static const char *const usage[] =
Consider FILE to be infinitely new.\n"),
N_("\
--warn-undefined-variables Warn when an undefined variable is referenced.\n"),
+ N_("\
+ --strace Log system calls.\n"),
+ N_("\
+ --ftrace Log function calls.\n"),
NULL
};
@@ -1101,11 +1107,7 @@ main (int argc, char **argv, char **envp)
/* Figure out where we are. */
-#ifdef WINDOWS32
- if (getcwd_fs (current_directory, GET_PATH_MAX) == 0)
-#else
if (getcwd (current_directory, GET_PATH_MAX) == 0)
-#endif
{
#ifdef HAVE_GETCWD
perror_with_name ("getcwd", "");
@@ -2980,7 +2982,7 @@ print_version (void)
/* Do it only once. */
return;
- printf ("%sLandlock Make 1.0.1 (GNU Make %s)\n", precede, version_string);
+ printf ("%sLandlock Make 1.1.1 (GNU Make %s)\n", precede, version_string);
if (!remote_description || *remote_description == '\0')
printf (_("%sBuilt for %s\n"), precede, make_host);
@@ -2993,6 +2995,8 @@ print_version (void)
year, and none of the rest of it should be translated (including the
word "Copyright"), so it hardly seems worth it. */
+ printf ("%sCopyright (C) 2022 Justine Alexandra Roberts Tunney\n",
+ precede);
printf ("%sCopyright (C) 1988-2020 Free Software Foundation, Inc.\n",
precede);
diff --git a/third_party/make/make.mk b/third_party/make/make.mk
index 3df09c3db..b034c1cf8 100644
--- a/third_party/make/make.mk
+++ b/third_party/make/make.mk
@@ -65,7 +65,6 @@ THIRD_PARTY_MAKE_SRCS_LIB = \
third_party/make/fcntl.c \
third_party/make/fd-hook.c \
third_party/make/findprog-in.c \
- third_party/make/getloadavg.c \
third_party/make/getprogname.c \
third_party/make/stripslash.c \
third_party/make/unistd.c \
diff --git a/third_party/mbedtls/test/test.mk b/third_party/mbedtls/test/test.mk
index d7acf12b5..177828317 100644
--- a/third_party/mbedtls/test/test.mk
+++ b/third_party/mbedtls/test/test.mk
@@ -408,6 +408,7 @@ o/$(MODE)/third_party/mbedtls/test/test_suite_cipher.padding.com.dbg: \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
+o/$(MODE)/third_party/mbedtls/test/test_suite_ctr_drbg.com.runs: private .UNVEIL += rwc:o/tmp
o/$(MODE)/third_party/mbedtls/test/test_suite_ctr_drbg.com: o/$(MODE)/third_party/mbedtls/test/test_suite_ctr_drbg.com.dbg
o/$(MODE)/third_party/mbedtls/test/test_suite_ctr_drbg.com.dbg: \
$(THIRD_PARTY_MBEDTLS_TEST_DEPS) \
@@ -586,6 +587,7 @@ o/$(MODE)/third_party/mbedtls/test/test_suite_hkdf.com.dbg: \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
+o/$(MODE)/third_party/mbedtls/test/test_suite_hmac_drbg.misc.com.runs: private .UNVEIL += rwc:o/tmp
o/$(MODE)/third_party/mbedtls/test/test_suite_hmac_drbg.misc.com: o/$(MODE)/third_party/mbedtls/test/test_suite_hmac_drbg.misc.com.dbg
o/$(MODE)/third_party/mbedtls/test/test_suite_hmac_drbg.misc.com.dbg: \
$(THIRD_PARTY_MBEDTLS_TEST_DEPS) \
@@ -668,6 +670,7 @@ o/$(MODE)/third_party/mbedtls/test/test_suite_memory_buffer_alloc.com.dbg: \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
+o/$(MODE)/third_party/mbedtls/test/test_suite_mpi.com.runs: private .UNVEIL += rwc:o/tmp
o/$(MODE)/third_party/mbedtls/test/test_suite_mpi.com: o/$(MODE)/third_party/mbedtls/test/test_suite_mpi.com.dbg
o/$(MODE)/third_party/mbedtls/test/test_suite_mpi.com.dbg: \
$(THIRD_PARTY_MBEDTLS_TEST_DEPS) \
diff --git a/third_party/quickjs/quickjs-libc.c b/third_party/quickjs/quickjs-libc.c
index 60123889f..07fb0622f 100644
--- a/third_party/quickjs/quickjs-libc.c
+++ b/third_party/quickjs/quickjs-libc.c
@@ -615,24 +615,6 @@ static JSValue js_std_getenv(JSContext *ctx, JSValueConst this_val,
return JS_NewString(ctx, str);
}
-#if defined(_WIN32)
-static void setenv(const char *name, const char *value, int overwrite)
-{
- char *str;
- size_t name_len, value_len;
- name_len = strlen(name);
- value_len = strlen(value);
- str = malloc(name_len + 1 + value_len + 1);
- memcpy(str, name, name_len);
- str[name_len] = '=';
- memcpy(str + name_len + 1, value, value_len);
- str[name_len + 1 + value_len] = '\0';
- _putenv(str);
- free(str);
-}
-
-#endif /* _WIN32 */
-
static JSValue js_std_setenv(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{