It LIVES!!!

This commit is contained in:
Radon Rosborough 2021-08-14 16:56:20 -07:00
parent 157176f013
commit c6a22e2793
2 changed files with 59 additions and 41 deletions

View File

@ -3,9 +3,11 @@
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
@ -22,8 +24,12 @@ void die_with_usage() { die("usage: riju-pty [-f] CMDLINE..."); }
struct termios orig_termios;
bool do_restore_tty = true;
void restore_tty()
{
if (!do_restore_tty)
return;
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) < 0)
die("tcsetattr failed");
}
@ -57,11 +63,7 @@ int main(int argc, char **argv)
if (tcgetattr(STDIN_FILENO, &orig_termios) < 0)
die("tcgetattr failed");
struct termios raw = orig_termios;
// https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode.html
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
raw.c_oflag &= ~(OPOST);
raw.c_cflag |= (CS8);
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
cfmakeraw(&raw);
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) < 0)
die("tcsetattr failed");
if (atexit(restore_tty) < 0)
@ -70,10 +72,15 @@ int main(int argc, char **argv)
if (errno != ENOTTY)
die("isatty failed");
}
pid_t orig_ppid = getpid();
pid_t exec_pid = fork();
if (exec_pid < 0)
die("fork failed");
else if (exec_pid == 0) {
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
die("prctl failed");
if (getppid() != orig_ppid)
exit(EXIT_FAILURE);
if (!no_pty) {
close(pty_master_fd);
if (setsid() < 0)
@ -93,9 +100,7 @@ int main(int argc, char **argv)
execvp(argv[0], &argv[0]);
die("execvp failed");
}
if (setpgrp() < 0)
die("setpgrp failed");
int pid = no_pty ? 1 : fork();
pid_t pid = no_pty ? 1 : fork();
if (pid < 0)
die("fork failed");
else if (pid > 0) {
@ -103,19 +108,29 @@ int main(int argc, char **argv)
if (waitpid(exec_pid, &wstatus, 0) != exec_pid)
die("waitpid failed");
if (!no_pty) {
if (signal(SIGTERM, SIG_IGN) == SIG_ERR)
die("signal failed");
if (kill(0, SIGTERM) < 0)
if (kill(-pid, SIGTERM) < 0)
die("kill failed");
}
return WEXITSTATUS(wstatus);
}
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
die("prctl failed");
if (getppid() != orig_ppid)
exit(EXIT_FAILURE);
do_restore_tty = false;
if (setpgrp() < 0)
die("setpgrp failed");
char buf[1024];
int len, len_written;
orig_ppid = getpid();
pid = fork();
if (pid < 0)
die("fork failed");
else if (pid == 0) {
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
die("prctl failed");
if (getppid() != orig_ppid)
exit(EXIT_FAILURE);
while ((len = read(STDIN_FILENO, buf, 1024)) > 0) {
char *ptr = buf;
while (len > 0) {

View File

@ -1,3 +1,4 @@
#include <linux/prctl.h>
#define _GNU_SOURCE
#include <ctype.h>
#include <errno.h>
@ -8,6 +9,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/random.h>
#include <sys/stat.h>
#include <sys/types.h>
@ -174,10 +176,15 @@ void session(char *uuid, char *lang, char *imageHash)
die("asprintf failed");
if (mknod(fifo, 0600 | S_IFIFO, 0) < 0)
die("mknod failed");
pid_t orig_ppid = getpid();
pid_t pid = fork();
if (pid < 0)
die("fork failed");
else if (pid == 0) {
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
die("prctl failed");
if (getppid() != orig_ppid)
exit(EXIT_FAILURE);
char *argv[] = {
"docker",
"run",
@ -253,27 +260,18 @@ void session(char *uuid, char *lang, char *imageHash)
}
if (signal(SIGALRM, SIG_IGN) == SIG_ERR)
die("signal failed");
pid = fork();
if (pid < 0)
die("fork failed");
else if (pid == 0) {
struct timespec ts_1s;
ts_1s.tv_sec = 1;
ts_1s.tv_nsec = 0;
while (1) {
static const char ok[] = "ping\n";
if (write(fd, ok, sizeof(ok) / sizeof(char)) != sizeof(ok) / sizeof(char))
die("write failed");
int rv = nanosleep(&ts_1s, NULL);
if (rv != 0 && errno != EINTR)
die("nanosleep failed");
}
}
printf("riju: container ready\n"); // magic string
if (waitpid(pid, NULL, 0) <= 0)
die("waitpid failed");
if (close(fd) < 0)
die("close failed");
struct timespec ts_1s;
ts_1s.tv_sec = 1;
ts_1s.tv_nsec = 0;
while (1) {
static const char ok[] = "ping\n";
if (write(fd, ok, sizeof(ok) / sizeof(char)) != sizeof(ok) / sizeof(char))
die("write failed");
int rv = nanosleep(&ts_1s, NULL);
if (rv != 0 && errno != EINTR)
die("nanosleep failed");
}
}
void exec(char *uuid, int argc, char **cmdline, bool pty)
@ -313,16 +311,25 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
struct timespec ts_10ms;
ts_10ms.tv_sec = 0;
ts_10ms.tv_nsec = 1000 * 1000 * 10;
pid_t input_pid = fork(), output_pid;
if (input_pid < 0)
pid_t orig_ppid = getpid();
pid_t pid = fork();
if (pid < 0)
die("fork failed");
else if (input_pid == 0) {
else if (pid == 0) {
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
die("prctl failed");
if (getppid() != orig_ppid)
exit(EXIT_FAILURE);
dataFIFO = inputFIFO;
} else {
output_pid = fork();
if (output_pid < 0)
pid = fork();
if (pid < 0)
die("fork failed");
else if (output_pid == 0) {
else if (pid == 0) {
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
die("prctl failed");
if (getppid() != orig_ppid)
exit(EXIT_FAILURE);
dataFIFO = outputFIFO;
} else {
dataFIFO = statusFIFO;
@ -392,10 +399,6 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
long status = strtol(line, &endptr, 10);
if (*endptr != '\n')
die("strtol failed");
if (kill(input_pid, SIGTERM) < 0)
die("kill failed");
if (kill(output_pid, SIGTERM) < 0)
die("kill failed");
exit(status);
}
}