Add MODE=optlinux build mode (#141)

This commit is contained in:
Justine Tunney 2021-10-14 19:36:49 -07:00
parent 226aaf3547
commit 67b5200a0b
111 changed files with 934 additions and 854 deletions

View file

@ -19,9 +19,12 @@
#include "libc/calls/math.h"
#include "libc/macros.internal.h"
/**
* Adds resource usages.
*/
void AddRusage(struct rusage *x, const struct rusage *y) {
AddTimeval(&x->ru_utime, &y->ru_utime);
AddTimeval(&x->ru_stime, &y->ru_stime);
x->ru_utime = AddTimeval(x->ru_utime, y->ru_utime);
x->ru_stime = AddTimeval(x->ru_stime, y->ru_stime);
x->ru_maxrss = MAX(x->ru_maxrss, y->ru_maxrss);
x->ru_ixrss += y->ru_ixrss;
x->ru_idrss += y->ru_idrss;

32
libc/calls/addtimespec.c Normal file
View file

@ -0,0 +1,32 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/math.h"
/**
* Adds two microsecond timestamps.
*/
struct timespec AddTimespec(struct timespec x, struct timespec y) {
x.tv_sec += y.tv_sec;
x.tv_nsec += y.tv_nsec;
if (x.tv_nsec >= 10000000000) {
x.tv_nsec -= 10000000000;
x.tv_sec += 1;
}
return x;
}

View file

@ -18,11 +18,15 @@
*/
#include "libc/calls/math.h"
void AddTimeval(struct timeval *x, const struct timeval *y) {
x->tv_sec += y->tv_sec;
x->tv_usec += y->tv_usec;
if (x->tv_usec >= 1000000) {
x->tv_usec -= 1000000;
x->tv_sec += 1;
/**
* Adds two microsecond timestamps.
*/
struct timeval AddTimeval(struct timeval x, struct timeval y) {
x.tv_sec += y.tv_sec;
x.tv_usec += y.tv_usec;
if (x.tv_usec >= 1000000) {
x.tv_usec -= 1000000;
x.tv_sec += 1;
}
return x;
}

View file

@ -19,6 +19,7 @@
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/sysdebug.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sysv/errfuns.h"
@ -39,9 +40,16 @@
* @see fchmod()
*/
int fchmodat(int dirfd, const char *path, uint32_t mode, int flags) {
int rc;
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
return -1; /* TODO(jart): implement me */
rc = -1; /* TODO(jart): implement me */
} else if (!IsWindows()) {
rc = sys_fchmodat(dirfd, path, mode, flags);
} else {
rc = sys_fchmodat_nt(dirfd, path, mode, flags);
}
return sys_fchmodat(dirfd, path, mode, flags);
SYSDEBUG("fchmodat(%d, %s, %o, %d) -> %d %s", (long)dirfd, path, mode, flags,
rc != -1 ? "" : strerror(errno));
return rc;
}

View file

@ -44,30 +44,35 @@
*/
bool fileexists(const char *path) {
int e;
bool res;
union metastat st;
struct ZiposUri zipname;
uint16_t path16[PATH_MAX];
e = errno;
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
e = errno;
if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) {
return true;
res = true;
} else {
errno = e;
return false;
res = false;
}
} else if (IsMetal()) {
return false;
res = false;
} else if (!IsWindows()) {
e = errno;
if (__sys_fstatat(AT_FDCWD, path, &st, 0) != -1) {
return true;
res = true;
} else {
errno = e;
return false;
res = false;
}
} else if (__mkntpath(path, path16) != -1) {
res = GetFileAttributes(path16) != -1u;
} else {
if (__mkntpath(path, path16) == -1) return -1;
return GetFileAttributes(path16) != -1u;
res = false;
}
SYSDEBUG("fileexists(%s) -> %s %s", path, res ? "true" : "false",
res ? "" : strerror(errno));
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
errno = e;
}
return res;
}

View file

@ -21,6 +21,9 @@
#include "libc/calls/weirdtypes.h"
#include "libc/str/str.h"
/**
* Convert pathname and a project ID to System V IPC key.
*/
int ftok(const char *path, int id) {
struct stat st;
if (stat(path, &st) == -1) return -1;

View file

@ -16,8 +16,12 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/runtime/runtime.h"
#define ToUpper(c) \
(IsWindows() && (c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c))
/**
* Returns value of environment variable, or NULL if not found.
*
@ -35,11 +39,11 @@ char *getenv(const char *s) {
}
break;
}
if (s[j] != p[i][j]) {
if (ToUpper(s[j]) != ToUpper(p[i][j])) {
break;
}
}
}
}
return NULL;
return 0;
}

View file

@ -21,6 +21,7 @@
#include "libc/calls/internal.h"
#include "libc/calls/struct/metastat.internal.h"
#include "libc/calls/struct/stat.h"
#include "libc/calls/sysdebug.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
@ -43,29 +44,34 @@
* @see isregularfile(), issymlink(), ischardev()
*/
bool isdirectory(const char *path) {
int rc, e;
int e;
bool res;
union metastat st;
struct ZiposUri zipname;
e = errno;
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
e = errno;
if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) {
return S_ISDIR(st.cosmo.st_mode);
res = S_ISDIR(st.cosmo.st_mode);
} else {
errno = e;
return false;
res = false;
}
} else if (IsMetal()) {
return false;
res = false;
} else if (!IsWindows()) {
e = errno;
if (__sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1) {
return S_ISDIR(METASTAT(st, st_mode));
res = S_ISDIR(METASTAT(st, st_mode));
} else {
errno = e;
return false;
res = false;
}
} else {
return isdirectory_nt(path);
res = isdirectory_nt(path);
}
SYSDEBUG("isdirectory(%s) -> %s %s", path, res ? "true" : "false",
res ? "" : strerror(errno));
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
errno = e;
}
return res;
}

View file

@ -1,11 +1,13 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_MATH_H_
#define COSMOPOLITAN_LIBC_CALLS_MATH_H_
#include "libc/calls/struct/rusage.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timeval.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
void AddTimeval(struct timeval *, const struct timeval *);
struct timeval AddTimeval(struct timeval, struct timeval);
struct timespec AddTimespec(struct timespec, struct timespec);
void AddRusage(struct rusage *, const struct rusage *);
COSMOPOLITAN_C_END_

View file

@ -29,10 +29,13 @@
#include "libc/str/utf16.h"
#include "libc/sysv/errfuns.h"
#define ToUpper(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c))
static noasan int CompareStrings(const char *l, const char *r) {
int a, b;
size_t i = 0;
while (l[i] == r[i] && r[i]) ++i;
return (l[i] & 0xff) - (r[i] & 0xff);
while ((a = ToUpper(l[i] & 255)) == (b = ToUpper(r[i] & 255)) && r[i]) ++i;
return a - b;
}
static noasan void InsertString(char **a, size_t i, char *s) {
@ -56,6 +59,7 @@ static noasan void InsertString(char **a, size_t i, char *s) {
*/
textwindows noasan int mkntenvblock(char16_t envvars[ARG_MAX],
char *const envp[], const char *extravar) {
bool v;
char *t;
axdx_t rc;
uint64_t w;
@ -68,6 +72,7 @@ textwindows noasan int mkntenvblock(char16_t envvars[ARG_MAX],
if (extravar) InsertString(vars, n++, extravar);
for (k = i = 0; i < n; ++i) {
j = 0;
v = false;
do {
x = vars[i][j++] & 0xff;
if (x >= 0200) {
@ -83,6 +88,13 @@ textwindows noasan int mkntenvblock(char16_t envvars[ARG_MAX],
}
}
}
if (!v) {
if (x != '=') {
x = ToUpper(x);
} else {
v = true;
}
}
w = EncodeUtf16(x);
do {
envvars[k++] = w & 0xffff;

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/calls/sysdebug.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/str/str.h"
@ -59,12 +58,5 @@ int sys_openat(int dirfd, const char *file, int flags, unsigned mode) {
d = sys_openat(dirfd, file, flags, mode);
}
}
if (d != -1) {
SYSDEBUG("sys_openat(%d, %s, %d, %d) -> %d", (long)dirfd, file, flags,
(flags & (O_CREAT | O_TMPFILE)) ? mode : 0, d);
} else {
SYSDEBUG("sys_openat(%d, %s, %d, %d) -> %s", (long)dirfd, file, flags,
(flags & (O_CREAT | O_TMPFILE)) ? mode : 0, strerror(errno));
}
return d;
}

View file

@ -19,6 +19,7 @@
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/sysdebug.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/log/log.h"
@ -43,24 +44,37 @@
* @vforksafe
*/
int openat(int dirfd, const char *file, int flags, ...) {
int rc;
va_list va;
unsigned mode;
struct ZiposUri zipname;
va_start(va, flags);
mode = va_arg(va, unsigned);
va_end(va);
if (!file) return efault();
if (IsAsan() && !__asan_is_valid(file, 1)) return efault();
if (__isfdkind(dirfd, kFdZip)) return einval(); /* TODO(jart): implement me */
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(file, &zipname) != -1) {
if (__vforked) return eopnotsupp();
if (dirfd != AT_FDCWD) return eopnotsupp();
return weaken(__zipos_open)(&zipname, flags, mode);
} else if (!IsWindows() && !IsMetal()) {
return sys_openat(dirfd, file, flags, mode);
} else if (IsMetal()) {
return sys_openat_metal(dirfd, file, flags, mode);
if (file && (!IsAsan() || __asan_is_valid(file, 1))) {
if (!__isfdkind(dirfd, kFdZip)) {
if (weaken(__zipos_open) &&
weaken(__zipos_parseuri)(file, &zipname) != -1) {
if (!__vforked && dirfd == AT_FDCWD) {
rc = weaken(__zipos_open)(&zipname, flags, mode);
} else {
rc = eopnotsupp(); /* TODO */
}
} else if (!IsWindows() && !IsMetal()) {
rc = sys_openat(dirfd, file, flags, mode);
} else if (IsMetal()) {
rc = sys_openat_metal(dirfd, file, flags, mode);
} else {
rc = sys_open_nt(dirfd, file, flags, mode);
}
} else {
rc = eopnotsupp(); /* TODO */
}
} else {
return sys_open_nt(dirfd, file, flags, mode);
rc = efault();
}
SYSDEBUG("openat(%d, %s, %d, %d) -> %d %s", (long)dirfd, file, flags,
(flags & (O_CREAT | O_TMPFILE)) ? mode : 0, (long)rc,
rc == -1 ? strerror(errno) : "");
return rc;
}

View file

@ -16,9 +16,16 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sock/internal.h"
#include "libc/sock/sock.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h"
/**
* Reads data from file descriptor.
@ -32,5 +39,22 @@
* @asyncsignalsafe
*/
ssize_t read(int fd, void *buf, size_t size) {
return readv(fd, &(struct iovec){buf, size}, 1);
if (fd >= 0) {
if (IsAsan() && !__asan_is_valid(buf, size)) return efault();
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_read)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle,
&(struct iovec){buf, size}, 1, -1);
} else if (!IsWindows() && !IsMetal()) {
return sys_read(fd, buf, size);
} else if (fd >= g_fds.n) {
return ebadf();
} else if (IsMetal()) {
return sys_readv_metal(g_fds.p + fd, &(struct iovec){buf, size}, 1);
} else {
return sys_readv_nt(g_fds.p + fd, &(struct iovec){buf, size}, 1);
}
} else {
return einval();
}
}

View file

@ -96,7 +96,7 @@ noasan int sigaltstack(const struct sigaltstack *neu, struct sigaltstack *old) {
return enosys();
}
if ((rc = sys_sigaltstack(a, b)) != -1) {
if (old) {
if (IsBsd() && old) {
sigaltstack2linux(old, &bsd);
}
return 0;

View file

@ -17,9 +17,13 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/weaken.h"
#include "libc/dce.h"
#include "libc/mem/internal.h"
#include "libc/runtime/runtime.h"
#define ToUpper(c) \
(IsWindows() && (c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c))
/**
* Removes environment variable.
*/
@ -42,7 +46,7 @@ int unsetenv(const char *s) {
}
break;
}
if (s[j] != p[i][j]) {
if (ToUpper(s[j]) != ToUpper(p[i][j])) {
break;
}
}

View file

@ -16,8 +16,14 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/weaken.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sock/sock.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h"
/**
* Writes data to file descriptor.
@ -31,5 +37,22 @@
* @asyncsignalsafe
*/
ssize_t write(int fd, const void *buf, size_t size) {
return writev(fd, &(struct iovec){buf, size}, 1);
if (fd >= 0) {
if (IsAsan() && !__asan_is_valid(buf, size)) return efault();
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_write)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle,
&(struct iovec){buf, size}, 1, -1);
} else if (!IsWindows() && !IsMetal()) {
return sys_write(fd, buf, size);
} else if (fd >= g_fds.n) {
return ebadf();
} else if (IsMetal()) {
return sys_writev_metal(g_fds.p + fd, &(struct iovec){buf, size}, 1);
} else {
return sys_writev_nt(g_fds.p + fd, &(struct iovec){buf, size}, 1);
}
} else {
return einval();
}
}