mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 13:52:28 +00:00
Escape LaunchBrowser path
This also fix a bug where CTRL-C'ing redbean on Linux would kill the browser process. It furthermore fixes a regression with the APE self repair process that happened in a recent change. See #158
This commit is contained in:
parent
6215c91e90
commit
2d34819779
2 changed files with 64 additions and 25 deletions
|
@ -1,7 +1,10 @@
|
||||||
-- /.init.lua is loaded at startup in redbean's main process
|
-- /.init.lua is loaded at startup in redbean's main process
|
||||||
|
|
||||||
HidePath('/usr/share/zoneinfo/')
|
HidePath('/usr/share/zoneinfo/')
|
||||||
|
|
||||||
|
-- open a browser tab using explorer/open/xdg-open
|
||||||
|
-- LaunchBrowser('/tool/net/demo/index.html')
|
||||||
|
|
||||||
|
-- this intercepts all requests if it's defined
|
||||||
function OnHttpRequest()
|
function OnHttpRequest()
|
||||||
if HasParam('magic') then
|
if HasParam('magic') then
|
||||||
Write('<p>\r\n')
|
Write('<p>\r\n')
|
||||||
|
@ -11,7 +14,7 @@ function OnHttpRequest()
|
||||||
Write(EscapeHtml(LoadAsset('/.init.lua')))
|
Write(EscapeHtml(LoadAsset('/.init.lua')))
|
||||||
Write('</pre>\r\n')
|
Write('</pre>\r\n')
|
||||||
else
|
else
|
||||||
Route()
|
Route() -- this asks redbean to do the default thing
|
||||||
end
|
end
|
||||||
SetHeader('Server', 'redbean!')
|
SetHeader('Server', 'redbean!')
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,8 +19,10 @@
|
||||||
#include "libc/bits/popcnt.h"
|
#include "libc/bits/popcnt.h"
|
||||||
#include "libc/bits/safemacros.internal.h"
|
#include "libc/bits/safemacros.internal.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/calls/sigbits.h"
|
||||||
#include "libc/calls/struct/itimerval.h"
|
#include "libc/calls/struct/itimerval.h"
|
||||||
#include "libc/calls/struct/rusage.h"
|
#include "libc/calls/struct/rusage.h"
|
||||||
|
#include "libc/calls/struct/sigaction.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/fmt/conv.h"
|
||||||
|
@ -33,6 +35,7 @@
|
||||||
#include "libc/nexgen32e/bsr.h"
|
#include "libc/nexgen32e/bsr.h"
|
||||||
#include "libc/nexgen32e/crc32.h"
|
#include "libc/nexgen32e/crc32.h"
|
||||||
#include "libc/runtime/clktck.h"
|
#include "libc/runtime/clktck.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
|
@ -2003,26 +2006,61 @@ static char *GetBasicAuthorization(size_t *z) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LaunchBrowser(const char *path) {
|
static const char *GetSystemUrlLauncherCommand(void) {
|
||||||
char openbrowsercommand[255];
|
|
||||||
char *prog;
|
|
||||||
if (IsWindows()) {
|
if (IsWindows()) {
|
||||||
prog = "explorer";
|
return "explorer";
|
||||||
} else if (IsXnu()) {
|
} else if (IsXnu()) {
|
||||||
prog = "open";
|
return "open";
|
||||||
} else {
|
} else {
|
||||||
prog = "xdg-open";
|
return "xdg-open";
|
||||||
}
|
}
|
||||||
struct in_addr addr = serveraddr.sin_addr;
|
|
||||||
if (addr.s_addr == INADDR_ANY) addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
||||||
const char *pathname = path;
|
|
||||||
if (path == NULL) {
|
|
||||||
pathname = "/";
|
|
||||||
}
|
}
|
||||||
snprintf(openbrowsercommand, sizeof(openbrowsercommand), "%s http://%s:%d%s",
|
|
||||||
prog, inet_ntoa(addr), ntohs(serveraddr.sin_port), pathname);
|
static void LaunchBrowser(const char *path) {
|
||||||
DEBUGF("Opening browser with command %s\n", openbrowsercommand);
|
int pid, ws;
|
||||||
system(openbrowsercommand);
|
struct in_addr addr;
|
||||||
|
const char *u, *prog;
|
||||||
|
sigset_t chldmask, savemask;
|
||||||
|
struct sigaction ignore, saveint, savequit;
|
||||||
|
path = firstnonnull(path, "/");
|
||||||
|
addr = serveraddr.sin_addr;
|
||||||
|
if (!addr.s_addr) addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
|
if (*path != '/') path = gc(xasprintf("/%s", path));
|
||||||
|
if ((prog = commandv(GetSystemUrlLauncherCommand(), gc(malloc(PATH_MAX))))) {
|
||||||
|
u = gc(xasprintf("http://%s:%d%s", inet_ntoa(addr),
|
||||||
|
ntohs(serveraddr.sin_port), gc(EscapePath(path, -1, 0))));
|
||||||
|
DEBUGF("opening browser with command %s %s\n", prog, u);
|
||||||
|
ignore.sa_flags = 0;
|
||||||
|
ignore.sa_handler = SIG_IGN;
|
||||||
|
sigemptyset(&ignore.sa_mask);
|
||||||
|
sigaction(SIGINT, &ignore, &saveint);
|
||||||
|
sigaction(SIGQUIT, &ignore, &savequit);
|
||||||
|
sigemptyset(&chldmask);
|
||||||
|
sigaddset(&chldmask, SIGCHLD);
|
||||||
|
sigprocmask(SIG_BLOCK, &chldmask, &savemask);
|
||||||
|
CHECK_NE(-1, (pid = fork()));
|
||||||
|
if (!pid) {
|
||||||
|
setpgid(getpid(), getpid());
|
||||||
|
sigaction(SIGINT, &saveint, 0);
|
||||||
|
sigaction(SIGQUIT, &savequit, 0);
|
||||||
|
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||||
|
execv(prog, (char *const[]){prog, u, 0});
|
||||||
|
_exit(127);
|
||||||
|
}
|
||||||
|
while (wait4(pid, &ws, 0, 0) == -1) {
|
||||||
|
CHECK_EQ(EINTR, errno);
|
||||||
|
}
|
||||||
|
sigaction(SIGINT, &saveint, 0);
|
||||||
|
sigaction(SIGQUIT, &savequit, 0);
|
||||||
|
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||||
|
if (!(WIFEXITED(ws) && WEXITSTATUS(ws) == 0)) {
|
||||||
|
WARNF("%s failed with %d", GetSystemUrlLauncherCommand(),
|
||||||
|
WIFEXITED(ws) ? WEXITSTATUS(ws) : 128 + WEXITSTATUS(ws));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
WARNF("can't launch browser because %s isn't installed",
|
||||||
|
GetSystemUrlLauncherCommand());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *BadMethod(void) {
|
static char *BadMethod(void) {
|
||||||
|
@ -3555,8 +3593,7 @@ static void LuaSetIntField(lua_State *L, const char *k, lua_Integer v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int LuaLaunchBrowser(lua_State *L) {
|
static int LuaLaunchBrowser(lua_State *L) {
|
||||||
const char *p = luaL_optstring(L, 1, "/");
|
LaunchBrowser(luaL_optstring(L, 1, "/"));
|
||||||
LaunchBrowser(p);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4530,6 +4567,7 @@ static void TuneSockets(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RestoreApe(void) {
|
static void RestoreApe(void) {
|
||||||
|
int fd;
|
||||||
char *p;
|
char *p;
|
||||||
size_t n;
|
size_t n;
|
||||||
struct Asset *a;
|
struct Asset *a;
|
||||||
|
@ -4538,16 +4576,14 @@ static void RestoreApe(void) {
|
||||||
if (IsOpenbsd()) return; /* TODO */
|
if (IsOpenbsd()) return; /* TODO */
|
||||||
if (IsNetbsd()) return; /* TODO */
|
if (IsNetbsd()) return; /* TODO */
|
||||||
if (endswith(zpath, ".com.dbg")) return;
|
if (endswith(zpath, ".com.dbg")) return;
|
||||||
close(OpenExecutable());
|
fd = OpenExecutable();
|
||||||
if ((a = GetAssetZip("/.ape", 5)) && (p = LoadAsset(a, &n))) {
|
if ((a = GetAssetZip("/.ape", 5)) && (p = LoadAsset(a, &n))) {
|
||||||
mprotect(ape_rom_vaddr, PAGESIZE, PROT_READ | PROT_WRITE);
|
write(fd, p, n);
|
||||||
memcpy(ape_rom_vaddr, p, MIN(n, PAGESIZE));
|
|
||||||
msync(ape_rom_vaddr, PAGESIZE, MS_ASYNC);
|
|
||||||
mprotect(ape_rom_vaddr, PAGESIZE, PROT_NONE);
|
|
||||||
free(p);
|
free(p);
|
||||||
} else {
|
} else {
|
||||||
LOGF("/.ape not found");
|
WARNF("/.ape not found");
|
||||||
}
|
}
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RedBean(int argc, char *argv[]) {
|
void RedBean(int argc, char *argv[]) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue