begin simple child process interface

This commit is contained in:
Emile Clark-Boman 2025-09-10 01:25:08 +10:00
parent 8991d8ec04
commit 2e10e88504
3 changed files with 82 additions and 14 deletions

63
cli/child.c Normal file
View file

@ -0,0 +1,63 @@
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#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;
}

14
cli/child.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef DORNE_CHILD_H
#define DORNE_CHILD_H
#include <unistd.h>
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 */

View file

@ -1,7 +1,8 @@
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#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;
}