diff --git a/libc/runtime/openexecutable.S b/libc/runtime/openexecutable.S index 71babb8f..24750acd 100644 --- a/libc/runtime/openexecutable.S +++ b/libc/runtime/openexecutable.S @@ -40,9 +40,7 @@ OpenExecutable: pushq MAP_ANONYMOUS(%rip) # -0x28(%rbp) pushq MAP_PRIVATE(%rip) # -0x30(%rbp) pushq MAP_FIXED(%rip) # -0x38(%rbp) - pushq MAP_SHARED(%rip) # -0x40(%rbp) - pushq __NR_mprotect(%rip) # -0x48(%rbp) - pushq __NR_mprotect(%rip) # -0x50(%rbp) + pushq __NR_mprotect(%rip) # -0x40(%rbp) push %rbx # code buffer push %r12 # data buffer push %r14 # filename @@ -98,7 +96,7 @@ OpenExecutable: rep movsb // Change protection. - mov -0x48(%rbp),%eax # __NR_mprotect + mov -0x40(%rbp),%eax # __NR_mprotect mov %rbx,%rdi mov $PAGESIZE,%esi mov $PROT_READ|PROT_EXEC,%edx @@ -133,7 +131,7 @@ OpenExecutable: mov $ape_rom_filesz,%esi mov $PROT_READ|PROT_EXEC,%edx mov -0x38(%rbp),%r10d # MAP_FIXED - or -0x40(%rbp),%r10d # MAP_SHARED + or -0x30(%rbp),%r10d # MAP_PRIVATE mov %r15d,%r8d mov $ape_rom_offset,%r9d push %r9 # openbsd:pad diff --git a/tool/net/redbean.c b/tool/net/redbean.c index 0ff6e3d0..eac8ce6a 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -241,6 +241,7 @@ static struct Assets { static struct Shared { int workers; long double nowish; + long double lastreindex; long double lastmeltdown; char currentdate[32]; struct rusage server; @@ -318,6 +319,7 @@ static struct Shared { long readresets; long readtimeouts; long redirects; + long reindexes; long reloads; long rewrites; long serveroptions; @@ -379,13 +381,14 @@ static uint32_t clientaddrsize; static lua_State *L; static size_t zsize; static char *content; -static uint8_t *cdir; static uint8_t *zmap; +static uint8_t *zcdir; static size_t hdrsize; static size_t msgsize; static size_t amtread; static char *extrahdrs; static char *luaheaderp; +static const char *zpath; static const char *brand; static const char *pidpath; static const char *logpath; @@ -408,6 +411,7 @@ static struct Url url; static struct HttpRequest msg; static char slashpath[PATH_MAX]; +static struct stat zst; static long double startread; static long double lastrefresh; static long double startserver; @@ -1415,12 +1419,12 @@ static void IndexAssets(void) { struct Asset *p; uint32_t i, n, m, step, hash; CHECK_GE(HASH_LOAD_FACTOR, 2); - CHECK(READ32LE(cdir) == kZipCdir64HdrMagic || - READ32LE(cdir) == kZipCdirHdrMagic); - n = GetZipCdirRecords(cdir); + CHECK(READ32LE(zcdir) == kZipCdir64HdrMagic || + READ32LE(zcdir) == kZipCdirHdrMagic); + n = GetZipCdirRecords(zcdir); m = roundup2pow(MAX(1, n) * HASH_LOAD_FACTOR); p = xcalloc(m, sizeof(struct Asset)); - for (cf = GetZipCdirOffset(cdir); 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)); lf = GetZipCfileOffset(zmap + cf); if (!IsCompressionMethodSupported(ZIP_LFILE_COMPRESSIONMETHOD(zmap + lf))) { @@ -1447,17 +1451,17 @@ static void IndexAssets(void) { assets.n = m; } -static void OpenZip(const char *path) { +static void OpenZip(void) { int fd; uint8_t *p; - struct stat st; - CHECK_NE(-1, (fd = open(path, O_RDONLY))); - CHECK_NE(-1, fstat(fd, &st)); - CHECK((zsize = st.st_size)); + if (zmap) munmap(zmap, zsize); + CHECK_NE(-1, (fd = open(zpath, O_RDONLY))); + CHECK_NE(-1, fstat(fd, &zst)); + CHECK((zsize = zst.st_size)); CHECK_NE(MAP_FAILED, (zmap = mmap(NULL, zsize, PROT_READ, MAP_SHARED, fd, 0))); - CHECK_NOTNULL((cdir = GetZipCdir(zmap, zsize))); - if (endswith(path, ".com.dbg") && (p = memmem(zmap, zsize, "MZqFpD", 6))) { + CHECK_NOTNULL((zcdir = GetZipCdir(zmap, zsize))); + if (endswith(zpath, ".com.dbg") && (p = memmem(zmap, zsize, "MZqFpD", 6))) { zsize -= p - zmap; zmap = p; } @@ -2080,11 +2084,11 @@ td { padding-right: 3em; }\r\n\ "
\r\n",
- strnlen(GetZipCdirComment(cdir), GetZipCdirCommentSize(cdir)),
- GetZipCdirComment(cdir));
+ strnlen(GetZipCdirComment(zcdir), GetZipCdirCommentSize(zcdir)),
+ GetZipCdirComment(zcdir));
memset(w, 0, sizeof(w));
- n = GetZipCdirRecords(cdir);
- for (cf = GetZipCdirOffset(cdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
+ n = GetZipCdirRecords(zcdir);
+ for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
lf = GetZipCfileOffset(zmap + cf);
path = GetAssetPath(cf, &pathlen);
@@ -2095,8 +2099,8 @@ td { padding-right: 3em; }\r\n\
}
free(path);
}
- n = GetZipCdirRecords(cdir);
- for (cf = GetZipCdirOffset(cdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
+ n = GetZipCdirRecords(zcdir);
+ for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
lf = GetZipCfileOffset(zmap + cf);
path = GetAssetPath(cf, &pathlen);
@@ -2299,6 +2303,7 @@ static char *ServeStatusz(void) {
AppendLong1("readresets", shared->readresets);
AppendLong1("readtimeouts", shared->readtimeouts);
AppendLong1("redirects", shared->redirects);
+ AppendLong1("reindexes", shared->reindexes);
AppendLong1("reloads", shared->reloads);
AppendLong1("rewrites", shared->rewrites);
AppendLong1("serveroptions", shared->serveroptions);
@@ -2507,6 +2512,13 @@ static char *Route(const char *host, size_t hostlen, const char *path,
}
}
+static void Reindex(void) {
+ LockInc(&shared->reindexes);
+ LOGF("reindexing");
+ OpenZip();
+ IndexAssets();
+}
+
static const char *LuaCheckPath(lua_State *L, int idx, size_t *pathlen) {
const char *path;
if (lua_isnoneornil(L, idx)) {
@@ -3446,8 +3458,8 @@ static int LuaGetZipPaths(lua_State *L) {
size_t i, n, pathlen;
lua_newtable(L);
i = 0;
- n = GetZipCdirRecords(cdir);
- for (cf = GetZipCdirOffset(cdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
+ n = GetZipCdirRecords(zcdir);
+ for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
path = GetAssetPath(cf, &pathlen);
lua_pushlstring(L, path, pathlen);
@@ -3847,13 +3859,31 @@ static void LuaReload(void) {
}
static void HandleReload(void) {
+ LockInc(&shared->reloads);
LOGF("reloading");
+ Reindex();
LuaReload();
}
+static bool ZipCdirChanged(void) {
+ struct stat st;
+ if (!IsZipCdir32(zmap, zsize, zcdir - zmap) &&
+ !IsZipCdir64(zmap, zsize, zcdir - zmap)) {
+ return true;
+ }
+ if (stat(zpath, &st) != -1 && st.st_ino != zst.st_ino) {
+ return true;
+ }
+ return false;
+}
+
static void HandleHeartbeat(void) {
if (nowl() - lastrefresh > 60 * 60) RefreshTime();
UpdateCurrentDate(nowl());
+ if (ZipCdirChanged()) {
+ shared->lastreindex = nowl();
+ kill(0, SIGUSR1);
+ }
getrusage(RUSAGE_SELF, &shared->server);
#ifndef STATIC
LuaRun("/.heartbeat.lua");
@@ -4344,6 +4374,10 @@ static void HandleMessages(void) {
LogClose(DescribeClose());
return;
}
+ if (invalidated) {
+ HandleReload();
+ invalidated = false;
+ }
}
if (msgsize == amtread) {
amtread = 0;
@@ -4363,6 +4397,10 @@ static void HandleMessages(void) {
}
}
CollectGarbage();
+ if (invalidated) {
+ HandleReload();
+ invalidated = false;
+ }
}
}
@@ -4485,7 +4523,7 @@ static void TuneSockets(void) {
setsockopt(server, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
}
-static void RestoreApe(const char *prog) {
+static void RestoreApe(void) {
char *p;
size_t n;
struct Asset *a;
@@ -4493,7 +4531,7 @@ static void RestoreApe(const char *prog) {
if (IsWindows()) return; /* TODO */
if (IsOpenbsd()) return; /* TODO */
if (IsNetbsd()) return; /* TODO */
- if (endswith(prog, ".com.dbg")) return;
+ if (endswith(zpath, ".com.dbg")) return;
close(OpenExecutable());
if ((a = GetAssetZip("/.ape", 5)) && (p = LoadAsset(a, &n))) {
mprotect(ape_rom_vaddr, PAGESIZE, PROT_READ | PROT_WRITE);
@@ -4506,7 +4544,7 @@ static void RestoreApe(const char *prog) {
}
}
-void RedBean(int argc, char *argv[], const char *prog) {
+void RedBean(int argc, char *argv[]) {
uint32_t addrsize;
gmtoff = GetGmtOffset((lastrefresh = startserver = nowl()));
CHECK_GT(CLK_TCK, 0);
@@ -4514,9 +4552,10 @@ void RedBean(int argc, char *argv[], const char *prog) {
(shared = mmap(NULL, ROUNDUP(sizeof(struct Shared), FRAMESIZE),
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
-1, 0)));
- OpenZip(prog);
+ zpath = (const char *)getauxval(AT_EXECFN);
+ OpenZip();
IndexAssets();
- RestoreApe(prog);
+ RestoreApe();
SetDefaults();
GetOpts(argc, argv);
LuaInit();
@@ -4603,6 +4642,6 @@ int main(int argc, char *argv[]) {
setenv("GDB", "", true);
showcrashreports();
}
- RedBean(argc, argv, (const char *)getauxval(AT_EXECFN));
+ RedBean(argc, argv);
return 0;
}