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:
Justine Tunney 2022-08-14 01:21:26 -07:00
parent e1699c5b68
commit d36d0634db
25 changed files with 387 additions and 357 deletions

View file

@ -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"

View file

@ -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;
}

View file

@ -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));

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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++);

View file

@ -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
View 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;
}

View file

@ -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;