Add missing ICANON features

This commit is contained in:
Justine Tunney 2024-09-05 03:17:19 -07:00
parent dd8544c3bd
commit 03875beadb
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
22 changed files with 526 additions and 251 deletions

View file

@ -453,8 +453,8 @@ void *ClientWorker(void *arg) {
char *addrstr, *origname;
unsigned char msg[4 + 1 + 4 + 4 + 4];
ts0 = timespec_real();
ts1 = timespec_real();
ts0 = timespec_mono();
ts1 = timespec_mono();
SetupPresharedKeySsl(MBEDTLS_SSL_IS_SERVER, g_psk);
defer(FreeClient, client);
@ -466,14 +466,14 @@ void *ClientWorker(void *arg) {
addrstr = DescribeAddress(&client->addr);
DEBUF("%s %s %s", DescribeAddress(&g_servaddr), "accepted", addrstr);
DEBUF("it took %'zu us to handshake client",
timespec_tomicros(timespec_sub(timespec_real(), ts1)));
timespec_tomicros(timespec_sub(timespec_mono(), ts1)));
// get the executable
ts1 = timespec_real();
ts2 = timespec_real();
ts1 = timespec_mono();
ts2 = timespec_mono();
Recv(client, msg, sizeof(msg));
DEBUF("it took %'zu us to receive #1",
timespec_tomicros(timespec_sub(timespec_real(), ts2)));
timespec_tomicros(timespec_sub(timespec_mono(), ts2)));
if (READ32BE(msg) != RUNITD_MAGIC) {
WARNF("%s magic mismatch!", addrstr);
pthread_exit(0);
@ -486,19 +486,19 @@ void *ClientWorker(void *arg) {
filesize = READ32BE(msg + 9);
crc = READ32BE(msg + 13);
origname = gc(calloc(1, namesize + 1));
ts2 = timespec_real();
ts2 = timespec_mono();
Recv(client, origname, namesize);
DEBUF("it took %'zu us to receive #2",
timespec_tomicros(timespec_sub(timespec_real(), ts2)));
timespec_tomicros(timespec_sub(timespec_mono(), ts2)));
VERBF("%s sent %#s (%'u bytes @ %#s)", addrstr, origname, filesize,
client->tmpexepath);
char *exedata = gc(malloc(filesize));
ts2 = timespec_real();
ts2 = timespec_mono();
Recv(client, exedata, filesize);
DEBUF("it took %'zu us to receive #3",
timespec_tomicros(timespec_sub(timespec_real(), ts2)));
timespec_tomicros(timespec_sub(timespec_mono(), ts2)));
DEBUF("it took %'zu us to receive executable from network",
timespec_tomicros(timespec_sub(timespec_real(), ts1)));
timespec_tomicros(timespec_sub(timespec_mono(), ts1)));
if (crc32_z(0, exedata, filesize) != crc) {
WARNF("%s crc mismatch! %#s", addrstr, origname);
pthread_exit(0);
@ -509,7 +509,7 @@ void *ClientWorker(void *arg) {
// condition can happen, where etxtbsy is raised by our execve
// we're using o_cloexec so it's guaranteed to fix itself fast
// thus we use an optimistic approach to avoid expensive locks
ts1 = timespec_real();
ts1 = timespec_mono();
sprintf(client->tmpexepath, "o/%s.XXXXXX",
basename(stripext(gc(strdup(origname)))));
int exefd = openatemp(AT_FDCWD, client->tmpexepath, 0, O_CLOEXEC, 0700);
@ -533,7 +533,7 @@ void *ClientWorker(void *arg) {
pthread_exit(0);
}
DEBUF("it took %'zu us to write executable to disk",
timespec_tomicros(timespec_sub(timespec_real(), ts1)));
timespec_tomicros(timespec_sub(timespec_mono(), ts1)));
// do the args
int i = 0;
@ -574,7 +574,7 @@ RetryOnEtxtbsyRaceCondition:
posix_spawnattr_t spawnattr;
posix_spawn_file_actions_t spawnfila;
sigemptyset(&sigmask);
started = timespec_real();
started = timespec_mono();
pipe2(client->pipe, O_CLOEXEC);
posix_spawnattr_init(&spawnattr);
posix_spawnattr_setflags(&spawnattr,
@ -584,11 +584,11 @@ RetryOnEtxtbsyRaceCondition:
posix_spawn_file_actions_adddup2(&spawnfila, g_bogusfd, 0);
posix_spawn_file_actions_adddup2(&spawnfila, client->pipe[1], 1);
posix_spawn_file_actions_adddup2(&spawnfila, client->pipe[1], 2);
ts1 = timespec_real();
ts1 = timespec_mono();
err = posix_spawn(&client->pid, client->tmpexepath, &spawnfila, &spawnattr,
args, environ);
DEBUF("it took %'zu us to call posix_spawn",
timespec_tomicros(timespec_sub(timespec_real(), ts1)));
timespec_tomicros(timespec_sub(timespec_mono(), ts1)));
if (err) {
if (err == ETXTBSY) {
goto RetryOnEtxtbsyRaceCondition;
@ -603,7 +603,7 @@ RetryOnEtxtbsyRaceCondition:
DEBUF("communicating %s[%d]", origname, client->pid);
struct timespec deadline =
timespec_add(timespec_real(), timespec_fromseconds(DEATH_CLOCK_SECONDS));
timespec_add(timespec_mono(), timespec_fromseconds(DEATH_CLOCK_SECONDS));
for (;;) {
if (g_interrupted) {
WARNF("killing %d %s and hanging up %d due to interrupt", client->fd,
@ -615,7 +615,7 @@ RetryOnEtxtbsyRaceCondition:
PrintProgramOutput(client);
pthread_exit(0);
}
struct timespec now = timespec_real();
struct timespec now = timespec_mono();
if (timespec_cmp(now, deadline) >= 0) {
WARNF("killing %s (pid %d) which timed out after %d seconds", origname,
client->pid, DEATH_CLOCK_SECONDS);
@ -626,11 +626,11 @@ RetryOnEtxtbsyRaceCondition:
fds[0].events = POLLIN;
fds[1].fd = client->pipe[0];
fds[1].events = POLLIN;
ts1 = timespec_real();
ts1 = timespec_mono();
int64_t ms = timespec_tomillis(timespec_sub(deadline, now));
events = poll(fds, ARRAYLEN(fds), MIN(ms, -1u));
DEBUF("it took %'zu us to call poll",
timespec_tomicros(timespec_sub(timespec_real(), ts1)));
timespec_tomicros(timespec_sub(timespec_mono(), ts1)));
if (events == -1) {
if (errno == EINTR) {
INFOF("poll interrupted");
@ -645,10 +645,10 @@ RetryOnEtxtbsyRaceCondition:
if (fds[0].revents) {
int received;
char buf[512];
ts1 = timespec_real();
ts1 = timespec_mono();
received = mbedtls_ssl_read(&ezssl, buf, sizeof(buf));
DEBUF("it took %'zu us to call mbedtls_ssl_read",
timespec_tomicros(timespec_sub(timespec_real(), ts1)));
timespec_tomicros(timespec_sub(timespec_mono(), ts1)));
if (!received) {
WARNF("%s client disconnected so killing worker %d", origname,
client->pid);
@ -673,10 +673,10 @@ RetryOnEtxtbsyRaceCondition:
}
if (fds[1].revents) {
char buf[512];
ts1 = timespec_real();
ts1 = timespec_mono();
ssize_t got = read(client->pipe[0], buf, sizeof(buf));
DEBUF("it took %'zu us to call read",
timespec_tomicros(timespec_sub(timespec_real(), ts1)));
timespec_tomicros(timespec_sub(timespec_mono(), ts1)));
if (got == -1) {
WARNF("got %s reading %s output", strerror(errno), origname);
goto HangupClientAndTerminateJob;
@ -694,10 +694,10 @@ RetryOnEtxtbsyRaceCondition:
WaitAgain:
DEBUF("waitpid");
struct rusage rusage;
ts1 = timespec_real();
ts1 = timespec_mono();
int wrc = wait4(client->pid, &wstatus, 0, &rusage);
DEBUF("it took %'zu us to call wait4",
timespec_tomicros(timespec_sub(timespec_real(), ts1)));
timespec_tomicros(timespec_sub(timespec_mono(), ts1)));
if (wrc == -1) {
if (errno == EINTR) {
WARNF("waitpid interrupted; killing %s pid %d", origname, client->pid);
@ -715,7 +715,7 @@ WaitAgain:
}
client->pid = 0;
int exitcode;
struct timespec ended = timespec_real();
struct timespec ended = timespec_mono();
int64_t micros = timespec_tomicros(timespec_sub(ended, started));
if (WIFEXITED(wstatus)) {
if (WEXITSTATUS(wstatus)) {
@ -750,18 +750,18 @@ WaitAgain:
AppendResourceReport(&client->output, &rusage, "\n");
PrintProgramOutput(client);
}
ts1 = timespec_real();
ts1 = timespec_mono();
SendProgramOutput(client);
SendExitMessage(exitcode);
mbedtls_ssl_close_notify(&ezssl);
DEBUF("it took %'zu us to send result to client",
timespec_tomicros(timespec_sub(timespec_real(), ts1)));
timespec_tomicros(timespec_sub(timespec_mono(), ts1)));
if (etxtbsy_tries > 1) {
WARNF("encountered %d ETXTBSY race conditions spawning %s",
etxtbsy_tries - 1, origname);
}
DEBUF("it took %'zu us TO DO EVERYTHING",
timespec_tomicros(timespec_sub(timespec_real(), ts0)));
timespec_tomicros(timespec_sub(timespec_mono(), ts0)));
pthread_exit(0);
}