begin simple child process interface
This commit is contained in:
parent
8991d8ec04
commit
2e10e88504
3 changed files with 82 additions and 14 deletions
63
cli/child.c
Normal file
63
cli/child.c
Normal 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
14
cli/child.h
Normal 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 */
|
||||
19
cli/main.c
19
cli/main.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue