Make improvements

- Expand redbean UNIX module
- Expand redbean documentation
- Ensure Lua copyright is embedded in binary
- Increase the PATH_MAX limit especially on NT
- Use column major sorting for linenoise completions
- Fix some suboptimalities in redbean's new UNIX API
- Figured out right flags for Multics newline in raw mode
This commit is contained in:
Justine Tunney 2022-04-24 09:59:22 -07:00
parent cf3174dc74
commit 2046c0d2ae
305 changed files with 6602 additions and 4221 deletions

View file

@ -173,7 +173,7 @@ char *shortened;
char *cachedcmd;
char *colorflag;
char *originalcmd;
char ccpath[PATH_MAX];
char ccpath[PATH_MAX + 1];
struct stat st;
struct Strings env;
@ -811,7 +811,7 @@ int main(int argc, char *argv[]) {
cmd = argv[optind];
if (!strchr(cmd, '/')) {
if (!(cmd = commandv(cmd, ccpath))) exit(127);
if (!(cmd = commandv(cmd, ccpath, sizeof(ccpath)))) exit(127);
}
s = basename(strdup(cmd));

View file

@ -42,9 +42,9 @@ void CloseCxxFilt(void) {
void SpawnCxxFilt(void) {
int pipefds[2][2];
const char *cxxfilt;
char path[PATH_MAX];
char path[PATH_MAX + 1];
cxxfilt = firstnonnull(emptytonull(getenv("CXXFILT")), "c++filt");
if (commandv(cxxfilt, path)) {
if (commandv(cxxfilt, path, sizeof(path))) {
pipe2(pipefds[0], O_CLOEXEC);
pipe2(pipefds[1], O_CLOEXEC);
if (!(g_cxxfilt.pid = vfork())) {

View file

@ -73,7 +73,7 @@ void elfwriter_yoink(struct ElfWriter *, const char *, int);
void elfwriter_setsection(struct ElfWriter *, struct ElfWriterSymRef, uint16_t);
void elfwriter_zip(struct ElfWriter *, const char *, const char *, size_t,
const void *, size_t, uint32_t, struct timespec,
struct timespec, struct timespec, bool, uint64_t);
struct timespec, struct timespec, bool, uint64_t, size_t);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -136,7 +136,8 @@ static void EmitZipCdirHdr(unsigned char *p, const void *name, size_t namesize,
void elfwriter_zip(struct ElfWriter *elf, const char *symbol, const char *name,
size_t namesize, const void *data, size_t size,
uint32_t mode, struct timespec mtim, struct timespec atim,
struct timespec ctim, bool nocompress, uint64_t imagebase) {
struct timespec ctim, bool nocompress, uint64_t imagebase,
size_t kZipCdirHdrLinkableSizeBootstrap) {
z_stream zs;
uint8_t era;
uint32_t crc;
@ -159,7 +160,7 @@ void elfwriter_zip(struct ElfWriter *elf, const char *symbol, const char *name,
if (S_ISREG(mode) && _istext(data, size)) {
iattrs |= kZipIattrText;
}
commentsize = kZipCdirHdrLinkableSize - (CFILE_HDR_SIZE + namesize);
commentsize = kZipCdirHdrLinkableSizeBootstrap - (CFILE_HDR_SIZE + namesize);
dosmode = !(mode & 0200) ? kNtFileAttributeReadonly : 0;
method = ShouldCompress(name, namesize, data, size, nocompress)
? kZipCompressionDeflate
@ -209,15 +210,15 @@ void elfwriter_zip(struct ElfWriter *elf, const char *symbol, const char *name,
elfwriter_startsection(elf,
gc(xasprintf("%s%s", ZIP_DIRECTORY_SECTION, name)),
SHT_PROGBITS, SHF_ALLOC);
EmitZipCdirHdr((cfile = elfwriter_reserve(elf, kZipCdirHdrLinkableSize)),
name, namesize, crc, era, gflags, method, mtime, mdate, iattrs,
dosmode, mode, compsize, uncompsize, commentsize, mtim, atim,
ctim);
EmitZipCdirHdr(
(cfile = elfwriter_reserve(elf, kZipCdirHdrLinkableSizeBootstrap)), name,
namesize, crc, era, gflags, method, mtime, mdate, iattrs, dosmode, mode,
compsize, uncompsize, commentsize, mtim, atim, ctim);
elfwriter_appendsym(elf, gc(xasprintf("%s%s", "zip+cdir:", name)),
ELF64_ST_INFO(STB_LOCAL, STT_OBJECT), STV_DEFAULT, 0,
kZipCdirHdrLinkableSize);
kZipCdirHdrLinkableSizeBootstrap);
elfwriter_appendrela(elf, kZipCfileOffsetOffset, lfilesym, R_X86_64_32,
-imagebase);
elfwriter_commit(elf, kZipCdirHdrLinkableSize);
elfwriter_commit(elf, kZipCdirHdrLinkableSizeBootstrap);
elfwriter_finishsection(elf);
}

View file

@ -121,11 +121,11 @@ static void MovqQqPq(struct Machine *m, uint32_t rde) {
static void MovqVdqEqp(struct Machine *m, uint32_t rde) {
memcpy(XmmRexrReg(m, rde), GetModrmRegisterWordPointerRead8(m, rde), 8);
memset(XmmRexrReg(m, rde) + 8, 0, 8);
bzero(XmmRexrReg(m, rde) + 8, 8);
}
static void MovdVdqEd(struct Machine *m, uint32_t rde) {
memset(XmmRexrReg(m, rde), 0, 16);
bzero(XmmRexrReg(m, rde), 16);
memcpy(XmmRexrReg(m, rde), GetModrmRegisterWordPointerRead4(m, rde), 4);
}
@ -135,7 +135,7 @@ static void MovqPqEqp(struct Machine *m, uint32_t rde) {
static void MovdPqEd(struct Machine *m, uint32_t rde) {
memcpy(MmReg(m, rde), GetModrmRegisterWordPointerRead4(m, rde), 4);
memset(MmReg(m, rde) + 4, 0, 4);
bzero(MmReg(m, rde) + 4, 4);
}
static void MovdEdVdq(struct Machine *m, uint32_t rde) {
@ -168,7 +168,7 @@ static void MovntqMqPq(struct Machine *m, uint32_t rde) {
static void MovqVqWq(struct Machine *m, uint32_t rde) {
memcpy(XmmRexrReg(m, rde), GetModrmRegisterXmmPointerRead8(m, rde), 8);
memset(XmmRexrReg(m, rde) + 8, 0, 8);
bzero(XmmRexrReg(m, rde) + 8, 8);
}
static void MovssVpsWps(struct Machine *m, uint32_t rde) {
@ -176,7 +176,7 @@ static void MovssVpsWps(struct Machine *m, uint32_t rde) {
memcpy(XmmRexrReg(m, rde), XmmRexbRm(m, rde), 4);
} else {
memcpy(XmmRexrReg(m, rde), ComputeReserveAddressRead4(m, rde), 4);
memset(XmmRexrReg(m, rde) + 4, 0, 12);
bzero(XmmRexrReg(m, rde) + 4, 12);
}
}
@ -189,7 +189,7 @@ static void MovsdVpsWps(struct Machine *m, uint32_t rde) {
memcpy(XmmRexrReg(m, rde), XmmRexbRm(m, rde), 8);
} else {
memcpy(XmmRexrReg(m, rde), ComputeReserveAddressRead8(m, rde), 8);
memset(XmmRexrReg(m, rde) + 8, 0, 8);
bzero(XmmRexrReg(m, rde) + 8, 8);
}
}
@ -267,7 +267,7 @@ static void MovhpdMqVq(struct Machine *m, uint32_t rde) {
static void MovqWqVq(struct Machine *m, uint32_t rde) {
if (IsModrmRegister(rde)) {
memcpy(XmmRexbRm(m, rde), XmmRexrReg(m, rde), 8);
memset(XmmRexbRm(m, rde) + 8, 0, 8);
bzero(XmmRexbRm(m, rde) + 8, 8);
} else {
memcpy(ComputeReserveAddressWrite8(m, rde), XmmRexrReg(m, rde), 8);
}
@ -275,7 +275,7 @@ static void MovqWqVq(struct Machine *m, uint32_t rde) {
static void Movq2dqVdqNq(struct Machine *m, uint32_t rde) {
memcpy(XmmRexrReg(m, rde), MmRm(m, rde), 8);
memset(XmmRexrReg(m, rde) + 8, 0, 8);
bzero(XmmRexrReg(m, rde) + 8, 8);
}
static void Movdq2qPqUq(struct Machine *m, uint32_t rde) {

View file

@ -113,10 +113,10 @@ char *g_prog;
char *g_runitd;
jmp_buf g_jmpbuf;
uint16_t g_sshport;
char g_ssh[PATH_MAX];
char g_hostname[128];
uint16_t g_runitdport;
volatile bool alarmed;
char g_ssh[PATH_MAX + 1];
int __sys_execve(const char *, char *const[], char *const[]) hidden;
@ -505,7 +505,8 @@ int main(int argc, char *argv[]) {
}
CheckExists((g_runitd = argv[1]));
CheckExists((g_prog = argv[2]));
CHECK_NOTNULL(commandv(firstnonnull(getenv("SSH"), "ssh"), g_ssh));
CHECK_NOTNULL(
commandv(firstnonnull(getenv("SSH"), "ssh"), g_ssh, sizeof(g_ssh)));
if (argc == 3) {
/* hosts list empty */
return 0;

View file

@ -660,7 +660,7 @@ static void Flush(void) {
static const char *GetErrnoName(int x) {
const char *s;
static char buf[16];
if ((s = strerror_short(x))) return s;
if ((s = strerrno(x))) return s;
FormatInt64(buf, x);
return buf;
}
@ -1195,6 +1195,5 @@ wontreturn void StraceMain(int argc, char *argv[]) {
}
int main(int argc, char *argv[]) {
__nomultics = true;
StraceMain(argc, argv);
}

View file

@ -34,6 +34,7 @@
#include "libc/sysv/consts/prot.h"
#include "libc/time/time.h"
#include "libc/x/x.h"
#include "libc/zip.h"
#include "third_party/getopt/getopt.h"
#include "tool/build/lib/elfwriter.h"
#include "tool/build/lib/stripcomponents.h"
@ -48,6 +49,7 @@ int64_t image_base_;
int strip_components_;
const char *path_prefix_;
struct timespec timestamp;
size_t kZipCdirHdrLinkableSizeBootstrap;
wontreturn void PrintUsage(int rc, FILE *f) {
fprintf(f, "%s%s%s\n", "Usage: ", program_invocation_name,
@ -60,7 +62,8 @@ void GetOpts(int *argc, char ***argv) {
int opt;
yoink_ = "__zip_start";
image_base_ = IMAGE_BASE_VIRTUAL;
while ((opt = getopt(*argc, *argv, "?0nhBN:C:P:o:s:y:b:")) != -1) {
kZipCdirHdrLinkableSizeBootstrap = kZipCdirHdrLinkableSize;
while ((opt = getopt(*argc, *argv, "?0nhBL:N:C:P:o:s:y:b:")) != -1) {
switch (opt) {
case 'o':
outpath_ = optarg;
@ -91,6 +94,9 @@ void GetOpts(int *argc, char ***argv) {
case '0':
nocompress_ = true;
break;
case 'L':
kZipCdirHdrLinkableSizeBootstrap = strtoul(optarg, NULL, 0);
break;
case '?':
case 'h':
PrintUsage(EXIT_SUCCESS, stdout);
@ -135,7 +141,8 @@ void ProcessFile(struct ElfWriter *elf, const char *path) {
}
}
elfwriter_zip(elf, name, name, strlen(name), map, st.st_size, st.st_mode,
timestamp, timestamp, timestamp, nocompress_, image_base_);
timestamp, timestamp, timestamp, nocompress_, image_base_,
kZipCdirHdrLinkableSizeBootstrap);
if (st.st_size) CHECK_NE(-1, munmap(map, st.st_size));
close(fd);
}
@ -149,7 +156,8 @@ void PullEndOfCentralDirectoryIntoLinkage(struct ElfWriter *elf) {
}
void CheckFilenameKosher(const char *path) {
CHECK_LE(strlen(path), PATH_MAX);
CHECK_LE(kZipCfileHdrMinSize + strlen(path),
kZipCdirHdrLinkableSizeBootstrap);
CHECK(!startswith(path, "/"));
CHECK(!strstr(path, ".."));
}

View file

@ -151,7 +151,7 @@ int main(int argc, char *argv[])
}
samp = binary ? "bit" : "byte";
memset(ccount, 0, sizeof ccount);
bzero(ccount, sizeof ccount);
/* Initialise for calculations */

View file

@ -58,7 +58,7 @@ bool bitabuilder_setbit(struct BitaBuilder *bb, size_t bit) {
if (i > bb->n) {
n = i + (i >> 2);
if ((p2 = realloc(bb->p, n))) {
memset((char *)p2 + bb->n, 0, n - bb->n);
bzero((char *)p2 + bb->n, n - bb->n);
bb->n = n;
bb->p = p2;
} else {

View file

@ -44,7 +44,7 @@ void disassemblehex(uint8_t *data, size_t size, FILE *f) {
if (i == size) break;
}
fprintf(f, "\t.%s\t", "byte");
memset(glyphs, 0, sizeof(glyphs));
bzero(glyphs, sizeof(glyphs));
}
/* TODO(jart): Fix Emacs */
glyphs[col] = kCp437[ch == '"' || ch == '\\' || ch == '#' ? '.' : ch];

View file

@ -793,6 +793,7 @@
(message header))))
(progn
(define-key prog-mode-map (kbd "C-c C-h") 'cosmo-add-include)
(define-key asm-mode-map (kbd "C-c C-h") 'cosmo-add-include)
(define-key c-mode-base-map (kbd "C-c C-h") 'cosmo-add-include))

View file

@ -34,3 +34,7 @@ function OnHttpRequest()
end
SetHeader('Server', 'redbean!')
end
function Adder(x, y)
return x + y
end

View file

@ -12,7 +12,7 @@ function dosomething(param1, x)
SetHeader('Content-Type', 'text/plain; charset=utf-8')
Write('preprae to crash... now\r\n')
res = x / y
Write(string.format('42 / 0 is %d\r\n', res))
Write('42 / 0 is %d\r\n' % {res})
end
function start(param1)

View file

@ -2,7 +2,7 @@
local function WriteForm(url)
Write('<!doctype html>\r\n')
Write(string.format([[
Write([[
<title>redbean fetch demo</title>
<style>
body {
@ -41,7 +41,7 @@ local function WriteForm(url)
value="%s" placeholder="uri" autofocus>
<input type="submit" value="fetch">
</form>
]], EscapeHtml(url)))
]] % {EscapeHtml(url)})
end
local function main()
@ -54,7 +54,7 @@ local function main()
WriteForm(GetParam('url'))
Write('<dl>\r\n')
Write('<dt>Status\r\n')
Write(string.format('<dd><p>%d %s\r\n', status, GetHttpReason(status)))
Write('<dd><p>%d %s\r\n' % {status, GetHttpReason(status)})
Write('<dt>Headers\r\n')
Write('<dd>\r\n')
for k,v in pairs(headers) do

View file

@ -167,7 +167,7 @@ local function main()
Write('<dt>GetRemoteAddr() <small>(from Berkeley Sockets or X-Forwarded-For header)</small>\r\n')
Write('<dd>')
ip, port = GetRemoteAddr()
Write(string.format('%s, %d', FormatIp(ip), port))
Write('%s, %d' % {FormatIp(ip), port})
if CategorizeIp(ip) then
Write('<br>\r\n')
Write(CategorizeIp(ip))
@ -176,7 +176,7 @@ local function main()
Write('<dt>GetClientAddr()\r\n')
Write('<dd>')
ip, port = GetClientAddr()
Write(string.format('%s, %d', FormatIp(ip), port))
Write('%s, %d' % {FormatIp(ip), port})
if CategorizeIp(ip) then
Write('<br>\r\n')
Write(CategorizeIp(ip))
@ -185,7 +185,7 @@ local function main()
Write('<dt>GetServerIp()\r\n')
Write('<dd>')
ip, port = GetServerAddr()
Write(string.format('%s, %d', FormatIp(ip), port))
Write('%s, %d' % {FormatIp(ip), port})
if CategorizeIp(ip) then
Write('<br>\r\n')
Write(CategorizeIp(ip))
@ -269,28 +269,28 @@ local function main()
m,a,b,c,d = pat:search(s) -- m and rest are nil if match not found
Write('<pre>\r\n')
Write([[pat = re.compile('([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})')]])
Write(string.format('\r\nm,a,b,c,d = pat:search(%q)\r\n', s))
Write('\r\nm,a,b,c,d = pat:search(%q)\r\n' % {s})
Write('</pre>\r\n')
Write('<dl>\r\n')
Write('<dt>m\r\n')
Write('<dd>')
Write(string.format("%q", m))
Write("%q" % {m})
Write('\r\n')
Write('<dt>a\r\n')
Write('<dd>')
Write(string.format("%q", a))
Write("%q" % {a})
Write('\r\n')
Write('<dt>b\r\n')
Write('<dd>')
Write(string.format("%q", b))
Write("%q" % {b})
Write('\r\n')
Write('<dt>c\r\n')
Write('<dd>')
Write(string.format("%q", c))
Write("%q" % {c})
Write('\r\n')
Write('<dt>d\r\n')
Write('<dd>')
Write(string.format("%q", d))
Write("%q" % {d})
Write('\r\n')
Write('</dl>\r\n')
@ -328,7 +328,7 @@ local function main()
Write(FormatHttpDateTime(GetLastModifiedTime(paths[i])))
Write('<br>\r\n')
Write('Mode: ')
Write(string.format("0%o", GetAssetMode(paths[i])))
Write("0%o" % {GetAssetMode(paths[i])})
Write('<br>\r\n')
Write('Size: ')
Write(tostring(GetAssetSize(paths[i])))

View file

@ -3,53 +3,58 @@ local unix = require 'unix'
Write('<!doctype html>\r\n')
Write('<title>redbean</title>\r\n')
Write('<h3>UNIX Information Demo</h3>\r\n')
Write('<style>dt { margin: .5em 0; font-style:italic; }</style>\r\n')
Write('<dl>\r\n')
Write('<dt>getuid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getuid()))
Write('<dt>getgid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getgid()))
Write('<dt>getpid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getpid()))
Write('<dt>getppid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getppid()))
Write('<dt>getpgrp()\r\n')
Write(string.format('<dd>%d\r\n', unix.getpgrp()))
Write('<dt>unix.getuid()\r\n')
Write('<dd>%d\r\n' % {unix.getuid()})
Write('<dt>unix.getgid()\r\n')
Write('<dd>%d\r\n' % {unix.getgid()})
Write('<dt>unix.getpid()\r\n')
Write('<dd>%d\r\n' % {unix.getpid()})
Write('<dt>unix.getppid()\r\n')
Write('<dd>%d\r\n' % {unix.getppid()})
Write('<dt>unix.getpgrp()\r\n')
Write('<dd>%d\r\n' % {unix.getpgrp()})
Write('<dt>unix.umask()\r\n')
mask = unix.umask(027)
unix.umask(mask)
Write('<dd>%.4o\r\n' % {mask})
Write('<dt>getsid(0)\r\n')
Write('<dt>unix.getsid(0)\r\n')
sid, errno = unix.getsid(0)
if sid then
Write(string.format('<dd>%d\r\n', sid))
Write('<dd>%d\r\n' % {sid})
else
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.strerrno(errno))))
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
end
Write('<dt>gethostname()\r\n')
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.gethostname())))
Write('<dt>getcwd()\r\n')
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.getcwd())))
Write('<dt>unix.gethostname()\r\n')
Write('<dd>%s\r\n' % {EscapeHtml(unix.gethostname())})
Write('<dt>unix.getcwd()\r\n')
Write('<dd>%s\r\n' % {EscapeHtml(unix.getcwd())})
function PrintResourceLimit(name, id)
soft, hard, errno = unix.getrlimit(id)
Write(string.format('<dt>getrlimit(%s)\r\n', name))
Write('<dt>getrlimit(%s)\r\n' % {name})
if soft then
Write('<dd>')
Write('soft ')
if soft == -1 then
Write('')
else
Write(string.format('%d', soft))
Write('%d' % {soft})
end
Write('<br>\r\n')
Write('hard ')
if hard == -1 then
Write('')
else
Write(string.format('%d', hard))
Write('%d' % {hard})
end
Write('\r\n')
else
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.strerrno(errno))))
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
end
end
PrintResourceLimit('RLIMIT_AS', unix.RLIMIT_AS)
@ -59,7 +64,7 @@ PrintResourceLimit('RLIMIT_FSIZE', unix.RLIMIT_FSIZE)
PrintResourceLimit('RLIMIT_NPROC', unix.RLIMIT_NPROC)
PrintResourceLimit('RLIMIT_NOFILE', unix.RLIMIT_NOFILE)
Write('<dt>siocgifconf()\r\n')
Write('<dt>unix.siocgifconf()\r\n')
Write('<dd>\r\n')
ifs, errno = unix.siocgifconf()
if ifs then
@ -69,12 +74,217 @@ if ifs then
else
cidr = 0
end
Write(string.format('%s %s/%d<br>\r\n',
EscapeHtml(ifs[i].name),
FormatIp(ifs[i].ip),
cidr))
Write('%s %s/%d<br>\r\n' % {EscapeHtml(ifs[i].name), FormatIp(ifs[i].ip), cidr})
end
else
Write(string.format('%s\r\n', EscapeHtml(unix.strerrno(errno))))
Write('%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
end
Write('</dl>\r\n')
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DEBUG)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DEBUG)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEADDR)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEADDR)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEPORT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEPORT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_KEEPALIVE)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_KEEPALIVE)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NODELAY)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NODELAY)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, secs, micros = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVTIMEO)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVTIMEO)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d sec %d µs\r\n' % {secs, micros})
end
errno, secs, micros = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDTIMEO)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDTIMEO)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d sec %d µs\r\n' % {secs, micros})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DONTROUTE)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DONTROUTE)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDBUF)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDBUF)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVBUF)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVBUF)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_BROADCAST)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_BROADCAST)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_CORK)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_CORK)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_QUICKACK)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_QUICKACK)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_DEFER_ACCEPT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_DEFER_ACCEPT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN_CONNECT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN_CONNECT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDLOWAT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDLOWAT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVLOWAT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVLOWAT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPCNT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPCNT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_MAXSEG)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_MAXSEG)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_SYNCNT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_SYNCNT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NOTSENT_LOWAT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NOTSENT_LOWAT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_WINDOW_CLAMP)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_WINDOW_CLAMP)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPIDLE)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPIDLE)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPINTVL)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPINTVL)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
Write('<dt>unix.environ()\r\n')
Write('<dd>\r\n')
Write('<ul>\r\n')
env = unix.environ()
for i = 1,#env do
Write('<li>%s\r\n' % {EscapeHtml(env[i])})
end
Write('</ul>\r\n')

View file

@ -32,8 +32,9 @@ local function main()
-- steal client from redbean
fd = GetClientFd()
rc, errno = unix.fork()
-- this function returns twice
pid, errno = unix.fork()
if errno then
SetStatus(400)
SetHeader('Content-Type', 'text/html; charset=utf-8')
@ -44,7 +45,7 @@ local function main()
Write(EncodeBase64(LoadAsset('/redbean.png')))
Write('">\r\n')
Write('redbean unix demo\r\n')
Write(string.format('<span style="color:red">&nbsp;%s</span>\r\n', unix.strerrno(errno)))
Write('<span style="color:red">&nbsp;%s</span>\r\n' % {unix.strerrno(errno)})
Write('</h1>\r\n')
Write([[
<p>
@ -57,11 +58,13 @@ local function main()
return
end
if rc ~= 0 then
-- the parent process gets the pid
if pid ~= 0 then
unix.close(fd)
return
end
-- if pid is zero then we're the child
-- turn into a daemon
unix.umask(0)
unix.setsid()
@ -119,7 +122,7 @@ local function main()
else
st, err = unix.stat(name)
if st then
unix.write(fd, string.format(' (%d bytes)', st:size()))
unix.write(fd, ' (%d bytes)' % {st:size()})
end
end
unix.write(fd, '\r\n')
@ -127,7 +130,7 @@ local function main()
unix.write(fd, '</ul>\r\n')
else
unix.write(fd, '<p>\r\n')
unix.write(fd, string.format('failed: %s\r\n', EscapeHtml(VisualizeControlCodes(unix:strerror(err)))))
unix.write(fd, 'failed: %s\r\n' % {EscapeHtml(VisualizeControlCodes(unix:strerror(err)))})
unix.write(fd, '</p>\r\n')
end

View file

@ -2,15 +2,20 @@
-- and pipe its output to the http user
local unix = require "unix"
function main()
if GetHostOs() == 'WINDOWS' then
cmd = 'dir'
else
cmd = 'ls'
end
syscall = 'commandv'
ls, errno = unix.commandv("ls")
ls, errno = unix.commandv(cmd)
if ls then
syscall = 'pipe'
reader, writer, errno = unix.pipe()
if reader then
oldint = unix.sigaction(unix.SIGINT, unix.SIG_IGN)
oldquit = unix.sigaction(unix.SIGQUIT, unix.SIG_IGN)
oldmask = unix.sigprocmask(unix.SIG_BLOCK, unix.SIGCHLD)
-- oldint = unix.sigaction(unix.SIGINT, unix.SIG_IGN)
-- oldquit = unix.sigaction(unix.SIGQUIT, unix.SIG_IGN)
-- oldmask = unix.sigprocmask(unix.SIG_BLOCK, unix.SIGCHLD)
syscall = 'fork'
child, errno = unix.fork()
if child then
@ -19,10 +24,10 @@ function main()
unix.dup(writer)
unix.close(writer)
unix.close(reader)
unix.sigaction(unix.SIGINT, oldint)
unix.sigaction(unix.SIGQUIT, oldquit)
unix.sigprocmask(unix.SIG_SETMASK, oldmask)
unix.execve(ls, {ls, "-Shal"})
-- unix.sigaction(unix.SIGINT, oldint)
-- unix.sigaction(unix.SIGQUIT, oldquit)
-- unix.sigprocmask(unix.SIG_SETMASK, oldmask)
unix.execve(ls, {ls, '-Shal'})
unix.exit(127)
else
unix.close(writer)
@ -31,21 +36,21 @@ function main()
while true do
data, errno = unix.read(reader)
if data then
if data ~= "" then
if data ~= '' then
Write(data)
else
break
end
elseif errno ~= unix.EINTR then
Log(kLogWarn, string.format('read() failed: %s', unix.strerror(errno)))
Log(kLogWarn, 'read() failed: %s' % {unix.strerror(errno)})
break
end
end
unix.close(reader)
unix.wait(-1)
unix.sigaction(unix.SIGINT, oldint)
unix.sigaction(unix.SIGQUIT, oldquit)
unix.sigprocmask(unix.SIG_SETMASK, oldmask)
-- unix.sigaction(unix.SIGINT, oldint)
-- unix.sigaction(unix.SIGQUIT, oldquit)
-- unix.sigprocmask(unix.SIG_SETMASK, oldmask)
return
end
end
@ -53,6 +58,6 @@ function main()
end
SetStatus(200)
SetHeader('Content-Type', 'text/plain')
Write(string.format('error %s calling %s()', unix.strerrno(errno), syscall))
Write('error %s calling %s()' % {unix.strerrno(errno), syscall})
end
main()

View file

@ -46,12 +46,10 @@ function main()
unix.bind(server, ifs[i].ip)
unix.listen(server)
ip, port = unix.getsockname(server)
addr = string.format('%s:%d', FormatIp(ip), port)
url = string.format('http://%s', addr)
Log(kLogInfo, string.format('listening on %s', addr))
unix.write(mainfd, string.format(
'listening on <a target="_blank" href="%s">%s</a><br>\r\n',
url, url))
addr = '%s:%d' % {FormatIp(ip), port}
url = 'http://%s' % {addr}
Log(kLogInfo, 'listening on %s' % {addr})
unix.write(mainfd, 'listening on <a target="_blank" href="%s">%s</a><br>\r\n' % {url, url})
pollfds[server] = unix.POLLIN | unix.POLLHUP
servers[server] = true
addrs[server] = addr
@ -67,7 +65,7 @@ function main()
if fd == mainfd then
data, errno = unix.read(mainfd)
if not data then
Log(kLogInfo, string.format('got %s from parent client', unix.strerrno(errno)))
Log(kLogInfo, 'got %s from parent client' % {unix.strerrno(errno)})
-- prevent redbean core from writing a response
unix.exit(1)
end
@ -80,20 +78,20 @@ function main()
-- echo it back for fun
unix.write(mainfd, data)
elseif servers[fd] then
unix.write(mainfd, string.format('preparing to accept from %d<br>\r\n', fd))
unix.write(mainfd, 'preparing to accept from %d<br>\r\n' % {fd})
client, clientip, clientport = unix.accept(fd)
unix.write(mainfd, string.format('preparing to accept from %d<br>\r\n', fd))
addr = string.format('%s:%d', FormatIp(clientip), clientport)
unix.write(mainfd, 'preparing to accept from %d<br>\r\n' % {fd})
addr = '%s:%d' % {FormatIp(clientip), clientport}
addrs[client] = addr
unix.write(mainfd, string.format('got client %s<br>\r\n', addr))
unix.write(mainfd, 'got client %s<br>\r\n' % {addr})
pollfds[client] = unix.POLLIN
evs[server] = nil
else
unix.write(mainfd, string.format('preparing to read from %d<br>\r\n', fd))
unix.write(mainfd, 'preparing to read from %d<br>\r\n' % {fd})
data = unix.read(fd)
unix.write(mainfd, string.format('done reading from %d<br>\r\n', fd))
unix.write(mainfd, 'done reading from %d<br>\r\n' % {fd})
if data and #data ~= 0 then
unix.write(mainfd, string.format('got %d bytes from %s<br>\r\n', #data, addrs[fd]))
unix.write(mainfd, 'got %d bytes from %s<br>\r\n' % {#data, addrs[fd]})
unix.write(fd, 'HTTP/1.0 200 OK\r\n' ..
'Date: '.. FormatHttpDateTime(GetDate()) ..'\r\n' ..
'Content-Type: text/html; charset=utf-8\r\n' ..

File diff suppressed because it is too large Load diff

562
tool/net/lfuncs.c Normal file
View file

@ -0,0 +1,562 @@
/*-*- 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 2022 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 "dsp/scale/cdecimate2xuint8x8.h"
#include "libc/bits/popcnt.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/bsf.h"
#include "libc/nexgen32e/bsr.h"
#include "libc/nexgen32e/crc32.h"
#include "libc/nexgen32e/rdtsc.h"
#include "libc/nexgen32e/rdtscp.h"
#include "libc/rand/rand.h"
#include "libc/runtime/gc.internal.h"
#include "libc/sock/sock.h"
#include "libc/sysv/consts/af.h"
#include "libc/time/time.h"
#include "libc/x/x.h"
#include "net/http/escape.h"
#include "net/http/http.h"
#include "net/http/ip.h"
#include "net/http/url.h"
#include "third_party/lua/cosmo.h"
#include "third_party/lua/lauxlib.h"
#include "third_party/lua/lua.h"
#include "third_party/mbedtls/md.h"
#include "third_party/mbedtls/md5.h"
#include "third_party/mbedtls/platform.h"
#include "third_party/mbedtls/sha1.h"
#include "third_party/mbedtls/sha256.h"
#include "third_party/mbedtls/sha512.h"
#include "tool/net/lfuncs.h"
int LuaGetTime(lua_State *L) {
lua_pushnumber(L, nowl());
return 1;
}
int LuaSleep(lua_State *L) {
usleep(1e6 * luaL_checknumber(L, 1));
return 0;
}
int LuaRdtsc(lua_State *L) {
lua_pushinteger(L, rdtsc());
return 1;
}
int LuaGetCpuNode(lua_State *L) {
lua_pushinteger(L, TSC_AUX_NODE(rdpid()));
return 1;
}
int LuaGetCpuCore(lua_State *L) {
lua_pushinteger(L, TSC_AUX_CORE(rdpid()));
return 1;
}
int LuaGetLogLevel(lua_State *L) {
lua_pushinteger(L, __log_level);
return 1;
}
int LuaSetLogLevel(lua_State *L) {
__log_level = luaL_checkinteger(L, 1);
return 0;
}
static int LuaRand(lua_State *L, uint64_t impl(void)) {
lua_pushinteger(L, impl());
return 1;
}
int LuaLemur64(lua_State *L) {
return LuaRand(L, lemur64);
}
int LuaRand64(lua_State *L) {
return LuaRand(L, rand64);
}
int LuaRdrand(lua_State *L) {
return LuaRand(L, rdrand);
}
int LuaRdseed(lua_State *L) {
return LuaRand(L, rdseed);
}
int LuaDecimate(lua_State *L) {
size_t n, m;
const char *s;
unsigned char *p;
s = luaL_checklstring(L, 1, &n);
m = ROUNDUP(n, 16);
p = xmalloc(m);
bzero(p + n, m - n);
cDecimate2xUint8x8(m, p, (signed char[8]){-1, -3, 3, 17, 17, 3, -3, -1});
lua_pushlstring(L, (char *)p, (n + 1) >> 1);
free(p);
return 1;
}
int LuaMeasureEntropy(lua_State *L) {
size_t n;
const char *s;
s = luaL_checklstring(L, 1, &n);
lua_pushnumber(L, MeasureEntropy(s, n));
return 1;
}
int LuaGetHostOs(lua_State *L) {
const char *s = NULL;
if (IsLinux()) {
s = "LINUX";
} else if (IsMetal()) {
s = "METAL";
} else if (IsWindows()) {
s = "WINDOWS";
} else if (IsXnu()) {
s = "XNU";
} else if (IsOpenbsd()) {
s = "OPENBSD";
} else if (IsFreebsd()) {
s = "FREEBSD";
} else if (IsNetbsd()) {
s = "NETBSD";
}
if (s) {
lua_pushstring(L, s);
} else {
lua_pushnil(L);
}
return 1;
}
int LuaFormatIp(lua_State *L) {
char b[16];
uint32_t ip;
ip = htonl(luaL_checkinteger(L, 1));
inet_ntop(AF_INET, &ip, b, sizeof(b));
lua_pushstring(L, b);
return 1;
}
int LuaParseIp(lua_State *L) {
size_t n;
const char *s;
s = luaL_checklstring(L, 1, &n);
lua_pushinteger(L, ParseIp(s, n));
return 1;
}
static int LuaIsIp(lua_State *L, bool IsIp(uint32_t)) {
lua_pushboolean(L, IsIp(luaL_checkinteger(L, 1)));
return 1;
}
int LuaIsPublicIp(lua_State *L) {
return LuaIsIp(L, IsPublicIp);
}
int LuaIsPrivateIp(lua_State *L) {
return LuaIsIp(L, IsPrivateIp);
}
int LuaIsLoopbackIp(lua_State *L) {
return LuaIsIp(L, IsLoopbackIp);
}
int LuaCategorizeIp(lua_State *L) {
lua_pushstring(L, GetIpCategoryName(CategorizeIp(luaL_checkinteger(L, 1))));
return 1;
}
int LuaFormatHttpDateTime(lua_State *L) {
char buf[30];
lua_pushstring(L, FormatUnixHttpDateTime(buf, luaL_checkinteger(L, 1)));
return 1;
}
int LuaParseHttpDateTime(lua_State *L) {
size_t n;
const char *s;
s = luaL_checklstring(L, 1, &n);
lua_pushinteger(L, ParseHttpDateTime(s, n));
return 1;
}
int LuaParseParams(lua_State *L) {
void *m;
size_t size;
const char *data;
struct UrlParams h;
data = luaL_checklstring(L, 1, &size);
bzero(&h, sizeof(h));
m = ParseParams(data, size, &h);
LuaPushUrlParams(L, &h);
free(h.p);
free(m);
return 1;
}
int LuaParseHost(lua_State *L) {
void *m;
size_t n;
struct Url h;
const char *p;
bzero(&h, sizeof(h));
p = luaL_checklstring(L, 1, &n);
m = ParseHost(p, n, &h);
lua_newtable(L);
LuaPushUrlView(L, &h.host);
LuaPushUrlView(L, &h.port);
free(m);
return 1;
}
int LuaPopcnt(lua_State *L) {
lua_pushinteger(L, popcnt(luaL_checkinteger(L, 1)));
return 1;
}
int LuaBsr(lua_State *L) {
long x;
if ((x = luaL_checkinteger(L, 1))) {
lua_pushinteger(L, bsr(x));
return 1;
} else {
luaL_argerror(L, 1, "zero");
unreachable;
}
}
int LuaBsf(lua_State *L) {
long x;
if ((x = luaL_checkinteger(L, 1))) {
lua_pushinteger(L, bsf(x));
return 1;
} else {
luaL_argerror(L, 1, "zero");
unreachable;
}
}
static int LuaHash(lua_State *L, uint32_t H(uint32_t, const void *, size_t)) {
long i;
size_t n;
const char *p;
i = luaL_checkinteger(L, 1);
p = luaL_checklstring(L, 2, &n);
lua_pushinteger(L, H(i, p, n));
return 1;
}
int LuaCrc32(lua_State *L) {
return LuaHash(L, crc32_z);
}
int LuaCrc32c(lua_State *L) {
return LuaHash(L, crc32c);
}
int LuaIndentLines(lua_State *L) {
void *p;
size_t n, j;
p = luaL_checklstring(L, 1, &n);
j = luaL_optinteger(L, 2, 1);
if (!(0 <= j && j <= 65535)) {
luaL_argerror(L, 2, "not in range 0..65535");
unreachable;
}
p = IndentLines(p, n, &n, j);
lua_pushlstring(L, p, n);
free(p);
return 1;
}
int LuaGetMonospaceWidth(lua_State *L) {
int w;
if (lua_isinteger(L, 1)) {
w = wcwidth(lua_tointeger(L, 1));
} else if (lua_isstring(L, 1)) {
w = strwidth(luaL_checkstring(L, 1), luaL_optinteger(L, 2, 0) & 7);
} else {
luaL_argerror(L, 1, "not integer or string");
unreachable;
}
lua_pushinteger(L, w);
return 1;
}
int LuaSlurp(lua_State *L) {
char *p, *f;
size_t n;
f = luaL_checkstring(L, 1);
if ((p = xslurp(f, &n))) {
lua_pushlstring(L, p, n);
free(p);
return 1;
} else {
lua_pushnil(L);
lua_pushstring(L, gc(xasprintf("Can't slurp file %`'s: %m", f)));
return 2;
}
}
static int LuaCheckControlFlags(lua_State *L, int idx) {
int f = luaL_checkinteger(L, idx);
if (f & ~(kControlWs | kControlC0 | kControlC1)) {
luaL_argerror(L, idx, "invalid control flags");
unreachable;
}
return f;
}
int LuaHasControlCodes(lua_State *L) {
int f;
size_t n;
const char *p;
p = luaL_checklstring(L, 1, &n);
f = LuaCheckControlFlags(L, 2);
lua_pushboolean(L, HasControlCodes(p, n, f) != -1);
return 1;
}
int LuaEncodeLatin1(lua_State *L) {
int f;
char *p;
size_t n;
p = luaL_checklstring(L, 1, &n);
f = LuaCheckControlFlags(L, 2);
p = EncodeLatin1(p, n, &n, f);
lua_pushlstring(L, p, n);
free(p);
return 1;
}
int LuaGetRandomBytes(lua_State *L) {
char *p;
size_t n = luaL_optinteger(L, 1, 16);
if (!(n > 0 && n <= 256)) {
luaL_argerror(L, 1, "not in range 1..256");
unreachable;
}
p = malloc(n);
CHECK_EQ(n, getrandom(p, n, 0));
lua_pushlstring(L, p, n);
free(p);
return 1;
}
int LuaGetHttpReason(lua_State *L) {
lua_pushstring(L, GetHttpReason(luaL_checkinteger(L, 1)));
return 1;
}
int LuaGetCryptoHash(lua_State *L) {
size_t hl, pl, kl;
uint8_t d[64];
mbedtls_md_context_t ctx;
// get hash name, payload, and key
void *h = luaL_checklstring(L, 1, &hl);
void *p = luaL_checklstring(L, 2, &pl);
void *k = luaL_optlstring(L, 3, "", &kl);
const mbedtls_md_info_t *digest = mbedtls_md_info_from_string(h);
if (!digest) return luaL_argerror(L, 1, "unknown hash type");
if (kl == 0) {
// no key provided, run generic hash function
if ((digest->f_md)(p, pl, d)) return luaL_error(L, "bad input data");
} else if (mbedtls_md_hmac(digest, k, kl, p, pl, d)) {
return luaL_error(L, "bad input data");
}
lua_pushlstring(L, (void *)d, digest->size);
mbedtls_platform_zeroize(d, sizeof(d));
return 1;
}
static dontinline int LuaIsValid(lua_State *L, bool V(const char *, size_t)) {
size_t size;
const char *data;
data = luaL_checklstring(L, 1, &size);
lua_pushboolean(L, V(data, size));
return 1;
}
int LuaIsValidHttpToken(lua_State *L) {
return LuaIsValid(L, IsValidHttpToken);
}
int LuaIsAcceptablePath(lua_State *L) {
return LuaIsValid(L, IsAcceptablePath);
}
int LuaIsReasonablePath(lua_State *L) {
return LuaIsValid(L, IsReasonablePath);
}
int LuaIsAcceptableHost(lua_State *L) {
return LuaIsValid(L, IsAcceptableHost);
}
int LuaIsAcceptablePort(lua_State *L) {
return LuaIsValid(L, IsAcceptablePort);
}
static dontinline int LuaCoderImpl(lua_State *L,
char *C(const char *, size_t, size_t *)) {
void *p;
size_t n;
p = luaL_checklstring(L, 1, &n);
p = C(p, n, &n);
lua_pushlstring(L, p, n);
free(p);
return 1;
}
static dontinline int LuaCoder(lua_State *L,
char *C(const char *, size_t, size_t *)) {
return LuaCoderImpl(L, C);
}
int LuaUnderlong(lua_State *L) {
return LuaCoder(L, Underlong);
}
int LuaEncodeBase64(lua_State *L) {
return LuaCoder(L, EncodeBase64);
}
int LuaDecodeBase64(lua_State *L) {
return LuaCoder(L, DecodeBase64);
}
int LuaDecodeLatin1(lua_State *L) {
return LuaCoder(L, DecodeLatin1);
}
int LuaEscapeHtml(lua_State *L) {
return LuaCoder(L, EscapeHtml);
}
int LuaEscapeParam(lua_State *L) {
return LuaCoder(L, EscapeParam);
}
int LuaEscapePath(lua_State *L) {
return LuaCoder(L, EscapePath);
}
int LuaEscapeHost(lua_State *L) {
return LuaCoder(L, EscapeHost);
}
int LuaEscapeIp(lua_State *L) {
return LuaCoder(L, EscapeIp);
}
int LuaEscapeUser(lua_State *L) {
return LuaCoder(L, EscapeUser);
}
int LuaEscapePass(lua_State *L) {
return LuaCoder(L, EscapePass);
}
int LuaEscapeSegment(lua_State *L) {
return LuaCoder(L, EscapeSegment);
}
int LuaEscapeFragment(lua_State *L) {
return LuaCoder(L, EscapeFragment);
}
int LuaEscapeLiteral(lua_State *L) {
return LuaCoder(L, EscapeJsStringLiteral);
}
int LuaVisualizeControlCodes(lua_State *L) {
return LuaCoder(L, VisualizeControlCodes);
}
static dontinline int LuaHasherImpl(lua_State *L, size_t k,
int H(const void *, size_t, uint8_t *)) {
void *p;
size_t n;
uint8_t d[64];
p = luaL_checklstring(L, 1, &n);
H(p, n, d);
lua_pushlstring(L, (void *)d, k);
mbedtls_platform_zeroize(d, sizeof(d));
return 1;
}
static dontinline int LuaHasher(lua_State *L, size_t k,
int H(const void *, size_t, uint8_t *)) {
return LuaHasherImpl(L, k, H);
}
int LuaMd5(lua_State *L) {
return LuaHasher(L, 16, mbedtls_md5_ret);
}
int LuaSha1(lua_State *L) {
return LuaHasher(L, 20, mbedtls_sha1_ret);
}
int LuaSha224(lua_State *L) {
return LuaHasher(L, 28, mbedtls_sha256_ret_224);
}
int LuaSha256(lua_State *L) {
return LuaHasher(L, 32, mbedtls_sha256_ret_256);
}
int LuaSha384(lua_State *L) {
return LuaHasher(L, 48, mbedtls_sha512_ret_384);
}
int LuaSha512(lua_State *L) {
return LuaHasher(L, 64, mbedtls_sha512_ret_512);
}
int LuaIsHeaderRepeatable(lua_State *L) {
int h;
bool r;
size_t n;
const char *s;
s = luaL_checklstring(L, 1, &n);
if ((h = GetHttpHeader(s, n)) != -1) {
r = kHttpRepeatable[h];
} else {
r = false;
}
lua_pushboolean(L, r);
return 1;
}
void LuaPushUrlView(lua_State *L, struct UrlView *v) {
if (v->p) {
lua_pushlstring(L, v->p, v->n);
} else {
lua_pushnil(L);
}
}

84
tool/net/lfuncs.h Normal file
View file

@ -0,0 +1,84 @@
#ifndef COSMOPOLITAN_TOOL_NET_LFUNCS_H_
#define COSMOPOLITAN_TOOL_NET_LFUNCS_H_
#include "net/http/url.h"
#include "third_party/lua/lua.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int LuaMaxmind(lua_State *);
int LuaRe(lua_State *);
int LuaUnix(lua_State *);
int luaopen_argon2(lua_State *);
int luaopen_lsqlite3(lua_State *);
int LuaBsf(lua_State *);
int LuaBsr(lua_State *);
int LuaCategorizeIp(lua_State *);
int LuaCrc32(lua_State *);
int LuaCrc32c(lua_State *);
int LuaDecimate(lua_State *);
int LuaDecodeBase64(lua_State *);
int LuaDecodeLatin1(lua_State *);
int LuaEncodeBase64(lua_State *);
int LuaEncodeLatin1(lua_State *);
int LuaEscapeFragment(lua_State *);
int LuaEscapeHost(lua_State *);
int LuaEscapeHtml(lua_State *);
int LuaEscapeIp(lua_State *);
int LuaEscapeLiteral(lua_State *);
int LuaEscapeParam(lua_State *);
int LuaEscapePass(lua_State *);
int LuaEscapePath(lua_State *);
int LuaEscapeSegment(lua_State *);
int LuaEscapeUser(lua_State *);
int LuaFormatHttpDateTime(lua_State *);
int LuaFormatIp(lua_State *);
int LuaGetCpuCore(lua_State *);
int LuaGetCpuNode(lua_State *);
int LuaGetCryptoHash(lua_State *);
int LuaGetHostOs(lua_State *);
int LuaGetHttpReason(lua_State *);
int LuaGetLogLevel(lua_State *);
int LuaGetMonospaceWidth(lua_State *);
int LuaGetRandomBytes(lua_State *);
int LuaGetTime(lua_State *);
int LuaHasControlCodes(lua_State *);
int LuaIndentLines(lua_State *);
int LuaIsAcceptableHost(lua_State *);
int LuaIsAcceptablePath(lua_State *);
int LuaIsAcceptablePort(lua_State *);
int LuaIsHeaderRepeatable(lua_State *);
int LuaIsLoopbackIp(lua_State *);
int LuaIsPrivateIp(lua_State *);
int LuaIsPublicIp(lua_State *);
int LuaIsReasonablePath(lua_State *);
int LuaIsValidHttpToken(lua_State *);
int LuaLemur64(lua_State *);
int LuaMd5(lua_State *);
int LuaMeasureEntropy(lua_State *);
int LuaParseHost(lua_State *);
int LuaParseHttpDateTime(lua_State *);
int LuaParseIp(lua_State *);
int LuaParseParams(lua_State *);
int LuaPopcnt(lua_State *);
int LuaRand64(lua_State *);
int LuaRdrand(lua_State *);
int LuaRdseed(lua_State *);
int LuaRdtsc(lua_State *);
int LuaSetLogLevel(lua_State *);
int LuaSha1(lua_State *);
int LuaSha224(lua_State *);
int LuaSha256(lua_State *);
int LuaSha384(lua_State *);
int LuaSha512(lua_State *);
int LuaSleep(lua_State *);
int LuaSlurp(lua_State *);
int LuaUnderlong(lua_State *);
int LuaVisualizeControlCodes(lua_State *);
void LuaPushUrlView(lua_State *, struct UrlView *);
char *FormatUnixHttpDateTime(char *, int64_t);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_TOOL_NET_LFUNCS_H_ */

File diff suppressed because it is too large Load diff

View file

@ -90,7 +90,8 @@ o/$(MODE)/tool/net/%.com.dbg: \
o/$(MODE)/tool/net/redbean.com.dbg: \
$(TOOL_NET_DEPS) \
o/$(MODE)/tool/net/redbean.o \
o/$(MODE)/tool/net/redbean.o \
o/$(MODE)/tool/net/lfuncs.o \
o/$(MODE)/tool/net/lre.o \
o/$(MODE)/tool/net/lunix.o \
o/$(MODE)/tool/net/lmaxmind.o \
@ -208,7 +209,8 @@ o/$(MODE)/tool/net/demo/virtualbean.html.zip.o: \
o/$(MODE)/tool/net/redbean-demo.com.dbg: \
$(TOOL_NET_DEPS) \
o/$(MODE)/tool/net/redbean.o \
o/$(MODE)/tool/net/redbean.o \
o/$(MODE)/tool/net/lfuncs.o \
o/$(MODE)/tool/net/lre.o \
o/$(MODE)/tool/net/lunix.o \
o/$(MODE)/tool/net/lmaxmind.o \
@ -326,6 +328,7 @@ o/$(MODE)/tool/net/redbean-unsecure.com: \
o/$(MODE)/tool/net/redbean-unsecure.com.dbg: \
$(TOOL_NET_DEPS) \
o/$(MODE)/tool/net/redbean-unsecure.o \
o/$(MODE)/tool/net/lfuncs.o \
o/$(MODE)/tool/net/lre.o \
o/$(MODE)/tool/net/lunix.o \
o/$(MODE)/tool/net/lmaxmind.o \
@ -408,6 +411,9 @@ o/$(MODE)/tool/net/redbean-original.com.dbg: \
o/$(MODE)/tool/net/redbean-original.o: tool/net/redbean.c o/$(MODE)/tool/net/redbean.o
@$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -DSTATIC -DUNSECURE -DREDBEAN=\"redbean-original\" $(OUTPUT_OPTION) $<
o/$(MODE)/tool/net/redbean-original.s: tool/net/redbean.c o/$(MODE)/tool/net/redbean.o
@$(COMPILE) -AOBJECTIFY.c $(COMPILE.c) -DSTATIC -DUNSECURE -DREDBEAN=\"redbean-original\" $(OUTPUT_OPTION) $<
# REDBEAN-ASSIMILATE.COM
#
# Same as REDBEAN.COM except without no-modify-self behavior.

File diff suppressed because it is too large Load diff

View file

@ -50,7 +50,7 @@ struct Gc *NewGc(int A) {
if (B < cHeap) cHeap = B;
n = ROUNDUP(A - B, DWBITS) / DWBITS;
G = Addr(BANE);
memset(G->M, 0, n * sizeof(G->M[0]));
bzero(G->M, n * sizeof(G->M[0]));
G->n = n;
G->A = A;
G->B = B;

View file

@ -28,7 +28,7 @@ int main(int argc, char *argv[]) {
while ((c = getchar()) != -1) {
if (col == 0) {
printf("\t.byte\t");
memset(glyphs, 0, sizeof(glyphs));
bzero(glyphs, sizeof(glyphs));
}
ch = c & 0xff;
glyphs[col] = kCp437[ch];

View file

@ -248,7 +248,7 @@ static unsigned combinecolors(unsigned char bf[1u << MC][2],
const unsigned char bl[CN][YS * XS]) {
uint64_t hv, ht[(1u << MC) * 2];
unsigned i, j, n, b, f, h, hi, bu, fu;
memset(ht, 0, sizeof(ht));
bzero(ht, sizeof(ht));
for (n = b = 0; b < BN && n < (1u << MC); ++b) {
bu = bl[2][b] << 020 | bl[1][b] << 010 | bl[0][b];
hi = 0;
@ -295,7 +295,7 @@ static unsigned combinecolors(unsigned char bf[1u << MC][2],
const float lb[CN][YS * XS]) { \
unsigned i, k, gu; \
float p[BN], q[BN], fu, bu, r; \
memset(q, 0, sizeof(q)); \
bzero(q, sizeof(q)); \
for (k = 0; k < CN; ++k) { \
gu = kGlyphs[g]; \
bu = lb[k][b]; \
@ -336,7 +336,7 @@ static float adjudicate(unsigned b, unsigned f, unsigned g,
const float lb[CN][YS * XS]) {
unsigned i, k, gu;
float p[BN], q[BN], fu, bu, r;
memset(q, 0, sizeof(q));
bzero(q, sizeof(q));
for (k = 0; k < CN; ++k) {
gu = kGlyphs[g];
bu = lb[k][b];
@ -487,8 +487,8 @@ static void LoadFileViaImageMagick(const char *path, unsigned yn, unsigned xn,
unsigned char rgb[yn][YS][xn][XS][CN]) {
const char *convert;
int pid, ws, pipefds[2];
char pathbuf[PATH_MAX], dim[32];
if (!(convert = commandv("convert", pathbuf))) {
char pathbuf[PATH_MAX + 1], dim[32];
if (!(convert = commandv("convert", pathbuf, sizeof(pathbuf)))) {
fputs("error: `convert` command not found\n"
"try: apt-get install imagemagick\n",
stderr);

View file

@ -93,7 +93,7 @@ void *BilinearScale(long dcw, long dyw, long dxw,
gc(xmemalign(64, ROUNDUP(dxn, 64))),
gc(xmemalign(64, ROUNDUP(sxn, 64) * 2)));
} else {
memset(dst[c0], 0, &dst[cn][0][0] - &dst[c0][0][0]);
bzero(dst[c0], &dst[cn][0][0] - &dst[c0][0][0]);
}
}
return dst;

View file

@ -19,12 +19,12 @@ forceinline void convolve(unsigned yn, unsigned xn, __m128 img[yn][xn], int KW,
kflip[KW - i - 1][KW - j - 1] = (__v4sf){f, f, f, f};
}
}
memset(&g, 0, sizeof(g));
bzero(&g, sizeof(g));
resizegraphic(&g, yn, xn);
tmp = g.b.p;
for (y = 0; y < yn - KW; ++y) {
for (x = 0; x < xn - KW; ++x) {
memset(&p, 0, sizeof(p));
bzero(&p, sizeof(p));
for (i = 0; i < KW; ++i) {
for (j = 0; j < KW; ++j) {
p += img[y + i][x + j] * kflip[i][j] + C2;

View file

@ -45,7 +45,7 @@ long unsharp(long cn, long yw, long xw, unsigned char img[cn][yw][xw], long yn,
for (x = 0; x < xn; ++x) {
img[c][y - 3][x] = MIN(255, MAX(0, (*t)[y % 3][x]));
}
memset((*t)[y % 3], 0, sizeof(short) * xn);
bzero((*t)[y % 3], sizeof(short) * xn);
}
if (y < yn) {
for (x = 0; x < xn; ++x) {

View file

@ -155,8 +155,8 @@ void YCbCrInit(struct YCbCr **ycbcr, bool yonly, int swing, double gamma,
const double gamut[3], const double illuminant[3]) {
if (!*ycbcr) *ycbcr = xcalloc(1, sizeof(struct YCbCr));
(*ycbcr)->yonly = yonly;
memset((*ycbcr)->magnums, 0, sizeof((*ycbcr)->magnums));
memset((*ycbcr)->lighting, 0, sizeof((*ycbcr)->lighting));
bzero((*ycbcr)->magnums, sizeof((*ycbcr)->magnums));
bzero((*ycbcr)->lighting, sizeof((*ycbcr)->lighting));
YCbCrComputeCoefficients(swing, gamma, gamut, illuminant, (*ycbcr)->magnums,
(*ycbcr)->lighting, (*ycbcr)->transfer[0]);
imapxlatab((*ycbcr)->transfer[1]);

View file

@ -612,7 +612,7 @@ static int LoadFile(const char *path) {
}
if (yn > byn || xn > bxn) goto ReadError;
xchg(&board, &board2);
memset(board, 0, (byn * bxn) >> 3);
bzero(board, (byn * bxn) >> 3);
yo = byn / 2 - yn / 2;
xo = bxn / 2 - xn / 2;
y = 0;
@ -857,7 +857,7 @@ static void Rando2(void) {
static void ReadKeyboard(void) {
char buf[32], *p = buf;
memset(buf, 0, sizeof(buf));
bzero(buf, sizeof(buf));
if (readansi(0, buf, sizeof(buf)) == -1) {
if (errno == EINTR) return;
exit(errno);
@ -895,7 +895,7 @@ static void ReadKeyboard(void) {
}
break;
case 'R':
memset(board, 0, (byn * bxn) >> 3);
bzero(board, (byn * bxn) >> 3);
break;
case CTRL('T'):
OnTurbo();
@ -1166,7 +1166,7 @@ static void OnMenuOpen(int64_t hwnd) {
char buf8[PATH_MAX];
char16_t buf16[PATH_MAX];
struct NtOpenFilename ofn;
memset(&ofn, 0, sizeof(ofn));
bzero(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = buf16;
@ -1370,7 +1370,7 @@ static void Gui(void) {
int64_t hwnd, mh;
struct NtMsg msg;
struct NtWndClass wc;
memset(&wc, 0, sizeof(wc));
bzero(&wc, sizeof(wc));
wc.lpfnWndProc = NT2SYSV(WindowProc);
wc.hInstance = GetModuleHandle(NULL);
wc.hCursor = LoadCursor(0, kNtIdcCross);

View file

@ -192,7 +192,7 @@ static void *MagikarpY(CHAR w, unsigned char p[1u << w][1u << w], char yw,
long y, x, yn, xn, ym;
unsigned char(*t)[(1u << w) + 2][1u << w];
t = memalign(64, ((1u << w) + 2) * (1u << w));
memset(t, 0, ((1u << w) + 2) * (1u << w));
bzero(t, ((1u << w) + 2) * (1u << w));
yn = 1u << yw;
xn = 1u << xw;
ym = yn >> 1;

View file

@ -496,7 +496,7 @@ static void OnMouse(char *p) {
static void ReadKeyboard(void) {
char buf[32], *p = buf;
memset(buf, 0, sizeof(buf));
bzero(buf, sizeof(buf));
if (readansi(0, buf, sizeof(buf)) == -1) {
if (errno == EINTR) return;
exit(errno);
@ -797,7 +797,7 @@ static void Zoom(long have) {
n >>= 1;
}
if (n < tyn * txn) {
memset(canvas + n, 0, canvassize - n);
bzero(canvas + n, canvassize - n);
}
if (have != -1) {
n = have >> zoom;
@ -817,7 +817,7 @@ static void FileZoom(void) {
have = MIN(displaysize, size - offset);
have = pread(fd, canvas, have, offset);
have = MAX(0, have);
memset(canvas + have, 0, canvassize - have);
bzero(canvas + have, canvassize - have);
Zoom(have);
Render();
}

View file

@ -26,11 +26,11 @@
int main(int argc, char *argv[]) {
int i;
for (i = 0; kDos2Errno[i].doscode; ++i) {
kprintf("dos error %10hu maps to rva %10d errno %10d which is %s%n",
kDos2Errno[i].doscode, kDos2Errno[i].systemv,
*(const int *)((intptr_t)kDos2Errno + kDos2Errno[i].systemv),
strerror_short(
*(const int *)((intptr_t)kDos2Errno + kDos2Errno[i].systemv)));
kprintf(
"dos error %10hu maps to rva %10d errno %10d which is %s%n",
kDos2Errno[i].doscode, kDos2Errno[i].systemv,
*(const int *)((intptr_t)kDos2Errno + kDos2Errno[i].systemv),
strerrno(*(const int *)((intptr_t)kDos2Errno + kDos2Errno[i].systemv)));
}
return 0;
}