mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
Make fixes and improvements
- Fix handling of precision in hex float formatting - Enhance the cocmd interpreter for system() and popen() - Manually ran the Lua unit tests, which are now passing - Let stdio i/o operations happen when file is in error state - We're now saving and restoring xmm in ftrace out of paranoia
This commit is contained in:
parent
95fbdb4f76
commit
41396ff48a
43 changed files with 495 additions and 261 deletions
|
@ -13,7 +13,7 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "third_party/musl/ftw.h"
|
||||
#include "libc/stdio/ftw.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Directory walker example.
|
||||
|
|
|
@ -218,7 +218,9 @@ privileged void _klog(const char *b, size_t n) {
|
|||
__imp_WriteFile(h, b, n, &wrote, 0);
|
||||
__imp_SetLastError(e);
|
||||
} else if (IsMetal()) {
|
||||
if (_weaken(_klog_vga)) _weaken(_klog_vga)(b, n);
|
||||
if (_weaken(_klog_vga)) {
|
||||
_weaken(_klog_vga)(b, n);
|
||||
}
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (;;) {
|
||||
dx = 0x3F8 + UART_LSR;
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
#define _FTW_H
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "third_party/musl/ftw.h"
|
||||
#include "libc/stdio/ftw.h"
|
||||
#endif /* _FTW_H */
|
||||
|
|
|
@ -58,7 +58,7 @@ relegated wontreturn void __die(void) {
|
|||
_Exitr(77);
|
||||
} else if (owner == me) {
|
||||
kprintf("die failed while dying\n");
|
||||
_Exitr(78);
|
||||
_Exitr(79);
|
||||
} else {
|
||||
_Exit1(79);
|
||||
}
|
||||
|
|
|
@ -36,20 +36,18 @@ __nt2sysv:
|
|||
mov %rsp,%rbp
|
||||
// TODO(jart): We should probably find some way to use our own
|
||||
// stack when Windows delivers signals ;_;
|
||||
sub $0x100,%rsp
|
||||
sub $256,%rsp
|
||||
push %rbx
|
||||
push %rdi
|
||||
push %rsi
|
||||
pushf # TODO(jart): Do we need it?
|
||||
lea -0x80(%rbp),%rdi
|
||||
call _savexmm
|
||||
pushf // TODO(jart): Do we need it?
|
||||
call __xmm_save
|
||||
mov %rcx,%rdi
|
||||
mov %rdx,%rsi
|
||||
mov %r8,%rdx
|
||||
mov %r9,%rcx
|
||||
call *%rax
|
||||
lea -0x80(%rbp),%rdi
|
||||
call _loadxmm
|
||||
call __xmm_load
|
||||
popf
|
||||
pop %rsi
|
||||
pop %rdi
|
||||
|
|
|
@ -17,28 +17,48 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
|
||||
// Loads XMM registers from buffer.
|
||||
//
|
||||
// @param %rdi points to &(forcealign(16) uint8_t[256])[128]
|
||||
// @note modern cpus have out-of-order execution engines
|
||||
_loadxmm:
|
||||
__xmm_save:
|
||||
lea -128(%rbp),%rdi
|
||||
.leafprologue
|
||||
movaps -0x80(%rdi),%xmm0
|
||||
movaps -0x70(%rdi),%xmm1
|
||||
movaps -0x60(%rdi),%xmm2
|
||||
movaps -0x50(%rdi),%xmm3
|
||||
movaps -0x40(%rdi),%xmm4
|
||||
movaps -0x30(%rdi),%xmm5
|
||||
movaps -0x20(%rdi),%xmm6
|
||||
movaps -0x10(%rdi),%xmm7
|
||||
movaps 0x00(%rdi),%xmm8
|
||||
movaps 0x10(%rdi),%xmm9
|
||||
movaps 0x20(%rdi),%xmm10
|
||||
movaps 0x30(%rdi),%xmm11
|
||||
movaps 0x40(%rdi),%xmm12
|
||||
movaps 0x50(%rdi),%xmm13
|
||||
movaps 0x60(%rdi),%xmm14
|
||||
movaps 0x70(%rdi),%xmm15
|
||||
movdqu %xmm0,-0x80(%rdi)
|
||||
movdqu %xmm1,-0x70(%rdi)
|
||||
movdqu %xmm2,-0x60(%rdi)
|
||||
movdqu %xmm3,-0x50(%rdi)
|
||||
movdqu %xmm4,-0x40(%rdi)
|
||||
movdqu %xmm5,-0x30(%rdi)
|
||||
movdqu %xmm6,-0x20(%rdi)
|
||||
movdqu %xmm7,-0x10(%rdi)
|
||||
movdqu %xmm8,0x00(%rdi)
|
||||
movdqu %xmm9,0x10(%rdi)
|
||||
movdqu %xmm10,0x20(%rdi)
|
||||
movdqu %xmm11,0x30(%rdi)
|
||||
movdqu %xmm12,0x40(%rdi)
|
||||
movdqu %xmm13,0x50(%rdi)
|
||||
movdqu %xmm14,0x60(%rdi)
|
||||
movdqu %xmm15,0x70(%rdi)
|
||||
.leafepilogue
|
||||
.endfn _loadxmm,globl,hidden
|
||||
.endfn __xmm_save,globl,hidden
|
||||
|
||||
__xmm_load:
|
||||
lea -128(%rbp),%rdi
|
||||
.leafprologue
|
||||
movdqu -0x80(%rdi),%xmm0
|
||||
movdqu -0x70(%rdi),%xmm1
|
||||
movdqu -0x60(%rdi),%xmm2
|
||||
movdqu -0x50(%rdi),%xmm3
|
||||
movdqu -0x40(%rdi),%xmm4
|
||||
movdqu -0x30(%rdi),%xmm5
|
||||
movdqu -0x20(%rdi),%xmm6
|
||||
movdqu -0x10(%rdi),%xmm7
|
||||
movdqu 0x00(%rdi),%xmm8
|
||||
movdqu 0x10(%rdi),%xmm9
|
||||
movdqu 0x20(%rdi),%xmm10
|
||||
movdqu 0x30(%rdi),%xmm11
|
||||
movdqu 0x40(%rdi),%xmm12
|
||||
movdqu 0x50(%rdi),%xmm13
|
||||
movdqu 0x60(%rdi),%xmm14
|
||||
movdqu 0x70(%rdi),%xmm15
|
||||
.leafepilogue
|
||||
.endfn __xmm_load,globl,hidden
|
|
@ -27,15 +27,19 @@
|
|||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/intrin/_getenv.internal.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/ok.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/consts/timer.h"
|
||||
#include "third_party/awk/cmd.h"
|
||||
#include "third_party/getopt/getopt.internal.h"
|
||||
#include "third_party/musl/glob.h"
|
||||
#include "third_party/sed/cmd.h"
|
||||
#include "third_party/tr/cmd.h"
|
||||
|
@ -61,7 +65,6 @@
|
|||
static char *p;
|
||||
static char *q;
|
||||
static char *r;
|
||||
static int envi;
|
||||
static int vari;
|
||||
static size_t n;
|
||||
static char *cmd;
|
||||
|
@ -75,6 +78,9 @@ static const char *prog;
|
|||
static char argbuf[ARG_MAX];
|
||||
static bool unsupported[256];
|
||||
|
||||
static int ShellSpawn(void);
|
||||
static int ShellExec(void);
|
||||
|
||||
static ssize_t Write(int fd, const char *s) {
|
||||
return write(fd, s, strlen(s));
|
||||
}
|
||||
|
@ -87,34 +93,19 @@ static wontreturn void UnsupportedSyntax(unsigned char c) {
|
|||
_Exit(4);
|
||||
}
|
||||
|
||||
static wontreturn void SysExit(int rc, const char *call, const char *thing) {
|
||||
int err;
|
||||
char ibuf[12];
|
||||
const char *estr;
|
||||
err = errno;
|
||||
FormatInt32(ibuf, err);
|
||||
estr = _strerdoc(err);
|
||||
if (!estr) estr = "EUNKNOWN";
|
||||
tinyprint(2, thing, ": ", call, "() failed: ", estr, " (", ibuf, ")\n", NULL);
|
||||
_Exit(rc);
|
||||
}
|
||||
|
||||
static void Open(const char *path, int fd, int flags) {
|
||||
const char *err;
|
||||
close(fd);
|
||||
if (open(path, flags, 0644) == -1) {
|
||||
SysExit(7, "open", path);
|
||||
perror(path);
|
||||
_Exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static wontreturn void Exec(void) {
|
||||
_unassert(args[0][0]);
|
||||
if (!n) {
|
||||
tinyprint(2, prog, ": error: too few args\n", NULL);
|
||||
_Exit(5);
|
||||
}
|
||||
static int SystemExec(void) {
|
||||
execvpe(args[0], args, envs);
|
||||
SysExit(127, "execve", args[0]);
|
||||
perror(args[0]);
|
||||
return (n = 0), 127;
|
||||
}
|
||||
|
||||
static int GetSignalByName(const char *s) {
|
||||
|
@ -133,6 +124,18 @@ static void PutEnv(char **p, const char *kv) {
|
|||
if (!e.s) p[e.i + 1] = 0;
|
||||
}
|
||||
|
||||
static void UnsetEnv(char **p, const char *k) {
|
||||
int i;
|
||||
struct Env e;
|
||||
if ((e = _getenv(p, k)).s) {
|
||||
p[e.i] = 0;
|
||||
for (i = e.i + 1; p[i]; ++i) {
|
||||
p[i - 1] = p[i];
|
||||
p[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Append(int c) {
|
||||
_npassert(q + 1 < argbuf + sizeof(argbuf));
|
||||
*q++ = c;
|
||||
|
@ -163,28 +166,53 @@ static wontreturn void Exit(void) {
|
|||
_Exit(n > 1 ? atoi(args[1]) : 0);
|
||||
}
|
||||
|
||||
static int Waiter(int pid) {
|
||||
int ws;
|
||||
n = 0;
|
||||
if (waitpid(pid, &ws, 0) == -1) {
|
||||
perror("wait");
|
||||
return 1;
|
||||
}
|
||||
if (WIFEXITED(ws)) {
|
||||
return WEXITSTATUS(ws);
|
||||
} else {
|
||||
return 128 + WTERMSIG(ws);
|
||||
}
|
||||
}
|
||||
|
||||
static int Wait(void) {
|
||||
char ibuf[12];
|
||||
int e, rc, ws, pid;
|
||||
int e, ws, pid;
|
||||
if (n > 1) {
|
||||
if (waitpid(atoi(args[1]), &ws, 0) == -1) {
|
||||
SysExit(22, "waitpid", prog);
|
||||
if ((pid = atoi(args[1])) <= 0) {
|
||||
tinyprint(2, "wait: bad pid\n", NULL);
|
||||
return 1;
|
||||
}
|
||||
rc = WIFEXITED(ws) ? WEXITSTATUS(ws) : 128 + WTERMSIG(ws);
|
||||
exitstatus = rc;
|
||||
return Waiter(pid);
|
||||
} else {
|
||||
for (e = errno;;) {
|
||||
for (n = 0, e = errno;;) {
|
||||
if (waitpid(-1, &ws, 0) == -1) {
|
||||
if (errno == ECHILD) {
|
||||
errno = e;
|
||||
break;
|
||||
}
|
||||
SysExit(22, "waitpid", prog);
|
||||
perror("wait");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
rc = 0;
|
||||
return 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const char *GetOptArg(int c, int *i, int j) {
|
||||
if (args[*i][j] == c) {
|
||||
if (args[*i][j + 1]) {
|
||||
return args[*i] + j + 1;
|
||||
} else if (*i + 1 < n) {
|
||||
return args[++*i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Echo(void) {
|
||||
|
@ -229,29 +257,60 @@ static int Read(void) {
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int NeedArgument(const char *prog) {
|
||||
tinyprint(2, prog, ": missing argument\n", NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Cd(void) {
|
||||
const char *s;
|
||||
if ((s = n > 1 ? args[1] : _getenv(envs, "HOME").s)) {
|
||||
if (!chdir(s)) {
|
||||
return 0;
|
||||
} else {
|
||||
tinyprint(2, "chdir: ", s, ": ", _strerdoc(errno), "\n", NULL);
|
||||
perror(s);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
tinyprint(2, "chdir: missing argument\n", NULL);
|
||||
return 1;
|
||||
return NeedArgument("cd");
|
||||
}
|
||||
}
|
||||
|
||||
static int Mkdir(void) {
|
||||
int i = 1;
|
||||
int (*f)(const char *, unsigned) = mkdir;
|
||||
if (n >= 3 && !strcmp(args[1], "-p")) ++i, f = makedirs;
|
||||
int i, j;
|
||||
int mode = 0755;
|
||||
const char *arg;
|
||||
int (*mkdir_impl)(const char *, unsigned) = mkdir;
|
||||
for (i = 1; i < n; ++i) {
|
||||
if (args[i][0] == '-' && args[i][1]) {
|
||||
if (args[i][1] == '-' && !args[i][2]) {
|
||||
++i; // rm -- terminates option parsing
|
||||
break;
|
||||
}
|
||||
for (j = 1; j < args[i][j]; ++j) {
|
||||
if (args[i][j] == 'p') {
|
||||
mkdir_impl = makedirs; // mkdir -p creates parents
|
||||
continue;
|
||||
}
|
||||
if ((arg = GetOptArg('m', &i, j))) {
|
||||
mode = strtol(arg, 0, 8); // mkdir -m OCTAL sets mode
|
||||
break;
|
||||
}
|
||||
char option[2] = {args[i][j]};
|
||||
tinyprint(2, "mkdir", ": illegal option -- ", option, "\n", NULL);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == n) {
|
||||
return NeedArgument("mkdir");
|
||||
}
|
||||
for (; i < n; ++i) {
|
||||
if (f(args[i], 0755)) {
|
||||
tinyprint(2, "mkdir: ", args[i], ": ", _strerdoc(errno), "\n", NULL);
|
||||
return errno;
|
||||
if (mkdir_impl(args[i], mode)) {
|
||||
perror(args[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -267,7 +326,7 @@ static int Kill(void) {
|
|||
}
|
||||
for (; i < n; ++i) {
|
||||
if (kill(atoi(args[i]), sig)) {
|
||||
tinyprint(2, "kill: ", args[i], ": ", _strerdoc(errno), "\n", NULL);
|
||||
perror("kill");
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
|
@ -321,33 +380,52 @@ static int Test(void) {
|
|||
}
|
||||
|
||||
static int Rm(void) {
|
||||
int i;
|
||||
if (n > 1 && args[1][0] != '-') {
|
||||
for (i = 1; i < n; ++i) {
|
||||
if (unlink(args[i])) {
|
||||
tinyprint(2, "rm: ", args[i], ": ", _strerdoc(errno), "\n", NULL);
|
||||
int i, j;
|
||||
bool force = false;
|
||||
for (i = 1; i < n; ++i) {
|
||||
if (args[i][0] == '-' && args[i][1]) {
|
||||
if (args[i][1] == '-' && !args[i][2]) {
|
||||
++i; // rm -- terminates option parsing
|
||||
break;
|
||||
}
|
||||
for (j = 1; j < args[i][j]; ++j) {
|
||||
if (args[i][j] == 'f') {
|
||||
force = true; // rm -f forces removal
|
||||
continue;
|
||||
}
|
||||
char option[2] = {args[i][j]};
|
||||
tinyprint(2, "rm", ": illegal option -- ", option, "\n", NULL);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return -1; // fall back to system rm command
|
||||
}
|
||||
if (i == n) {
|
||||
return NeedArgument("rm");
|
||||
}
|
||||
for (; i < n; ++i) {
|
||||
struct stat st;
|
||||
if ((!force && (lstat(args[i], &st) ||
|
||||
(!S_ISLNK(st.st_mode) && access(args[i], W_OK)))) ||
|
||||
unlink(args[i])) {
|
||||
if (force && errno == ENOENT) continue;
|
||||
perror(args[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Rmdir(void) {
|
||||
int i;
|
||||
if (n > 1 && args[1][0] != '-') {
|
||||
for (i = 1; i < n; ++i) {
|
||||
if (rmdir(args[i])) {
|
||||
tinyprint(2, "rmdir: ", args[i], ": ", _strerdoc(errno), "\n", NULL);
|
||||
return 1;
|
||||
}
|
||||
for (i = 1; i < n; ++i) {
|
||||
if (rmdir(args[i])) {
|
||||
perror(args[i]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return -1; // fall back to system rmdir command
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Touch(void) {
|
||||
|
@ -355,7 +433,7 @@ static int Touch(void) {
|
|||
if (n > 1 && args[1][0] != '-') {
|
||||
for (i = 1; i < n; ++i) {
|
||||
if (touch(args[i], 0644)) {
|
||||
tinyprint(2, "touch: ", args[i], ": ", _strerdoc(errno), "\n", NULL);
|
||||
perror(args[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -365,17 +443,77 @@ static int Touch(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static int Shift(int i) {
|
||||
if (i <= n) {
|
||||
memmove(args, args + i, (n - i + 1) * sizeof(*args));
|
||||
n -= i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Fake(int main(int, char **)) {
|
||||
int exitstatus, ws, pid;
|
||||
if ((pid = fork()) == -1) SysExit(21, "vfork", prog);
|
||||
int pid;
|
||||
if ((pid = fork()) == -1) {
|
||||
perror("fork");
|
||||
return 127;
|
||||
}
|
||||
if (!pid) {
|
||||
// TODO(jart): Maybe nuke stdio state somehow?
|
||||
// TODO(jart): Maybe nuke stdio too?
|
||||
if (_weaken(optind)) {
|
||||
*_weaken(optind) = 1;
|
||||
}
|
||||
environ = envs;
|
||||
exit(main(n, args));
|
||||
}
|
||||
if (waitpid(pid, &ws, 0) == -1) SysExit(22, "waitpid", prog);
|
||||
exitstatus = WIFEXITED(ws) ? WEXITSTATUS(ws) : 128 + WTERMSIG(ws);
|
||||
return n = 0, exitstatus;
|
||||
return Waiter(pid);
|
||||
}
|
||||
|
||||
static int Env(void) {
|
||||
int i, j;
|
||||
const char *arg;
|
||||
char term = '\n';
|
||||
for (i = 1; i < n; ++i) {
|
||||
if (args[i][0] == '-') {
|
||||
if (!args[i][1]) {
|
||||
envs[0] = 0; // env - clears environment
|
||||
continue;
|
||||
}
|
||||
for (j = 1; j < args[i][j]; ++j) {
|
||||
if (args[i][j] == 'i') {
|
||||
envs[0] = 0; // env -i clears environment
|
||||
continue;
|
||||
}
|
||||
if (args[i][j] == '0') {
|
||||
term = 0; // env -0 uses '\0' line separator
|
||||
continue;
|
||||
}
|
||||
if ((arg = GetOptArg('u', &i, j))) {
|
||||
UnsetEnv(envs, arg); // env -u VAR removes variable
|
||||
break;
|
||||
}
|
||||
char option[2] = {args[i][j]};
|
||||
tinyprint(2, "env", ": illegal option -- ", option, "\n", NULL);
|
||||
return 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (strchr(args[i], '=')) {
|
||||
PutEnv(envs, args[i]);
|
||||
} else {
|
||||
Shift(i);
|
||||
return ShellSpawn();
|
||||
}
|
||||
}
|
||||
for (i = 0; envs[i]; ++i) {
|
||||
Write(1, envs[i]);
|
||||
write(1, &term, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Exec(void) {
|
||||
Shift(1);
|
||||
return ShellExec();
|
||||
}
|
||||
|
||||
static int TryBuiltin(void) {
|
||||
|
@ -384,6 +522,8 @@ static int TryBuiltin(void) {
|
|||
if (!strcmp(args[0], "cd")) return Cd();
|
||||
if (!strcmp(args[0], "rm")) return Rm();
|
||||
if (!strcmp(args[0], "[")) return Test();
|
||||
if (!strcmp(args[0], "env")) return Env();
|
||||
if (!strcmp(args[0], "exec")) return Exec();
|
||||
if (!strcmp(args[0], "wait")) return Wait();
|
||||
if (!strcmp(args[0], "echo")) return Echo();
|
||||
if (!strcmp(args[0], "read")) return Read();
|
||||
|
@ -403,43 +543,64 @@ static int TryBuiltin(void) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static wontreturn void Launch(void) {
|
||||
static int ShellExec(void) {
|
||||
int rc;
|
||||
if ((rc = TryBuiltin()) != -1) _Exit(rc);
|
||||
Exec();
|
||||
if ((rc = TryBuiltin()) == -1) {
|
||||
rc = SystemExec();
|
||||
}
|
||||
return (n = 0), rc;
|
||||
}
|
||||
|
||||
static void Pipe(void) {
|
||||
int pid, pfds[2];
|
||||
if (pipe2(pfds, O_CLOEXEC)) SysExit(8, "pipe2", prog);
|
||||
if ((pid = fork()) == -1) SysExit(9, "vfork", prog);
|
||||
if (pipe2(pfds, O_CLOEXEC)) {
|
||||
perror("pipe");
|
||||
_Exit(127);
|
||||
}
|
||||
if ((pid = fork()) == -1) {
|
||||
perror("fork");
|
||||
_Exit(127);
|
||||
}
|
||||
if (!pid) {
|
||||
_unassert(dup2(pfds[1], 1) == 1);
|
||||
// we can't rely on cloexec because builtins
|
||||
if (pfds[0] != 1) _unassert(!close(pfds[0]));
|
||||
if (pfds[1] != 1) _unassert(!close(pfds[1]));
|
||||
Launch();
|
||||
_Exit(ShellExec());
|
||||
}
|
||||
_unassert(!dup2(pfds[0], 0));
|
||||
if (pfds[1]) _unassert(!close(pfds[1]));
|
||||
n = 0;
|
||||
}
|
||||
|
||||
static int Run(void) {
|
||||
int exitstatus, ws, pid;
|
||||
if ((exitstatus = TryBuiltin()) == -1) {
|
||||
if ((pid = vfork()) == -1) SysExit(21, "vfork", prog);
|
||||
if (!pid) Exec();
|
||||
if (waitpid(pid, &ws, 0) == -1) SysExit(22, "waitpid", prog);
|
||||
exitstatus = WIFEXITED(ws) ? WEXITSTATUS(ws) : 128 + WTERMSIG(ws);
|
||||
static int ShellSpawn(void) {
|
||||
int rc, ws, pid;
|
||||
if ((rc = TryBuiltin()) == -1) {
|
||||
switch ((pid = fork())) {
|
||||
case 0:
|
||||
_Exit(SystemExec());
|
||||
default:
|
||||
rc = Waiter(pid);
|
||||
break;
|
||||
case -1:
|
||||
perror("fork");
|
||||
rc = 127;
|
||||
break;
|
||||
}
|
||||
}
|
||||
n = 0;
|
||||
return exitstatus;
|
||||
return (n = 0), rc;
|
||||
}
|
||||
|
||||
static void Async(void) {
|
||||
if ((lastchild = fork()) == -1) SysExit(21, "vfork", prog);
|
||||
if (!lastchild) Launch();
|
||||
static void ShellSpawnAsync(void) {
|
||||
switch ((lastchild = fork())) {
|
||||
case 0:
|
||||
_Exit(ShellExec());
|
||||
default:
|
||||
break;
|
||||
case -1:
|
||||
perror("fork");
|
||||
break;
|
||||
}
|
||||
n = 0;
|
||||
}
|
||||
|
||||
|
@ -535,7 +696,7 @@ static char *Tokenize(void) {
|
|||
if (q > r) {
|
||||
return Finish();
|
||||
} else if (p[1] == '|') {
|
||||
rc = Run();
|
||||
rc = ShellSpawn();
|
||||
if (!rc) {
|
||||
_Exit(0);
|
||||
} else {
|
||||
|
@ -550,7 +711,7 @@ static char *Tokenize(void) {
|
|||
if (q > r) {
|
||||
return Finish();
|
||||
} else {
|
||||
exitstatus = Run();
|
||||
exitstatus = ShellSpawn();
|
||||
t = STATE_WHITESPACE;
|
||||
}
|
||||
} else if (*p == '>') {
|
||||
|
@ -562,7 +723,7 @@ static char *Tokenize(void) {
|
|||
if (q > r) {
|
||||
return Finish();
|
||||
} else if (p[1] == '&') {
|
||||
rc = Run();
|
||||
rc = ShellSpawn();
|
||||
if (!rc) {
|
||||
++p;
|
||||
t = STATE_WHITESPACE;
|
||||
|
@ -570,7 +731,7 @@ static char *Tokenize(void) {
|
|||
_Exit(rc);
|
||||
}
|
||||
} else {
|
||||
Async();
|
||||
ShellSpawnAsync();
|
||||
t = STATE_WHITESPACE;
|
||||
}
|
||||
} else {
|
||||
|
@ -691,7 +852,7 @@ int _cocmd(int argc, char **argv, char **envp) {
|
|||
}
|
||||
|
||||
// copy environment variables
|
||||
envi = 0;
|
||||
int envi = 0;
|
||||
if (envp) {
|
||||
for (; envp[envi]; ++envi) {
|
||||
_npassert(envi + 1 < ARRAYLEN(envs));
|
||||
|
@ -748,5 +909,5 @@ int _cocmd(int argc, char **argv, char **envp) {
|
|||
}
|
||||
}
|
||||
|
||||
Launch();
|
||||
return ShellExec();
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ ftrace_hook:
|
|||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
and $-16,%rsp
|
||||
sub $256,%rsp
|
||||
push %rax
|
||||
push %rdi
|
||||
push %rsi
|
||||
|
@ -44,7 +45,9 @@ ftrace_hook:
|
|||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
call __xmm_save
|
||||
call ftracer
|
||||
call __xmm_load
|
||||
pop %r15
|
||||
pop %r14
|
||||
pop %r13
|
||||
|
@ -67,7 +70,7 @@ ftrace_hook:
|
|||
ldr w16,[x16,#:lo12:__ftrace]
|
||||
cmp w16,0
|
||||
ble 1f
|
||||
stp x29,x30,[sp,-256]!
|
||||
stp x29,x30,[sp,-384]!
|
||||
mov x29,sp
|
||||
|
||||
stp x0,x1,[sp,16]
|
||||
|
@ -84,6 +87,10 @@ ftrace_hook:
|
|||
stp x24,x25,[sp,208]
|
||||
stp x26,x27,[sp,224]
|
||||
str x28,[sp,240]
|
||||
stp q0,q1,[sp,256]
|
||||
stp q2,q3,[sp,288]
|
||||
stp q4,q5,[sp,320]
|
||||
stp q6,q7,[sp,352]
|
||||
|
||||
bl ftracer
|
||||
|
||||
|
@ -101,8 +108,12 @@ ftrace_hook:
|
|||
ldp x24,x25,[sp,208]
|
||||
ldp x26,x27,[sp,224]
|
||||
ldr x28,[sp,240]
|
||||
ldp q0,q1,[sp,256]
|
||||
ldp q2,q3,[sp,288]
|
||||
ldp q4,q5,[sp,320]
|
||||
ldp q6,q7,[sp,352]
|
||||
|
||||
ldp x29,x30,[sp],256
|
||||
ldp x29,x30,[sp],384
|
||||
1: ret
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
|
|
|
@ -18,14 +18,13 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
|
||||
void ftrace_hook(void);
|
||||
|
||||
_Hide int ftrace_stackdigs;
|
||||
|
||||
textstartup int ftrace_install(void) {
|
||||
if (GetSymbolTable()) {
|
||||
ftrace_stackdigs = LengthInt64Thousands(GetStackSize());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
/*-*- 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 2020 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright 2023 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 │
|
||||
|
@ -16,29 +16,6 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
|
||||
// Stores XMM registers to buffer.
|
||||
//
|
||||
// @param %rdi points to &(forcealign(16) uint8_t[256])[128]
|
||||
// @note modern cpus have out-of-order execution engines
|
||||
_savexmm:
|
||||
.leafprologue
|
||||
movaps %xmm0,-0x80(%rdi)
|
||||
movaps %xmm1,-0x70(%rdi)
|
||||
movaps %xmm2,-0x60(%rdi)
|
||||
movaps %xmm3,-0x50(%rdi)
|
||||
movaps %xmm4,-0x40(%rdi)
|
||||
movaps %xmm5,-0x30(%rdi)
|
||||
movaps %xmm6,-0x20(%rdi)
|
||||
movaps %xmm7,-0x10(%rdi)
|
||||
movaps %xmm8,0x00(%rdi)
|
||||
movaps %xmm9,0x10(%rdi)
|
||||
movaps %xmm10,0x20(%rdi)
|
||||
movaps %xmm11,0x30(%rdi)
|
||||
movaps %xmm12,0x40(%rdi)
|
||||
movaps %xmm13,0x50(%rdi)
|
||||
movaps %xmm14,0x60(%rdi)
|
||||
movaps %xmm15,0x70(%rdi)
|
||||
.leafepilogue
|
||||
.endfn _savexmm,globl,hidden
|
||||
int ftrace_stackdigs;
|
|
@ -46,7 +46,6 @@
|
|||
#define DETOUR_SKEW 8
|
||||
#endif
|
||||
|
||||
extern _Hide int ftrace_stackdigs;
|
||||
static struct CosmoFtrace g_ftrace;
|
||||
|
||||
static privileged inline int GetNestingLevelImpl(struct StackFrame *frame) {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern int __pid;
|
||||
extern int ftrace_stackdigs;
|
||||
extern uint32_t __ntconsolemode[3];
|
||||
extern const char v_ntsubsystem[] __attribute__((__weak__));
|
||||
extern const uintptr_t __fini_array_end[] __attribute__((__weak__));
|
||||
|
|
|
@ -114,8 +114,6 @@ void _Exitr(int) libcesque wontreturn;
|
|||
void _Exit1(int) libcesque wontreturn;
|
||||
void _restorewintty(void);
|
||||
void __paginate(int, const char *);
|
||||
void _loadxmm(void *);
|
||||
void _savexmm(void *);
|
||||
long _missingno();
|
||||
/* memory management */
|
||||
void _weakfree(void *);
|
||||
|
|
|
@ -727,7 +727,6 @@ haveinc:
|
|||
* - `%e` double (expo formatting)
|
||||
* - `%f` double (ugly formatting)
|
||||
* - `%a` double (hex formatting)
|
||||
* - `%Lg` long double
|
||||
*
|
||||
* Size Modifiers
|
||||
*
|
||||
|
@ -738,6 +737,7 @@ haveinc:
|
|||
* - `%lx` unsigned long (64-bit hexadecimal)
|
||||
* - `%jd` intmax_t (64-bit)
|
||||
* - `%jjd` int128_t (128-bit)
|
||||
* - `%Lg` long double
|
||||
*
|
||||
* Width Modifiers
|
||||
*
|
||||
|
@ -1251,19 +1251,23 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
__FMT_PUT(*s++);
|
||||
if (prec || (flags & FLAGS_HASH)) __FMT_PUT('.');
|
||||
while (--prec >= 0) {
|
||||
if ((c = *s))
|
||||
if ((c = *s)) {
|
||||
s++;
|
||||
else
|
||||
} else {
|
||||
c = '0';
|
||||
}
|
||||
__FMT_PUT(c);
|
||||
}
|
||||
__FMT_PUT(d);
|
||||
if (decpt < 0) {
|
||||
__FMT_PUT('-');
|
||||
decpt = -decpt;
|
||||
} else
|
||||
} else {
|
||||
__FMT_PUT('+');
|
||||
for (c = 2, k = 10; 10 * k <= decpt; c++, k *= 10) donothing;
|
||||
}
|
||||
for (c = 2, k = 10; 10 * k <= decpt; c++, k *= 10) {
|
||||
donothing;
|
||||
}
|
||||
for (;;) {
|
||||
i1 = decpt / k;
|
||||
__FMT_PUT(i1 + '0');
|
||||
|
@ -1271,7 +1275,9 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
decpt -= i1 * k;
|
||||
decpt *= 10;
|
||||
}
|
||||
while (--width >= 0) __FMT_PUT(' ');
|
||||
while (--width >= 0) {
|
||||
__FMT_PUT(' ');
|
||||
}
|
||||
freedtoa(s0);
|
||||
break;
|
||||
|
||||
|
@ -1321,7 +1327,7 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
}
|
||||
if (sign) __FMT_PUT(sign);
|
||||
__FMT_PUT('0');
|
||||
__FMT_PUT(alphabet[17]);
|
||||
__FMT_PUT(alphabet[17]); // x or X
|
||||
if ((flags & FLAGS_ZEROPAD) && width > 0 && !(flags & FLAGS_LEFT)) {
|
||||
do __FMT_PUT('0');
|
||||
while (--width > 0);
|
||||
|
@ -1329,29 +1335,31 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
i1 = prec1 & 7;
|
||||
k = prec1 >> 3;
|
||||
__FMT_PUT(alphabet[(fpb.bits[k] >> 4 * i1) & 0xf]);
|
||||
if (prec1 > 0 || (flags & FLAGS_HASH)) __FMT_PUT('.');
|
||||
if (prec1 > 0) {
|
||||
prec -= prec1;
|
||||
while (prec1 > 0) {
|
||||
if (--i1 < 0) {
|
||||
if (--k < 0) break;
|
||||
i1 = 7;
|
||||
}
|
||||
__FMT_PUT(alphabet[(fpb.bits[k] >> 4 * i1) & 0xf]);
|
||||
--prec1;
|
||||
}
|
||||
if ((flags & FLAGS_HASH) && prec > 0) {
|
||||
do __FMT_PUT(0);
|
||||
while (--prec > 0);
|
||||
}
|
||||
if (prec1 > 0 || prec > 0) {
|
||||
__FMT_PUT('.');
|
||||
}
|
||||
__FMT_PUT(alphabet[16]);
|
||||
while (prec1 > 0) {
|
||||
if (--i1 < 0) {
|
||||
if (--k < 0) break;
|
||||
i1 = 7;
|
||||
}
|
||||
__FMT_PUT(alphabet[(fpb.bits[k] >> 4 * i1) & 0xf]);
|
||||
--prec1;
|
||||
--prec;
|
||||
}
|
||||
while (prec-- > 0) {
|
||||
__FMT_PUT('0');
|
||||
}
|
||||
__FMT_PUT(alphabet[16]); // p or P
|
||||
if (bex < 0) {
|
||||
__FMT_PUT('-');
|
||||
bex = -bex;
|
||||
} else
|
||||
} else {
|
||||
__FMT_PUT('+');
|
||||
for (c = 1; 10 * c <= bex; c *= 10) donothing;
|
||||
}
|
||||
for (c = 1; 10 * c <= bex; c *= 10) {
|
||||
donothing;
|
||||
}
|
||||
for (;;) {
|
||||
i1 = bex / c;
|
||||
__FMT_PUT('0' + i1);
|
||||
|
@ -1359,7 +1367,9 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
bex -= i1 * c;
|
||||
bex *= 10;
|
||||
}
|
||||
while (--width >= 0) __FMT_PUT(' ');
|
||||
while (--width >= 0) {
|
||||
__FMT_PUT(' ');
|
||||
}
|
||||
break;
|
||||
|
||||
case '%':
|
||||
|
|
|
@ -43,7 +43,7 @@ size_t fread_unlocked(void *buf, size_t stride, size_t count, FILE *f) {
|
|||
ssize_t rc;
|
||||
size_t n, m;
|
||||
struct iovec iov[2];
|
||||
if (f->state) {
|
||||
if (!stride) {
|
||||
return 0;
|
||||
}
|
||||
if ((f->iomode & O_ACCMODE) == O_WRONLY) {
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/musl/ftw.h"
|
||||
#include "libc/stdio/ftw.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
|
@ -45,7 +45,7 @@ size_t fwrite_unlocked(const void *data, size_t stride, size_t count, FILE *f) {
|
|||
size_t n, m;
|
||||
const char *p;
|
||||
struct iovec iov[2];
|
||||
if (f->state) {
|
||||
if (!stride) {
|
||||
return 0;
|
||||
}
|
||||
if ((f->iomode & O_ACCMODE) == O_RDONLY) {
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "third_party/musl/ftw.h"
|
||||
#include "libc/stdio/ftw.h"
|
||||
|
||||
#define PATH_MAXIMUS 4096
|
||||
|
|
@ -203,6 +203,7 @@ typedef const int *wctrans_t;
|
|||
wctrans_t wctrans(const char *);
|
||||
wint_t towctrans(wint_t, wctrans_t);
|
||||
|
||||
int getsubopt(char **, char *const *, char **) paramsnonnull();
|
||||
char *strsignal(int) returnsnonnull libcesque;
|
||||
char *strsignal_r(int, char[hasatleast 15]) returnsnonnull libcesque;
|
||||
char *strerror(int) returnsnonnull dontthrow nocallback;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "libc/errno.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/musl/ftw.h"
|
||||
#include "libc/stdio/ftw.h"
|
||||
|
||||
static int rmrf_callback(const char *fpath, //
|
||||
const struct stat *st, //
|
||||
|
|
|
@ -27,14 +27,24 @@
|
|||
char testlib_enable_tmp_setup_teardown;
|
||||
|
||||
TEST(ftrace, test) {
|
||||
if (!IsOptimized()) return; // TODO(jart): fix me
|
||||
if (1) {
|
||||
// TODO(jart)
|
||||
return;
|
||||
}
|
||||
const char *ftraceasm;
|
||||
testlib_extract("/zip/ftraceasm.txt", "ftraceasm.txt", 0755);
|
||||
ftraceasm = _gc(xslurp("ftraceasm.txt", 0));
|
||||
#ifdef __x86_64__
|
||||
if (strstr(ftraceasm, "%xmm") || strstr(ftraceasm, "%ymm")) {
|
||||
if (strstr(ftraceasm, "%xmm") || //
|
||||
strstr(ftraceasm, "%ymm") || //
|
||||
strstr(ftraceasm, "%zmm")) {
|
||||
#elif defined(__aarch64__)
|
||||
if (strstr(ftraceasm, " d0,") || strstr(ftraceasm, " v0.")) {
|
||||
if (strstr(ftraceasm, "\td0,") || //
|
||||
strstr(ftraceasm, "\tv0.") || //
|
||||
strstr(ftraceasm, "\tq0.") || //
|
||||
strstr(ftraceasm, "\td0,") || //
|
||||
strstr(ftraceasm, "\tv0,") || //
|
||||
strstr(ftraceasm, "\tq0,")) {
|
||||
#else
|
||||
if (0) {
|
||||
#endif
|
||||
|
|
|
@ -133,7 +133,14 @@ static const struct {
|
|||
{"1.23000000000000000002e-320", "%.21Lg",
|
||||
DUBBLE(3bd8, 9b98, c371, 844c, 3f1a)},
|
||||
{"0xap-3", "%.La", DUBBLE(3fff, 9d70, a3d7, a3d, 70a4)},
|
||||
{"0x9.d70a3d70a3d70a4p-3", "%.20La", DUBBLE(3fff, 9d70, a3d7, a3d, 70a4)},
|
||||
// cosmo prints 0x9.d70a3d70a3d70a400000p-3
|
||||
// glibc prints 0x9.d70a3d70a3d70a400000p-3
|
||||
// openbsd prints 0x9.d70a3d70a3d70a400000p-3
|
||||
// apple prints 0x9.d70a3d70a3d70a400000p-3
|
||||
// musl prints 0x1.3ae147ae147ae1480000p+0
|
||||
// freebsd prints 0x1.3ae147ae147ae1480000p+0
|
||||
{"0x9.d70a3d70a3d70a400000p-3", "%.20La",
|
||||
DUBBLE(3fff, 9d70, a3d7, 0a3d, 70a4)},
|
||||
{"0x9.b18ab5df7180b6cp+88", "%La", DUBBLE(405a, 9b18, ab5d, f718, b6c)},
|
||||
{"0xa.fc6a015291b4024p+87", "%La", DUBBLE(4059, afc6, a015, 291b, 4024)},
|
||||
};
|
||||
|
@ -151,8 +158,8 @@ TEST(printf, longdouble) {
|
|||
"TEST FAILED\n"
|
||||
"\t{%`'s, %`'s, DUBBLE(%x, %x, %x, %x, %x)}\n"
|
||||
"\t→%`'s\n",
|
||||
Vx[i].s, Vx[i].f, Vx[i].u.i[0], Vx[i].u.i[1], Vx[i].u.i[2],
|
||||
Vx[i].u.i[3], Vx[i].u.i[4], buf);
|
||||
Vx[i].s, Vx[i].f, Vx[i].u.i[4], Vx[i].u.i[3], Vx[i].u.i[2],
|
||||
Vx[i].u.i[1], Vx[i].u.i[0], buf);
|
||||
testlib_incrementfailed();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -308,6 +308,9 @@ TEST(fmt, e) {
|
|||
}
|
||||
|
||||
TEST(fmt, a) {
|
||||
EXPECT_STREQ("0x0p+0", _gc(xasprintf("%a", 0.)));
|
||||
EXPECT_STREQ("0x0p+0", _gc(xasprintf("%.a", 0.)));
|
||||
EXPECT_STREQ("0x0.000p+0", _gc(xasprintf("%.3a", 0.)));
|
||||
EXPECT_STREQ("0x1.921fb54442d18p+1",
|
||||
_gc(xasprintf("%a", 0x1.921fb54442d1846ap+1)));
|
||||
EXPECT_STREQ("0X1.921FB54442D18P+1",
|
||||
|
|
|
@ -31,10 +31,10 @@ TEST(fread, eofIsSticky) {
|
|||
ASSERT_TRUE(feof(fi));
|
||||
ASSERT_EQ(8, fwrite(b, 1, 8, fo));
|
||||
ASSERT_EQ(0, fflush(fo));
|
||||
ASSERT_EQ(0, fread(b, 1, 8, fi));
|
||||
ASSERT_EQ(4, fread(b, 1, 4, fi));
|
||||
ASSERT_TRUE(feof(fi));
|
||||
clearerr(fi);
|
||||
ASSERT_EQ(8, fread(b, 1, 10, fi));
|
||||
ASSERT_EQ(4, fread(b, 1, 10, fi));
|
||||
ASSERT_TRUE(feof(fi));
|
||||
ASSERT_EQ(0, fseek(fi, 0, SEEK_SET));
|
||||
ASSERT_FALSE(feof(fi));
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/paths.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
@ -29,6 +30,7 @@
|
|||
#include "libc/x/x.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
STATIC_YOINK("_tr");
|
||||
STATIC_YOINK("glob");
|
||||
|
||||
char testlib_enable_tmp_setup_teardown;
|
||||
|
@ -219,8 +221,28 @@ TEST(system, allowsLoneCloseCurlyBrace) {
|
|||
|
||||
TEST(system, glob) {
|
||||
testlib_extract("/zip/echo.com", "echo.com", 0755);
|
||||
ASSERT_EQ(0, WEXITSTATUS(system("./ec*.com aaa")));
|
||||
ASSERT_EQ(0, WEXITSTATUS(system("./ec?o.com aaa")));
|
||||
ASSERT_EQ(0, system("./ec*.com aaa"));
|
||||
ASSERT_EQ(0, system("./ec?o.com aaa"));
|
||||
}
|
||||
|
||||
TEST(system, env) {
|
||||
ASSERT_EQ(0, system("env - a=b c=d >res"));
|
||||
ASSERT_STREQ("a=b\nc=d\n", gc(xslurp("res", 0)));
|
||||
ASSERT_EQ(0, system("env -i -0 a=b c=d >res"));
|
||||
ASSERT_STREQN("a=b\0c=d\0", gc(xslurp("res", 0)), 8);
|
||||
ASSERT_EQ(0, system("env -i0 a=b c=d >res"));
|
||||
ASSERT_STREQN("a=b\0c=d\0", gc(xslurp("res", 0)), 8);
|
||||
ASSERT_EQ(0, system("env - a=b c=d -u a z=g >res"));
|
||||
ASSERT_STREQ("c=d\nz=g\n", gc(xslurp("res", 0)));
|
||||
ASSERT_EQ(0, system("env - a=b c=d -ua z=g >res"));
|
||||
ASSERT_STREQ("c=d\nz=g\n", gc(xslurp("res", 0)));
|
||||
ASSERT_EQ(0, system("env - dope='show' >res"));
|
||||
ASSERT_STREQ("dope=show\n", gc(xslurp("res", 0)));
|
||||
}
|
||||
|
||||
TEST(system, tr) {
|
||||
ASSERT_EQ(0, system("echo hello | tr a-z A-Z >res"));
|
||||
ASSERT_STREQ("HELLO\n", gc(xslurp("res", 0)));
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
|
|
|
@ -42,6 +42,7 @@ TEST_LIBC_STDIO_DIRECTDEPS = \
|
|||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_MBEDTLS \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_TR \
|
||||
THIRD_PARTY_ZLIB \
|
||||
THIRD_PARTY_ZLIB_GZ
|
||||
|
||||
|
|
1
third_party/getopt/getopt.internal.h
vendored
1
third_party/getopt/getopt.internal.h
vendored
|
@ -18,7 +18,6 @@ extern char *optarg;
|
|||
extern int optind, opterr, optopt, optreset;
|
||||
|
||||
int getopt(int, char *const[], const char *) paramsnonnull();
|
||||
int getsubopt(char **, char *const *, char **) paramsnonnull();
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
1
third_party/getopt/getsubopt.c
vendored
1
third_party/getopt/getsubopt.c
vendored
|
@ -29,7 +29,6 @@
|
|||
│ SUCH DAMAGE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/getopt/getopt.internal.h"
|
||||
// clang-format off
|
||||
|
||||
/*
|
||||
|
|
14
third_party/lua/lrepl.c
vendored
14
third_party/lua/lrepl.c
vendored
|
@ -26,6 +26,7 @@
|
|||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#define lua_c
|
||||
#include "third_party/lua/lrepl.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/errno.h"
|
||||
|
@ -44,7 +45,6 @@
|
|||
#include "third_party/lua/cosmo.h"
|
||||
#include "third_party/lua/lauxlib.h"
|
||||
#include "third_party/lua/lprefix.h"
|
||||
#include "third_party/lua/lrepl.h"
|
||||
#include "third_party/lua/lua.h"
|
||||
#include "third_party/lua/lualib.h"
|
||||
// clang-format off
|
||||
|
@ -70,8 +70,8 @@ bool lua_repl_blocking;
|
|||
bool lua_repl_isterminal;
|
||||
linenoiseCompletionCallback *lua_repl_completions_callback;
|
||||
struct linenoiseState *lua_repl_linenoise;
|
||||
const char *lua_progname;
|
||||
static lua_State *globalL;
|
||||
static const char *g_progname;
|
||||
static const char *g_historypath;
|
||||
|
||||
/*
|
||||
|
@ -253,6 +253,7 @@ static ssize_t pushline (lua_State *L, int firstline) {
|
|||
} else {
|
||||
lua_repl_unlock();
|
||||
fputs(prmt, stdout);
|
||||
free(prmt);
|
||||
fflush(stdout);
|
||||
b = linenoiseGetLine(stdin);
|
||||
if (b) {
|
||||
|
@ -328,16 +329,15 @@ static int multiline (lua_State *L) {
|
|||
}
|
||||
|
||||
|
||||
void lua_initrepl(lua_State *L, const char *progname) {
|
||||
void lua_initrepl(lua_State *L) {
|
||||
const char *prompt;
|
||||
lua_repl_lock();
|
||||
g_progname = progname;
|
||||
if ((lua_repl_isterminal = linenoiseIsTerminal())) {
|
||||
linenoiseSetCompletionCallback(lua_readline_completions);
|
||||
linenoiseSetHintsCallback(lua_readline_hint);
|
||||
linenoiseSetFreeHintsCallback(free);
|
||||
prompt = get_prompt(L, 1);
|
||||
if ((g_historypath = linenoiseGetHistoryPath(progname))) {
|
||||
if ((g_historypath = linenoiseGetHistoryPath(lua_progname))) {
|
||||
if (linenoiseHistoryLoad(g_historypath) == -1) {
|
||||
fprintf(stderr, "%r%s: failed to load history: %m%n", g_historypath);
|
||||
free(g_historypath);
|
||||
|
@ -469,7 +469,7 @@ void lua_l_print (lua_State *L) {
|
|||
lua_getglobal(L, "print");
|
||||
lua_insert(L, 1);
|
||||
if (lua_pcall(L, n, 0, 0) != LUA_OK)
|
||||
lua_l_message(g_progname, lua_pushfstring(L, "error calling 'print' (%s)",
|
||||
lua_l_message(lua_progname, lua_pushfstring(L, "error calling 'print' (%s)",
|
||||
lua_tostring(L, -1)));
|
||||
}
|
||||
}
|
||||
|
@ -483,7 +483,7 @@ void lua_l_print (lua_State *L) {
|
|||
int lua_report (lua_State *L, int status) {
|
||||
if (status != LUA_OK) {
|
||||
const char *msg = lua_tostring(L, -1);
|
||||
lua_l_message(g_progname, msg);
|
||||
lua_l_message(lua_progname, msg);
|
||||
lua_pop(L, 1); /* remove message */
|
||||
}
|
||||
return status;
|
||||
|
|
3
third_party/lua/lrepl.h
vendored
3
third_party/lua/lrepl.h
vendored
|
@ -8,6 +8,7 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
extern bool lua_repl_blocking;
|
||||
extern bool lua_repl_isterminal;
|
||||
extern const char *lua_progname;
|
||||
extern struct linenoiseState *lua_repl_linenoise;
|
||||
extern linenoiseCompletionCallback *lua_repl_completions_callback;
|
||||
|
||||
|
@ -16,8 +17,8 @@ void lua_repl_lock(void);
|
|||
void lua_repl_unlock(void);
|
||||
int lua_loadline(lua_State *);
|
||||
void lua_l_print(lua_State *);
|
||||
void lua_initrepl(lua_State *);
|
||||
void lua_sigint(lua_State *, int);
|
||||
void lua_initrepl(lua_State *, const char *);
|
||||
int lua_report(lua_State *, int);
|
||||
int lua_runchunk(lua_State *, int, int);
|
||||
void lua_l_message(const char *, const char *);
|
||||
|
|
20
third_party/lua/lua.main.c
vendored
20
third_party/lua/lua.main.c
vendored
|
@ -57,7 +57,7 @@ Lua 5.4.3 (MIT License)\\n\
|
|||
Copyright 1994–2021 Lua.org, PUC-Rio.\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
STATIC_STACK_SIZE(0x40000);
|
||||
STATIC_STACK_SIZE(0x80000);
|
||||
|
||||
#if !defined(LUA_PROGNAME)
|
||||
#define LUA_PROGNAME "lua"
|
||||
|
@ -71,7 +71,6 @@ STATIC_STACK_SIZE(0x40000);
|
|||
|
||||
|
||||
static lua_State *globalL = NULL;
|
||||
static const char *progname = LUA_PROGNAME;
|
||||
|
||||
|
||||
static bool lua_stdin_is_tty(void) {
|
||||
|
@ -80,7 +79,7 @@ static bool lua_stdin_is_tty(void) {
|
|||
|
||||
|
||||
static void print_usage (const char *badoption) {
|
||||
lua_writestringerror("%s: ", progname);
|
||||
lua_writestringerror("%s: ", lua_progname);
|
||||
if (badoption[1] == 'e' || badoption[1] == 'l')
|
||||
lua_writestringerror("'%s' needs argument\n", badoption);
|
||||
else
|
||||
|
@ -97,7 +96,7 @@ static void print_usage (const char *badoption) {
|
|||
" -- stop handling options\n"
|
||||
" - stop handling options and execute stdin\n"
|
||||
,
|
||||
progname);
|
||||
lua_progname);
|
||||
}
|
||||
|
||||
|
||||
|
@ -304,9 +303,9 @@ static int handle_luainit (lua_State *L) {
|
|||
*/
|
||||
static void doREPL (lua_State *L) {
|
||||
int status;
|
||||
const char *oldprogname = progname;
|
||||
progname = NULL; /* no 'progname' on errors in interactive mode */
|
||||
lua_initrepl(L, LUA_PROGNAME);
|
||||
const char *oldprogname = lua_progname;
|
||||
lua_progname = NULL; /* no 'progname' on errors in interactive mode */
|
||||
lua_initrepl(L);
|
||||
for (;;) {
|
||||
if (lua_repl_isterminal)
|
||||
linenoiseEnableRawMode(0);
|
||||
|
@ -325,7 +324,7 @@ static void doREPL (lua_State *L) {
|
|||
lua_pushfstring(L, "read error: %s", strerror(errno));
|
||||
lua_report(L, status);
|
||||
lua_freerepl();
|
||||
progname = oldprogname;
|
||||
lua_progname = oldprogname;
|
||||
return;
|
||||
}
|
||||
if (status == LUA_OK)
|
||||
|
@ -338,7 +337,7 @@ static void doREPL (lua_State *L) {
|
|||
}
|
||||
lua_freerepl();
|
||||
lua_settop(L, 0); /* clear stack */
|
||||
progname = oldprogname;
|
||||
lua_progname = oldprogname;
|
||||
}
|
||||
|
||||
/* }================================================================== */
|
||||
|
@ -354,7 +353,8 @@ static int pmain (lua_State *L) {
|
|||
int script;
|
||||
int args = collectargs(argv, &script);
|
||||
luaL_checkversion(L); /* check that interpreter has correct version */
|
||||
if (argv[0] && argv[0][0]) progname = argv[0];
|
||||
lua_progname = LUA_PROGNAME;
|
||||
if (argv[0] && argv[0][0]) lua_progname = argv[0];
|
||||
if (args == has_error) { /* bad arg? */
|
||||
print_usage(argv[script]); /* 'script' has index of bad arg. */
|
||||
return 0;
|
||||
|
|
15
third_party/lua/test/files.lua
vendored
15
third_party/lua/test/files.lua
vendored
|
@ -792,9 +792,18 @@ assert(os.date(string.rep("%", 200)) == string.rep("%", 100))
|
|||
local function checkDateTable (t)
|
||||
_G.D = os.date("*t", t)
|
||||
assert(os.time(D) == t)
|
||||
load(os.date([[assert(D.year==%Y and D.month==%m and D.day==%d and
|
||||
D.hour==%H and D.min==%M and D.sec==%S and
|
||||
D.wday==%w+1 and D.yday==%j)]], t))()
|
||||
-- [jart] rewrote test due to octal
|
||||
assert(string.format('%d', D.year) == os.date('%Y', t))
|
||||
assert(string.format('%02d', D.month) == os.date('%m', t))
|
||||
assert(string.format('%02d', D.day) == os.date('%d', t))
|
||||
assert(string.format('%02d', D.hour) == os.date('%H', t))
|
||||
assert(string.format('%02d', D.min) == os.date('%M', t))
|
||||
assert(string.format('%02d', D.sec) == os.date('%S', t))
|
||||
assert(string.format('%d', D.wday - 1) == os.date('%w', t))
|
||||
assert(string.format('%03d', D.yday) == os.date('%j', t))
|
||||
-- load(os.date([[assert(D.year==%Y and D.month==%m and D.day==%d and
|
||||
-- D.hour==%H and D.min==%M and D.sec==%S and
|
||||
-- D.wday==%w+1 and D.yday==%j)]], t))()
|
||||
_G.D = nil
|
||||
end
|
||||
|
||||
|
|
2
third_party/lua/test/literals.lua
vendored
2
third_party/lua/test/literals.lua
vendored
|
@ -25,7 +25,7 @@ assert("\099" == '\99')
|
|||
assert("\099\n" == 'c\10')
|
||||
assert('\0\0\0alo' == '\0' .. '\0\0' .. 'alo')
|
||||
|
||||
assert(010 .. 020 .. -030 == "1020-30")
|
||||
assert(10 .. 20 .. -30 == "1020-30") -- [jart] octal extension
|
||||
|
||||
-- hexadecimal escapes
|
||||
assert("\x00\x05\x10\x1f\x3C\xfF\xe8" == "\0\5\16\31\60\255\232")
|
||||
|
|
2
third_party/lua/test/math.lua
vendored
2
third_party/lua/test/math.lua
vendored
|
@ -401,7 +401,7 @@ assert(tonumber("-0x"..string.rep("f", (intbits//4))) == 1)
|
|||
|
||||
-- testing 'tonumber' with base
|
||||
assert(tonumber(' 001010 ', 2) == 10)
|
||||
assert(tonumber(' 001010 ', 10) == 001010)
|
||||
assert(tonumber(' 001010 ', 10) == 1010) -- [jart] octal extension fix
|
||||
assert(tonumber(' -1010 ', 2) == -10)
|
||||
assert(tonumber('10', 36) == 36)
|
||||
assert(tonumber(' -10 ', 36) == -36)
|
||||
|
|
2
third_party/quickjs/run-test262.c
vendored
2
third_party/quickjs/run-test262.c
vendored
|
@ -33,7 +33,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "third_party/musl/ftw.h"
|
||||
#include "libc/stdio/ftw.h"
|
||||
#include "third_party/quickjs/cutils.h"
|
||||
#include "third_party/quickjs/list.h"
|
||||
#include "third_party/quickjs/quickjs-libc.h"
|
||||
|
|
66
third_party/tr/tr.c
vendored
66
third_party/tr/tr.c
vendored
|
@ -1,34 +1,40 @@
|
|||
/* $OpenBSD: tr.c,v 1.21 2022/02/11 16:09:21 cheloha Exp $ */
|
||||
/* $NetBSD: tr.c,v 1.5 1995/08/31 22:13:48 jtc Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*-*- 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│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ $OpenBSD: tr.c,v 1.21 2022/02/11 16:09:21 cheloha Exp $ │
|
||||
│ $NetBSD: tr.c,v 1.5 1995/08/31 22:13:48 jtc Exp $ │
|
||||
│ │
|
||||
│ Copyright (c) 1988, 1993 │
|
||||
│ The Regents of the University of California. All rights reserved. │
|
||||
│ │
|
||||
│ Redistribution and use in source and binary forms, with or without │
|
||||
│ modification, are permitted provided that the following conditions │
|
||||
│ are met: │
|
||||
│ 1. Redistributions of source code must retain the above copyright │
|
||||
│ notice, this list of conditions and the following disclaimer. │
|
||||
│ 2. Redistributions in binary form must reproduce the above copyright │
|
||||
│ notice, this list of conditions and the following disclaimer in the │
|
||||
│ documentation and/or other materials provided with the distribution. │
|
||||
│ 3. Neither the name of the University nor the names of its contributors │
|
||||
│ may be used to endorse or promote products derived from this software │
|
||||
│ without specific prior written permission. │
|
||||
│ │
|
||||
│ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND │
|
||||
│ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE │
|
||||
│ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE │
|
||||
│ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE │
|
||||
│ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL │
|
||||
│ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS │
|
||||
│ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) │
|
||||
│ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT │
|
||||
│ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY │
|
||||
│ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF │
|
||||
│ SUCH DAMAGE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/bsd.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
|
2
third_party/tr/tr.mk
vendored
2
third_party/tr/tr.mk
vendored
|
@ -42,7 +42,7 @@ $(THIRD_PARTY_TR_A).pkg: \
|
|||
|
||||
o/$(MODE)/third_party/tr/tr.com.dbg: \
|
||||
$(THIRD_PARTY_TR) \
|
||||
o/$(MODE)/third_party/tr/tr.o \
|
||||
o/$(MODE)/third_party/tr/cmd.o \
|
||||
$(CRT) \
|
||||
$(APE_NO_MODIFY_SELF)
|
||||
@$(APELINK)
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/getopt/getopt.internal.h"
|
||||
#include "third_party/musl/ftw.h"
|
||||
#include "libc/stdio/ftw.h"
|
||||
|
||||
#define USAGE \
|
||||
" SRC... DST\n\
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/getopt/getopt.internal.h"
|
||||
#include "third_party/musl/ftw.h"
|
||||
#include "libc/stdio/ftw.h"
|
||||
|
||||
#define USAGE \
|
||||
" SRC... DST\n\
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "libc/sysv/consts/ok.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "third_party/getopt/getopt.internal.h"
|
||||
#include "third_party/musl/ftw.h"
|
||||
#include "libc/stdio/ftw.h"
|
||||
|
||||
#define USAGE \
|
||||
" FILE...\n\
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/musl/ftw.h"
|
||||
#include "libc/stdio/ftw.h"
|
||||
|
||||
const char *prog;
|
||||
char tmpdir[PATH_MAX];
|
||||
|
|
|
@ -140,7 +140,7 @@
|
|||
#include "tool/net/luacheck.h"
|
||||
#include "tool/net/sandbox.h"
|
||||
|
||||
STATIC_STACK_SIZE(0x40000);
|
||||
STATIC_STACK_SIZE(0x80000);
|
||||
|
||||
STATIC_YOINK("zipos");
|
||||
|
||||
|
@ -5462,7 +5462,7 @@ static int LuaInterpreter(lua_State *L) {
|
|||
} else {
|
||||
lua_repl_blocking = true;
|
||||
lua_repl_completions_callback = HandleCompletions;
|
||||
lua_initrepl(GL, "redbean");
|
||||
lua_initrepl(GL);
|
||||
EnableRawMode();
|
||||
for (;;) {
|
||||
status = lua_loadline(L);
|
||||
|
@ -7159,7 +7159,7 @@ static void ReplEventLoop(void) {
|
|||
DEBUGF("ReplEventLoop()");
|
||||
polls[0].fd = 0;
|
||||
lua_repl_completions_callback = HandleCompletions;
|
||||
lua_initrepl(L, "redbean");
|
||||
lua_initrepl(L);
|
||||
EnableRawMode();
|
||||
EventLoop(100);
|
||||
DisableRawMode();
|
||||
|
@ -7174,7 +7174,7 @@ static int WindowsReplThread(void *arg, int tid) {
|
|||
DEBUGF("(repl) started windows thread");
|
||||
lua_repl_blocking = true;
|
||||
lua_repl_completions_callback = HandleCompletions;
|
||||
lua_initrepl(L, "redbean");
|
||||
lua_initrepl(L);
|
||||
EnableRawMode();
|
||||
while (!terminated) {
|
||||
if (HandleReadline() == -1) {
|
||||
|
|
Loading…
Add table
Reference in a new issue