mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Add automatic TMPDIR setup/teardown to GNU Make
We now guarantee TMPDIR will be defined on a per build rule basis. It'll be an absolute path. It'll be secure and unique. It'll be rm -rf'd after the last shell script line in your build rule is executed. If $TMPDIR is already defined, then it'll be created as a subdirectory of your $TMPDIR and then replace the variable with the new definition. The Landlock Make repository will be updated with examples shortly after this change which shall be known as Landlock Make 1.1.1. See #530
This commit is contained in:
parent
e1699c5b68
commit
d36d0634db
25 changed files with 387 additions and 357 deletions
1
Makefile
1
Makefile
|
@ -83,7 +83,6 @@ o/$(MODE): \
|
|||
|
||||
.STRICT = 1
|
||||
.UNVEIL = \
|
||||
rwcx:o/tmp \
|
||||
libc/integral \
|
||||
libc/disclaimer.inc \
|
||||
rx:build/bootstrap \
|
||||
|
|
Binary file not shown.
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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++);
|
||||
|
|
|
@ -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 */
|
105
libc/tinymath/fmod.c
Normal file
105
libc/tinymath/fmod.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
2
third_party/make/config.h
vendored
2
third_party/make/config.h
vendored
|
@ -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 */
|
||||
|
|
4
third_party/make/debug.h
vendored
4
third_party/make/debug.h
vendored
|
@ -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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#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 <http://www.gnu.org/licenses/>. */
|
|||
|
||||
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. */
|
||||
|
|
157
third_party/make/getloadavg.c
vendored
157
third_party/make/getloadavg.c
vendored
|
@ -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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* 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;
|
||||
}
|
320
third_party/make/job.c
vendored
320
third_party/make/job.c
vendored
|
@ -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 <http://www.gnu.org/licenses/>. */
|
|||
#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> <running>/<total> <pid>
|
||||
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)));
|
||||
|
|
1
third_party/make/job.h
vendored
1
third_party/make/job.h
vendored
|
@ -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]. */
|
||||
|
|
14
third_party/make/main.c
vendored
14
third_party/make/main.c
vendored
|
@ -45,6 +45,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#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);
|
||||
|
||||
|
|
1
third_party/make/make.mk
vendored
1
third_party/make/make.mk
vendored
|
@ -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 \
|
||||
|
|
3
third_party/mbedtls/test/test.mk
vendored
3
third_party/mbedtls/test/test.mk
vendored
|
@ -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) \
|
||||
|
|
18
third_party/quickjs/quickjs-libc.c
vendored
18
third_party/quickjs/quickjs-libc.c
vendored
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue