mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-22 05:20:21 +00:00
Reduce number of disk seeks in redbean
This commit is contained in:
parent
daa32d27d4
commit
01e6b3ad8d
8 changed files with 212 additions and 173 deletions
|
@ -52,6 +52,8 @@
|
||||||
*
|
*
|
||||||
* Be sure to check for EINTR on your i/o calls, for best low latency.
|
* Be sure to check for EINTR on your i/o calls, for best low latency.
|
||||||
*
|
*
|
||||||
|
* Timers are not inherited across fork.
|
||||||
|
*
|
||||||
* @param which can be ITIMER_REAL, ITIMER_VIRTUAL, etc.
|
* @param which can be ITIMER_REAL, ITIMER_VIRTUAL, etc.
|
||||||
* @param newvalue specifies the interval ({0,0} means one-shot) and
|
* @param newvalue specifies the interval ({0,0} means one-shot) and
|
||||||
* duration ({0,0} means disarm) in microseconds ∈ [0,999999] and
|
* duration ({0,0} means disarm) in microseconds ∈ [0,999999] and
|
||||||
|
|
164
libc/fmt/kerrornames.S
Normal file
164
libc/fmt/kerrornames.S
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
/*-*- 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│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
|
|
||||||
|
.macro .e e
|
||||||
|
.long \e - kErrorNames
|
||||||
|
.long 1f - kErrorNames
|
||||||
|
.section .rodata.str1.1
|
||||||
|
1: .string "\e"
|
||||||
|
.previous
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
.align 4
|
||||||
|
kErrorNames:
|
||||||
|
.e ENOSYS
|
||||||
|
.e EPERM
|
||||||
|
.e ENOENT
|
||||||
|
.e ESRCH
|
||||||
|
.e EINTR
|
||||||
|
.e EIO
|
||||||
|
.e ENXIO
|
||||||
|
.e E2BIG
|
||||||
|
.e ENOEXEC
|
||||||
|
.e EBADF
|
||||||
|
.e ECHILD
|
||||||
|
.e EAGAIN
|
||||||
|
.e ENOMEM
|
||||||
|
.e EACCES
|
||||||
|
.e EFAULT
|
||||||
|
.e ENOTBLK
|
||||||
|
.e EBUSY
|
||||||
|
.e EEXIST
|
||||||
|
.e EXDEV
|
||||||
|
.e ENODEV
|
||||||
|
.e ENOTDIR
|
||||||
|
.e EISDIR
|
||||||
|
.e EINVAL
|
||||||
|
.e ENFILE
|
||||||
|
.e EMFILE
|
||||||
|
.e ENOTTY
|
||||||
|
.e ETXTBSY
|
||||||
|
.e EFBIG
|
||||||
|
.e ENOSPC
|
||||||
|
.e EDQUOT
|
||||||
|
.e ESPIPE
|
||||||
|
.e EROFS
|
||||||
|
.e EMLINK
|
||||||
|
.e EPIPE
|
||||||
|
.e EDOM
|
||||||
|
.e ERANGE
|
||||||
|
.e EDEADLK
|
||||||
|
.e ENAMETOOLONG
|
||||||
|
.e ENOLCK
|
||||||
|
.e ENOTEMPTY
|
||||||
|
.e ELOOP
|
||||||
|
.e ENOMSG
|
||||||
|
.e EIDRM
|
||||||
|
.e ETIME
|
||||||
|
.e EPROTO
|
||||||
|
.e EOVERFLOW
|
||||||
|
.e EILSEQ
|
||||||
|
.e EUSERS
|
||||||
|
.e ENOTSOCK
|
||||||
|
.e EDESTADDRREQ
|
||||||
|
.e EMSGSIZE
|
||||||
|
.e EPROTOTYPE
|
||||||
|
.e ENOPROTOOPT
|
||||||
|
.e EPROTONOSUPPORT
|
||||||
|
.e ESOCKTNOSUPPORT
|
||||||
|
.e ENOTSUP
|
||||||
|
.e EOPNOTSUPP
|
||||||
|
.e EPFNOSUPPORT
|
||||||
|
.e EAFNOSUPPORT
|
||||||
|
.e EADDRINUSE
|
||||||
|
.e EADDRNOTAVAIL
|
||||||
|
.e ENETDOWN
|
||||||
|
.e ENETUNREACH
|
||||||
|
.e ENETRESET
|
||||||
|
.e ECONNABORTED
|
||||||
|
.e ECONNRESET
|
||||||
|
.e ENOBUFS
|
||||||
|
.e EISCONN
|
||||||
|
.e ENOTCONN
|
||||||
|
.e ESHUTDOWN
|
||||||
|
.e ETOOMANYREFS
|
||||||
|
.e ETIMEDOUT
|
||||||
|
.e ECONNREFUSED
|
||||||
|
.e EHOSTDOWN
|
||||||
|
.e EHOSTUNREACH
|
||||||
|
.e EALREADY
|
||||||
|
.e EINPROGRESS
|
||||||
|
.e ESTALE
|
||||||
|
.e EREMOTE
|
||||||
|
.e EBADMSG
|
||||||
|
.e ECANCELED
|
||||||
|
.e EOWNERDEAD
|
||||||
|
.e ENOTRECOVERABLE
|
||||||
|
.e ENONET
|
||||||
|
.e ERESTART
|
||||||
|
.e ECHRNG
|
||||||
|
.e EL2NSYNC
|
||||||
|
.e EL3HLT
|
||||||
|
.e EL3RST
|
||||||
|
.e ELNRNG
|
||||||
|
.e EUNATCH
|
||||||
|
.e ENOCSI
|
||||||
|
.e EL2HLT
|
||||||
|
.e EBADE
|
||||||
|
.e EBADR
|
||||||
|
.e EXFULL
|
||||||
|
.e ENOANO
|
||||||
|
.e EBADRQC
|
||||||
|
.e EBADSLT
|
||||||
|
.e ENOSTR
|
||||||
|
.e ENODATA
|
||||||
|
.e ENOSR
|
||||||
|
.e ENOPKG
|
||||||
|
.e ENOLINK
|
||||||
|
.e EADV
|
||||||
|
.e ESRMNT
|
||||||
|
.e ECOMM
|
||||||
|
.e EMULTIHOP
|
||||||
|
.e EDOTDOT
|
||||||
|
.e ENOTUNIQ
|
||||||
|
.e EBADFD
|
||||||
|
.e EREMCHG
|
||||||
|
.e ELIBACC
|
||||||
|
.e ELIBBAD
|
||||||
|
.e ELIBSCN
|
||||||
|
.e ELIBMAX
|
||||||
|
.e ELIBEXEC
|
||||||
|
.e ESTRPIPE
|
||||||
|
.e EUCLEAN
|
||||||
|
.e ENOTNAM
|
||||||
|
.e ENAVAIL
|
||||||
|
.e EISNAM
|
||||||
|
.e EREMOTEIO
|
||||||
|
.e ENOMEDIUM
|
||||||
|
.e EMEDIUMTYPE
|
||||||
|
.e ENOKEY
|
||||||
|
.e EKEYEXPIRED
|
||||||
|
.e EKEYREVOKED
|
||||||
|
.e EKEYREJECTED
|
||||||
|
.e ERFKILL
|
||||||
|
.e EHWPOISON
|
||||||
|
.long 0
|
||||||
|
.endobj kErrorNames,globl,hidden
|
|
@ -27,149 +27,17 @@
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
const struct Error {
|
extern const struct Error {
|
||||||
const long *x;
|
int x;
|
||||||
const char *s;
|
int s;
|
||||||
} kErrors[] = {
|
} kErrorNames[];
|
||||||
{&ENOSYS, "ENOSYS"},
|
|
||||||
{&EPERM, "EPERM"},
|
|
||||||
{&ENOENT, "ENOENT"},
|
|
||||||
{&ESRCH, "ESRCH"},
|
|
||||||
{&EINTR, "EINTR"},
|
|
||||||
{&EIO, "EIO"},
|
|
||||||
{&ENXIO, "ENXIO"},
|
|
||||||
{&E2BIG, "E2BIG"},
|
|
||||||
{&ENOEXEC, "ENOEXEC"},
|
|
||||||
{&EBADF, "EBADF"},
|
|
||||||
{&ECHILD, "ECHILD"},
|
|
||||||
{&EAGAIN, "EAGAIN"},
|
|
||||||
{&ENOMEM, "ENOMEM"},
|
|
||||||
{&EACCES, "EACCES"},
|
|
||||||
{&EFAULT, "EFAULT"},
|
|
||||||
{&ENOTBLK, "ENOTBLK"},
|
|
||||||
{&EBUSY, "EBUSY"},
|
|
||||||
{&EEXIST, "EEXIST"},
|
|
||||||
{&EXDEV, "EXDEV"},
|
|
||||||
{&ENODEV, "ENODEV"},
|
|
||||||
{&ENOTDIR, "ENOTDIR"},
|
|
||||||
{&EISDIR, "EISDIR"},
|
|
||||||
{&EINVAL, "EINVAL"},
|
|
||||||
{&ENFILE, "ENFILE"},
|
|
||||||
{&EMFILE, "EMFILE"},
|
|
||||||
{&ENOTTY, "ENOTTY"},
|
|
||||||
{&ETXTBSY, "ETXTBSY"},
|
|
||||||
{&EFBIG, "EFBIG"},
|
|
||||||
{&ENOSPC, "ENOSPC"},
|
|
||||||
{&EDQUOT, "EDQUOT"},
|
|
||||||
{&ESPIPE, "ESPIPE"},
|
|
||||||
{&EROFS, "EROFS"},
|
|
||||||
{&EMLINK, "EMLINK"},
|
|
||||||
{&EPIPE, "EPIPE"},
|
|
||||||
{&EDOM, "EDOM"},
|
|
||||||
{&ERANGE, "ERANGE"},
|
|
||||||
{&EDEADLK, "EDEADLK"},
|
|
||||||
{&ENAMETOOLONG, "ENAMETOOLONG"},
|
|
||||||
{&ENOLCK, "ENOLCK"},
|
|
||||||
{&ENOTEMPTY, "ENOTEMPTY"},
|
|
||||||
{&ELOOP, "ELOOP"},
|
|
||||||
{&ENOMSG, "ENOMSG"},
|
|
||||||
{&EIDRM, "EIDRM"},
|
|
||||||
{&ETIME, "ETIME"},
|
|
||||||
{&EPROTO, "EPROTO"},
|
|
||||||
{&EOVERFLOW, "EOVERFLOW"},
|
|
||||||
{&EILSEQ, "EILSEQ"},
|
|
||||||
{&EUSERS, "EUSERS"},
|
|
||||||
{&ENOTSOCK, "ENOTSOCK"},
|
|
||||||
{&EDESTADDRREQ, "EDESTADDRREQ"},
|
|
||||||
{&EMSGSIZE, "EMSGSIZE"},
|
|
||||||
{&EPROTOTYPE, "EPROTOTYPE"},
|
|
||||||
{&ENOPROTOOPT, "ENOPROTOOPT"},
|
|
||||||
{&EPROTONOSUPPORT, "EPROTONOSUPPORT"},
|
|
||||||
{&ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT"},
|
|
||||||
{&ENOTSUP, "ENOTSUP"},
|
|
||||||
{&EOPNOTSUPP, "EOPNOTSUPP"},
|
|
||||||
{&EPFNOSUPPORT, "EPFNOSUPPORT"},
|
|
||||||
{&EAFNOSUPPORT, "EAFNOSUPPORT"},
|
|
||||||
{&EADDRINUSE, "EADDRINUSE"},
|
|
||||||
{&EADDRNOTAVAIL, "EADDRNOTAVAIL"},
|
|
||||||
{&ENETDOWN, "ENETDOWN"},
|
|
||||||
{&ENETUNREACH, "ENETUNREACH"},
|
|
||||||
{&ENETRESET, "ENETRESET"},
|
|
||||||
{&ECONNABORTED, "ECONNABORTED"},
|
|
||||||
{&ECONNRESET, "ECONNRESET"},
|
|
||||||
{&ENOBUFS, "ENOBUFS"},
|
|
||||||
{&EISCONN, "EISCONN"},
|
|
||||||
{&ENOTCONN, "ENOTCONN"},
|
|
||||||
{&ESHUTDOWN, "ESHUTDOWN"},
|
|
||||||
{&ETOOMANYREFS, "ETOOMANYREFS"},
|
|
||||||
{&ETIMEDOUT, "ETIMEDOUT"},
|
|
||||||
{&ECONNREFUSED, "ECONNREFUSED"},
|
|
||||||
{&EHOSTDOWN, "EHOSTDOWN"},
|
|
||||||
{&EHOSTUNREACH, "EHOSTUNREACH"},
|
|
||||||
{&EALREADY, "EALREADY"},
|
|
||||||
{&EINPROGRESS, "EINPROGRESS"},
|
|
||||||
{&ESTALE, "ESTALE"},
|
|
||||||
{&EREMOTE, "EREMOTE"},
|
|
||||||
{&EBADMSG, "EBADMSG"},
|
|
||||||
{&ECANCELED, "ECANCELED"},
|
|
||||||
{&EOWNERDEAD, "EOWNERDEAD"},
|
|
||||||
{&ENOTRECOVERABLE, "ENOTRECOVERABLE"},
|
|
||||||
{&ENONET, "ENONET"},
|
|
||||||
{&ERESTART, "ERESTART"},
|
|
||||||
{&ECHRNG, "ECHRNG"},
|
|
||||||
{&EL2NSYNC, "EL2NSYNC"},
|
|
||||||
{&EL3HLT, "EL3HLT"},
|
|
||||||
{&EL3RST, "EL3RST"},
|
|
||||||
{&ELNRNG, "ELNRNG"},
|
|
||||||
{&EUNATCH, "EUNATCH"},
|
|
||||||
{&ENOCSI, "ENOCSI"},
|
|
||||||
{&EL2HLT, "EL2HLT"},
|
|
||||||
{&EBADE, "EBADE"},
|
|
||||||
{&EBADR, "EBADR"},
|
|
||||||
{&EXFULL, "EXFULL"},
|
|
||||||
{&ENOANO, "ENOANO"},
|
|
||||||
{&EBADRQC, "EBADRQC"},
|
|
||||||
{&EBADSLT, "EBADSLT"},
|
|
||||||
{&ENOSTR, "ENOSTR"},
|
|
||||||
{&ENODATA, "ENODATA"},
|
|
||||||
{&ENOSR, "ENOSR"},
|
|
||||||
{&ENOPKG, "ENOPKG"},
|
|
||||||
{&ENOLINK, "ENOLINK"},
|
|
||||||
{&EADV, "EADV"},
|
|
||||||
{&ESRMNT, "ESRMNT"},
|
|
||||||
{&ECOMM, "ECOMM"},
|
|
||||||
{&EMULTIHOP, "EMULTIHOP"},
|
|
||||||
{&EDOTDOT, "EDOTDOT"},
|
|
||||||
{&ENOTUNIQ, "ENOTUNIQ"},
|
|
||||||
{&EBADFD, "EBADFD"},
|
|
||||||
{&EREMCHG, "EREMCHG"},
|
|
||||||
{&ELIBACC, "ELIBACC"},
|
|
||||||
{&ELIBBAD, "ELIBBAD"},
|
|
||||||
{&ELIBSCN, "ELIBSCN"},
|
|
||||||
{&ELIBMAX, "ELIBMAX"},
|
|
||||||
{&ELIBEXEC, "ELIBEXEC"},
|
|
||||||
{&ESTRPIPE, "ESTRPIPE"},
|
|
||||||
{&EUCLEAN, "EUCLEAN"},
|
|
||||||
{&ENOTNAM, "ENOTNAM"},
|
|
||||||
{&ENAVAIL, "ENAVAIL"},
|
|
||||||
{&EISNAM, "EISNAM"},
|
|
||||||
{&EREMOTEIO, "EREMOTEIO"},
|
|
||||||
{&ENOMEDIUM, "ENOMEDIUM"},
|
|
||||||
{&EMEDIUMTYPE, "EMEDIUMTYPE"},
|
|
||||||
{&ENOKEY, "ENOKEY"},
|
|
||||||
{&EKEYEXPIRED, "EKEYEXPIRED"},
|
|
||||||
{&EKEYREVOKED, "EKEYREVOKED"},
|
|
||||||
{&EKEYREJECTED, "EKEYREJECTED"},
|
|
||||||
{&ERFKILL, "ERFKILL"},
|
|
||||||
{&EHWPOISON, "EHWPOISON"},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *geterrname(long x) {
|
static const char *GetErrorName(long x) {
|
||||||
int i;
|
int i;
|
||||||
if (x) {
|
if (x) {
|
||||||
for (i = 0; i < ARRAYLEN(kErrors); ++i) {
|
for (i = 0; kErrorNames[i].x; ++i) {
|
||||||
if (x == *kErrors[i].x) {
|
if (x == *(const long *)((uintptr_t)kErrorNames + kErrorNames[i].x)) {
|
||||||
return kErrors[i].s;
|
return (const char *)((uintptr_t)kErrorNames + kErrorNames[i].s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,7 +52,7 @@ int strerror_r(int err, char *buf, size_t size) {
|
||||||
char *p;
|
char *p;
|
||||||
const char *s;
|
const char *s;
|
||||||
err &= 0xFFFF;
|
err &= 0xFFFF;
|
||||||
s = geterrname(err);
|
s = GetErrorName(err);
|
||||||
p = buf;
|
p = buf;
|
||||||
if (strlen(s) + 1 + 5 + 1 + 1 <= size) {
|
if (strlen(s) + 1 + 5 + 1 + 1 <= size) {
|
||||||
p = stpcpy(p, s);
|
p = stpcpy(p, s);
|
||||||
|
|
|
@ -24,6 +24,7 @@ _peekall:
|
||||||
.leafprologue
|
.leafprologue
|
||||||
ezlea _base,si
|
ezlea _base,si
|
||||||
ezlea _end,cx
|
ezlea _end,cx
|
||||||
|
add $0x1000,%rsi
|
||||||
0: mov (%rsi),%eax
|
0: mov (%rsi),%eax
|
||||||
add $PAGESIZE,%rsi
|
add $PAGESIZE,%rsi
|
||||||
cmp %rcx,%rsi
|
cmp %rcx,%rsi
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "net/http/http.h"
|
#include "net/http/http.h"
|
||||||
|
|
||||||
static const struct HttpReason {
|
static const struct thatispacked HttpReason {
|
||||||
int code;
|
short code;
|
||||||
const char *name;
|
const char *name;
|
||||||
} kHttpReason[] = {
|
} kHttpReason[] = {
|
||||||
{100, "Continue"},
|
{100, "Continue"},
|
||||||
|
|
|
@ -33,13 +33,14 @@
|
||||||
ssize_t HasControlCodes(const char *p, size_t n, int f) {
|
ssize_t HasControlCodes(const char *p, size_t n, int f) {
|
||||||
char t[256];
|
char t[256];
|
||||||
wint_t x, a, b;
|
wint_t x, a, b;
|
||||||
size_t i, j, m;
|
size_t i, j, m, g;
|
||||||
memset(t, 0, sizeof(t));
|
memset(t, 0, sizeof(t));
|
||||||
if (f & kControlC0) memset(t + 0x00, 1, 0x20 - 0x00), t[0x7F] = 1;
|
if (f & kControlC0) memset(t + 0x00, 1, 0x20 - 0x00), t[0x7F] = 1;
|
||||||
if (f & kControlC1) memset(t + 0x80, 1, 0xA0 - 0x80);
|
if (f & kControlC1) memset(t + 0x80, 1, 0xA0 - 0x80);
|
||||||
t['\t'] = t['\r'] = t['\n'] = t['\v'] = !!(f & kControlWs);
|
t['\t'] = t['\r'] = t['\n'] = t['\v'] = !!(f & kControlWs);
|
||||||
if (n == -1) n = p ? strlen(p) : 0;
|
if (n == -1) n = p ? strlen(p) : 0;
|
||||||
for (i = 0; i < n;) {
|
for (i = 0; i < n;) {
|
||||||
|
g = i;
|
||||||
x = p[i++] & 0xff;
|
x = p[i++] & 0xff;
|
||||||
if (UNLIKELY(x >= 0300)) {
|
if (UNLIKELY(x >= 0300)) {
|
||||||
a = ThomPikeByte(x);
|
a = ThomPikeByte(x);
|
||||||
|
@ -58,7 +59,7 @@ ssize_t HasControlCodes(const char *p, size_t n, int f) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (x < 256 && t[x]) {
|
if (x < 256 && t[x]) {
|
||||||
return i - 1;
|
return g;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -28,16 +28,13 @@
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
|
||||||
/* TODO(jart): Finish this */
|
|
||||||
|
|
||||||
STATIC_YOINK("zip_uri_support");
|
STATIC_YOINK("zip_uri_support");
|
||||||
STATIC_YOINK("o/" MODE "/tool/net/redbean.com");
|
STATIC_YOINK("o/" MODE "/tool/net/redbean.com");
|
||||||
char testlib_enable_tmp_setup_teardown;
|
char testlib_enable_tmp_setup_teardown;
|
||||||
|
|
||||||
void SetUp(void) {
|
void SetUp(void) {
|
||||||
return;
|
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
char buf[512];
|
char buf[1024];
|
||||||
int fdin, fdout;
|
int fdin, fdout;
|
||||||
ASSERT_NE(-1, mkdir("bin", 0755));
|
ASSERT_NE(-1, mkdir("bin", 0755));
|
||||||
ASSERT_NE(-1, (fdin = open("zip:o/" MODE "/tool/net/redbean.com", O_RDONLY)));
|
ASSERT_NE(-1, (fdin = open("zip:o/" MODE "/tool/net/redbean.com", O_RDONLY)));
|
||||||
|
@ -45,22 +42,22 @@ void SetUp(void) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ASSERT_NE(-1, (n = read(fdin, buf, sizeof(buf))));
|
ASSERT_NE(-1, (n = read(fdin, buf, sizeof(buf))));
|
||||||
if (!n) break;
|
if (!n) break;
|
||||||
ASSERT_EQ(n, write(fdout, buf, sizeof(buf)));
|
ASSERT_EQ(n, write(fdout, buf, n));
|
||||||
}
|
}
|
||||||
close(fdout);
|
close(fdout);
|
||||||
close(fdin);
|
close(fdin);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(redbean, test) {
|
TEST(redbean, test) {
|
||||||
return;
|
|
||||||
char portbuf[16];
|
char portbuf[16];
|
||||||
int pid, port, pipefds[2];
|
int pid, port, pipefds[2];
|
||||||
sigset_t chldmask, savemask;
|
sigset_t chldmask, savemask;
|
||||||
sigaddset(&chldmask, SIGCHLD);
|
sigaddset(&chldmask, SIGCHLD);
|
||||||
sigprocmask(SIG_BLOCK, &chldmask, &savemask);
|
sigprocmask(SIG_BLOCK, &chldmask, &savemask);
|
||||||
ASSERT_NE(-1, pipe2(pipefds, O_CLOEXEC));
|
ASSERT_NE(-1, pipe(pipefds));
|
||||||
ASSERT_NE(-1, (pid = vfork()));
|
ASSERT_NE(-1, (pid = vfork()));
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
|
close(pipefds[0]);
|
||||||
dup2(pipefds[1], 1);
|
dup2(pipefds[1], 1);
|
||||||
sigprocmask(SIG_SETMASK, &savemask, NULL);
|
sigprocmask(SIG_SETMASK, &savemask, NULL);
|
||||||
execv("bin/redbean.com",
|
execv("bin/redbean.com",
|
||||||
|
@ -71,6 +68,7 @@ TEST(redbean, test) {
|
||||||
EXPECT_NE(-1, read(pipefds[0], portbuf, sizeof(portbuf)));
|
EXPECT_NE(-1, read(pipefds[0], portbuf, sizeof(portbuf)));
|
||||||
port = atoi(portbuf);
|
port = atoi(portbuf);
|
||||||
printf("port %d\n", port);
|
printf("port %d\n", port);
|
||||||
|
fflush(stdout);
|
||||||
EXPECT_NE(-1, kill(pid, SIGTERM));
|
EXPECT_NE(-1, kill(pid, SIGTERM));
|
||||||
EXPECT_NE(-1, wait(0));
|
EXPECT_NE(-1, wait(0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "libc/sysv/consts/inaddr.h"
|
#include "libc/sysv/consts/inaddr.h"
|
||||||
#include "libc/sysv/consts/ipproto.h"
|
#include "libc/sysv/consts/ipproto.h"
|
||||||
#include "libc/sysv/consts/itimer.h"
|
#include "libc/sysv/consts/itimer.h"
|
||||||
|
#include "libc/sysv/consts/madv.h"
|
||||||
#include "libc/sysv/consts/map.h"
|
#include "libc/sysv/consts/map.h"
|
||||||
#include "libc/sysv/consts/msync.h"
|
#include "libc/sysv/consts/msync.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
|
@ -1246,7 +1247,8 @@ static void ReportWorkerResources(int pid, struct rusage *ru) {
|
||||||
AppendResourceReport(ru, "\n");
|
AppendResourceReport(ru, "\n");
|
||||||
if (outbuf.n) {
|
if (outbuf.n) {
|
||||||
if ((s = IndentLines(outbuf.p, outbuf.n - 1, 0, 1))) {
|
if ((s = IndentLines(outbuf.p, outbuf.n - 1, 0, 1))) {
|
||||||
LOGF("resource report for pid %d\n%s", pid, s);
|
flogf(kLogInfo, __FILE__, __LINE__, NULL,
|
||||||
|
"resource report for pid %d\n%s", pid, s);
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
ClearOutput();
|
ClearOutput();
|
||||||
|
@ -1415,7 +1417,7 @@ static bool IsCompressionMethodSupported(int method) {
|
||||||
|
|
||||||
static void IndexAssets(void) {
|
static void IndexAssets(void) {
|
||||||
int64_t lm;
|
int64_t lm;
|
||||||
uint64_t cf, lf;
|
uint64_t cf;
|
||||||
struct Asset *p;
|
struct Asset *p;
|
||||||
uint32_t i, n, m, step, hash;
|
uint32_t i, n, m, step, hash;
|
||||||
CHECK_GE(HASH_LOAD_FACTOR, 2);
|
CHECK_GE(HASH_LOAD_FACTOR, 2);
|
||||||
|
@ -1426,10 +1428,9 @@ static void IndexAssets(void) {
|
||||||
p = xcalloc(m, sizeof(struct Asset));
|
p = xcalloc(m, sizeof(struct Asset));
|
||||||
for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
|
for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
|
||||||
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
|
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
|
||||||
lf = GetZipCfileOffset(zmap + cf);
|
if (!IsCompressionMethodSupported(ZIP_CFILE_COMPRESSIONMETHOD(zmap + cf))) {
|
||||||
if (!IsCompressionMethodSupported(ZIP_LFILE_COMPRESSIONMETHOD(zmap + lf))) {
|
|
||||||
LOGF("don't understand zip compression method %d used by %`'.*s",
|
LOGF("don't understand zip compression method %d used by %`'.*s",
|
||||||
ZIP_LFILE_COMPRESSIONMETHOD(zmap + lf),
|
ZIP_CFILE_COMPRESSIONMETHOD(zmap + cf),
|
||||||
ZIP_CFILE_NAMESIZE(zmap + cf), ZIP_CFILE_NAME(zmap + cf));
|
ZIP_CFILE_NAMESIZE(zmap + cf), ZIP_CFILE_NAME(zmap + cf));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1441,8 +1442,8 @@ static void IndexAssets(void) {
|
||||||
} while (p[i].hash);
|
} while (p[i].hash);
|
||||||
lm = GetZipCfileLastModified(zmap + cf);
|
lm = GetZipCfileLastModified(zmap + cf);
|
||||||
p[i].hash = hash;
|
p[i].hash = hash;
|
||||||
p[i].lf = lf;
|
|
||||||
p[i].cf = cf;
|
p[i].cf = cf;
|
||||||
|
p[i].lf = GetZipCfileOffset(zmap + cf);
|
||||||
p[i].istext = !!(ZIP_CFILE_INTERNALATTRIBUTES(zmap + cf) & kZipIattrText);
|
p[i].istext = !!(ZIP_CFILE_INTERNALATTRIBUTES(zmap + cf) & kZipIattrText);
|
||||||
p[i].lastmodified = lm;
|
p[i].lastmodified = lm;
|
||||||
p[i].lastmodifiedstr = FormatUnixHttpDateTime(xmalloc(30), lm);
|
p[i].lastmodifiedstr = FormatUnixHttpDateTime(xmalloc(30), lm);
|
||||||
|
@ -1476,8 +1477,8 @@ static struct Asset *GetAssetZip(const char *path, size_t pathlen) {
|
||||||
i = (hash + (step * (step + 1)) >> 1) & (assets.n - 1);
|
i = (hash + (step * (step + 1)) >> 1) & (assets.n - 1);
|
||||||
if (!assets.p[i].hash) return NULL;
|
if (!assets.p[i].hash) return NULL;
|
||||||
if (hash == assets.p[i].hash &&
|
if (hash == assets.p[i].hash &&
|
||||||
pathlen == ZIP_LFILE_NAMESIZE(zmap + assets.p[i].lf) &&
|
pathlen == ZIP_CFILE_NAMESIZE(zmap + assets.p[i].cf) &&
|
||||||
memcmp(path, ZIP_LFILE_NAME(zmap + assets.p[i].lf), pathlen) == 0) {
|
memcmp(path, ZIP_CFILE_NAME(zmap + assets.p[i].cf), pathlen) == 0) {
|
||||||
return &assets.p[i];
|
return &assets.p[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2034,13 +2035,13 @@ static int GetOctalWidth(int x) {
|
||||||
return !x ? 1 : x < 8 ? 2 : 1 + bsr(x) / 3;
|
return !x ? 1 : x < 8 ? 2 : 1 + bsr(x) / 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *DescribeCompressionRatio(char rb[8], uint64_t lf) {
|
static const char *DescribeCompressionRatio(char rb[8], uint64_t cf) {
|
||||||
long percent;
|
long percent;
|
||||||
if (ZIP_LFILE_COMPRESSIONMETHOD(zmap + lf) == kZipCompressionNone) {
|
if (ZIP_CFILE_COMPRESSIONMETHOD(zmap + cf) == kZipCompressionNone) {
|
||||||
return "n/a";
|
return "n/a";
|
||||||
} else {
|
} else {
|
||||||
percent = lround(100 - (double)GetZipLfileCompressedSize(zmap + lf) /
|
percent = lround(100 - (double)GetZipCfileCompressedSize(zmap + cf) /
|
||||||
GetZipLfileUncompressedSize(zmap + lf) * 100);
|
GetZipCfileUncompressedSize(zmap + cf) * 100);
|
||||||
sprintf(rb, "%ld%%", MIN(999, MAX(-999, percent)));
|
sprintf(rb, "%ld%%", MIN(999, MAX(-999, percent)));
|
||||||
return rb;
|
return rb;
|
||||||
}
|
}
|
||||||
|
@ -2095,7 +2096,7 @@ td { padding-right: 3em; }\r\n\
|
||||||
if (!IsHiddenPath(path)) {
|
if (!IsHiddenPath(path)) {
|
||||||
w[0] = min(80, max(w[0], strwidth(path, 0) + 2));
|
w[0] = min(80, max(w[0], strwidth(path, 0) + 2));
|
||||||
w[1] = max(w[1], GetOctalWidth(GetZipCfileMode(zmap + cf)));
|
w[1] = max(w[1], GetOctalWidth(GetZipCfileMode(zmap + cf)));
|
||||||
w[2] = max(w[2], GetDecimalWidth(GetZipLfileUncompressedSize(zmap + lf)));
|
w[2] = max(w[2], GetDecimalWidth(GetZipCfileUncompressedSize(zmap + cf)));
|
||||||
}
|
}
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
|
@ -2117,17 +2118,17 @@ td { padding-right: 3em; }\r\n\
|
||||||
localtime_r(&lastmod, &tm);
|
localtime_r(&lastmod, &tm);
|
||||||
strftime(tb, sizeof(tb), "%Y-%m-%d %H:%M:%S %Z", &tm);
|
strftime(tb, sizeof(tb), "%Y-%m-%d %H:%M:%S %Z", &tm);
|
||||||
if (IsCompressionMethodSupported(
|
if (IsCompressionMethodSupported(
|
||||||
ZIP_LFILE_COMPRESSIONMETHOD(zmap + lf)) &&
|
ZIP_CFILE_COMPRESSIONMETHOD(zmap + cf)) &&
|
||||||
IsAcceptablePath(path, pathlen)) {
|
IsAcceptablePath(path, pathlen)) {
|
||||||
Append("<a href=\"%.*s\">%-*.*s</a> %s %0*o %4s %,*ld %'s\r\n",
|
Append("<a href=\"%.*s\">%-*.*s</a> %s %0*o %4s %,*ld %'s\r\n",
|
||||||
rn[2], rp[2], w[0], rn[4], rp[4], tb, w[1],
|
rn[2], rp[2], w[0], rn[4], rp[4], tb, w[1],
|
||||||
GetZipCfileMode(zmap + cf), DescribeCompressionRatio(rb, lf),
|
GetZipCfileMode(zmap + cf), DescribeCompressionRatio(rb, cf),
|
||||||
w[2], GetZipLfileUncompressedSize(zmap + lf), rp[3]);
|
w[2], GetZipCfileUncompressedSize(zmap + cf), rp[3]);
|
||||||
} else {
|
} else {
|
||||||
Append("%-*.*s %s %0*o %4s %,*ld %'s\r\n", w[0], rn[4], rp[4], tb,
|
Append("%-*.*s %s %0*o %4s %,*ld %'s\r\n", w[0], rn[4], rp[4], tb,
|
||||||
w[1], GetZipCfileMode(zmap + cf),
|
w[1], GetZipCfileMode(zmap + cf),
|
||||||
DescribeCompressionRatio(rb, lf), w[2],
|
DescribeCompressionRatio(rb, cf), w[2],
|
||||||
GetZipLfileUncompressedSize(zmap + lf), rp[3]);
|
GetZipCfileUncompressedSize(zmap + cf), rp[3]);
|
||||||
}
|
}
|
||||||
free(rp[4]);
|
free(rp[4]);
|
||||||
free(rp[3]);
|
free(rp[3]);
|
||||||
|
@ -4592,7 +4593,11 @@ void RedBean(int argc, char *argv[]) {
|
||||||
printf("%d\n", ntohs(serveraddr.sin_port));
|
printf("%d\n", ntohs(serveraddr.sin_port));
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
if (daemonize) Daemonize();
|
if (daemonize) {
|
||||||
|
Daemonize();
|
||||||
|
} else {
|
||||||
|
setpgid(getpid(), getpid());
|
||||||
|
}
|
||||||
if (setitimer(ITIMER_REAL, &kHeartbeat, NULL) == -1) {
|
if (setitimer(ITIMER_REAL, &kHeartbeat, NULL) == -1) {
|
||||||
heartless = true;
|
heartless = true;
|
||||||
}
|
}
|
||||||
|
@ -4602,9 +4607,9 @@ void RedBean(int argc, char *argv[]) {
|
||||||
unmaplist.c = 1;
|
unmaplist.c = 1;
|
||||||
unmaplist.p = xcalloc(unmaplist.c, sizeof(*unmaplist.p));
|
unmaplist.p = xcalloc(unmaplist.c, sizeof(*unmaplist.p));
|
||||||
hdrbuf.n = 4 * 1024;
|
hdrbuf.n = 4 * 1024;
|
||||||
hdrbuf.p = xvalloc(hdrbuf.n);
|
hdrbuf.p = xmalloc(hdrbuf.n);
|
||||||
inbuf.n = maxpayloadsize;
|
inbuf.n = maxpayloadsize;
|
||||||
inbuf.p = xvalloc(inbuf.n);
|
inbuf.p = xmalloc(inbuf.n);
|
||||||
while (!terminated) {
|
while (!terminated) {
|
||||||
if (zombied) {
|
if (zombied) {
|
||||||
ReapZombies();
|
ReapZombies();
|
||||||
|
|
Loading…
Add table
Reference in a new issue