diff --git a/cli/epty.c b/cli/epty.c new file mode 100644 index 0000000..85182e4 --- /dev/null +++ b/cli/epty.c @@ -0,0 +1,45 @@ +#include + +#include "mkpty.h" + +#define PIPE_READ 0 +#define PIPE_WRITE 1 + +/* Allocate a PTY and fork, giving fdmx (master) to the parent + * and binding the child's stdin/stdout to fds (slave). + * Return value is indentical to fork(2). + * NOTE: This function is my alternative to GLibC's + * NOTE: forkpty() function. It exists as a learning resource. + * REF: https://sourceware.org/git/glibc.git -> ./login/forkpty.c + */ +pid_t forkepty(int *fdmx, int *fderr) { + // master/slave, and stderr pipe fds + int epipe[2]; + pid_t pid; + + if (pipe(epipe) == -1) + return EXIT_FAILURE; + switch (pid = forkmkpty(fdmx)) { + case -1: + /* forkmkpty() will close fdmx/fds for us */ + close(epipe[PIPE_READ]); + close(epipe[PIPE_WRITE]); + return -1; + case 0: + /* Child Process */ + /* forkmkpty() will close fdmx for us */ + close(epipe[PIPE_READ]); + BIND(epipe[PIPE_WRITE], STDERR_FILENO); + break; + + default: + /* Parent Process */ + /* forkmkpty() will close fds for us */ + close(epipe[PIPE_WRITE]); + *fderr = epipe[PIPE_READ]; + break; + } + + /* Both Processes */ + return pid; +} diff --git a/cli/epty.h b/cli/epty.h new file mode 100644 index 0000000..8dd18e4 --- /dev/null +++ b/cli/epty.h @@ -0,0 +1,8 @@ +#ifndef DORNE_EPTY_H +#define DORNE_EPTY_H + +#include + +pid_t forkepty(int *fdmx, int *fderr); + +#endif /* DORNE_EPTY_H */