diff --git a/cli/child.c b/cli/child.c new file mode 100644 index 0000000..6fe3313 --- /dev/null +++ b/cli/child.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include + +#include "child.h" +#include "epty.h" + +/* SIGTERM grace period before a child is sent SIGKILL. + * Value is in microseconds (us), 1000us = 1ms */ +#define CHILD_GRACE_US 100000 + +/* Check if a child is still alive by pid + * by kill(3p) sending a null signal (0). + */ +static int is_alive(struct d_child *child) { + return (kill(child->pid, 0) == 0); +} + +/* Force a child to die, first by sending SIGTERM, otherwise SIGKILL. + * NOTE: killchild() ASSUMES the child is LIVING at the start. + * NOTE: Keep this in mind when threading! + */ +void killchild(struct d_child *child) { + int stat; + + /* Request Death */ + kill(child->pid, SIGTERM); + usleep(CHILD_GRACE_US); + + /* Force Death */ + if (is_alive(child)) + kill(child->pid, SIGKILL); + + /* Reap */ + waitpid(child->pid, &stat, 0); +} + +/* Fork to spawn a child process running bin/shfx in an "epty". + */ +int spawnchild(struct d_child *child) { + *child = (struct d_child){ 0 }; + + /* fork(2) and allocate an "error-piped pseudoterminal" (epty) */ + switch (child->pid = forkepty(&child->fdmx, &child->fderr)) { + case -1: + perror("forkepty"); + return EXIT_FAILURE; + case 0: + char *args[] = {"shfx", NULL}; + execvp("shfx", args); + perror("execvp"); + exit(1); + default: + usleep(1000); + char bufout[10]; + bufout[9] = '\0'; + read(child->fdmx, bufout, 9); + printf("child stdout: \"%s\"\n", bufout); + break; + } + return EXIT_SUCCESS; +} diff --git a/cli/child.h b/cli/child.h new file mode 100644 index 0000000..6ec3978 --- /dev/null +++ b/cli/child.h @@ -0,0 +1,14 @@ +#ifndef DORNE_CHILD_H +#define DORNE_CHILD_H + +#include + +struct d_child { + pid_t pid; + int fdmx; /* PTY master fd (read/write) */ + int fderr; /* child's stderr (readonly) */ +} __attribute__((packed, aligned(4))); + +int spawnchild(struct d_child *child); + +#endif /* DORNE_CHILD_H */ diff --git a/cli/main.c b/cli/main.c index e2d4986..af57f88 100644 --- a/cli/main.c +++ b/cli/main.c @@ -1,7 +1,8 @@ -#include +#include #include +#include -#include "mkpty.h" +#include "child.h" // struct d_window { // int ptmx; // fd @@ -14,17 +15,7 @@ // } int main(int argc, char **argv) { - pid_t pid; - switch (pid = forkmkpty()) { - case -1: - perror("forkmkpty"); - break; - case 0: - printf("fork: children\n"); - break; - default: - printf("fork: parent\n"); - break; - } + struct d_child child; + spawnchild(&child); return EXIT_SUCCESS; }