# HG changeset patch # User John "Elwin" Edwards # Date 1388603590 18000 # Node ID 8d6bf19d82272aa8913e3a50d95e54783700080e # Parent 5baa2d4d798bcb0998976a5a81c0fb61e54ec4d9 Remove ptyhelper.c because the pty module has replaced it. diff -r 5baa2d4d798b -r 8d6bf19d8227 ptyhelper.c --- a/ptyhelper.c Wed Jan 01 14:11:40 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +0,0 @@ -/* - * ptyhelper: a utility that runs a command in a pseudoterm and then streams - * stdio to/from it. Intended to get around the node.js loss of C/UNIX - * functionality. - * Remember to compile with -lutil. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int got_sighup = 0; - -void handle_HUP(int signum) { - if (signum == SIGHUP) - got_sighup = 1; - return; -} - -int main(int argc, char *argv[]) { - - int ptymaster, ptyslave; /* File descriptors */ - int child; - int status, selstatus; - int w = 80, h = 24, t; - struct sigaction sighup_act; - fd_set readset; - struct timeval select_time; - char buf[4096]; - int nread; - char *penv, *ptmp; -#if 0 - struct termios ptysettings; -#endif - struct winsize ptysize; - - if (argc == 1) { - fprintf(stderr, "No command given.\n"); - exit(1); - } - - /* Set up the signal handler. */ - sighup_act.sa_handler = &handle_HUP; - sighup_act.sa_flags = SA_RESTART; - sigaction(SIGHUP, &sighup_act, NULL); - - /* Check the environment for configuration options. */ - penv = getenv("PTYHELPER"); - if (penv != NULL) { - t = strtol(penv, &ptmp, 10); - if (t > 0 && t < 256) - h = t; - if (*ptmp != '\0') { - penv = ptmp + 1; - t = strtol(penv, &ptmp, 10); - if (t > 0 && t < 256) - w = t; - } - } - /* Set up the size. */ - ptysize.ws_row = h; - ptysize.ws_col = w; - - /* Open a pty */ - if (openpty(&ptymaster, &ptyslave, NULL, NULL, &ptysize)) { - return 1; - } -#if 0 - /* Put it into raw mode. */ - tcgetattr(ptyslave, &ptysettings); - cfmakeraw(&ptysettings); - tcsetattr(ptyslave, TCSANOW, &ptysettings); -#endif - - /* Start the child */ - /* forkpty() might be more convenient. */ - if (!(child = fork())) { - /* Child process */ - login_tty(ptyslave); - close(ptymaster); - execvp(argv[1], argv + 1); - perror("execvp() failed"); - return 1; - } - close(ptyslave); - - while (1) { - /* Now do a select() over stdin and ptymaster, and write anything that - * appears to ptymaster and stdout respectively. */ - FD_ZERO(&readset); - FD_SET(0, &readset); - FD_SET(ptymaster, &readset); - select_time.tv_sec = 1; - select_time.tv_usec = 0; - selstatus = select(ptymaster + 1, &readset, NULL, NULL, &select_time); - if (selstatus > 0) { - /* TODO make sure it all gets written if a signal interrupts write(). */ - if (FD_ISSET(0, &readset)) { - nread = read(0, buf, 4096); - if (nread > 0) { - write(ptymaster, buf, nread); - } - } - if (FD_ISSET(ptymaster, &readset)) { - nread = read(ptymaster, buf, 4096); - if (nread > 0) { - write(1, buf, nread); - } - } - } - - /* Periodically check to see if we're done. */ - /* TODO: catch SIGCHLD and only wait() if it is delivered. */ - if (waitpid(child, &status, WNOHANG)) { - break; - } - - /* If node sighup's us, pass it along. */ - if (got_sighup) { - kill(child, SIGHUP); - } - } - - /* Get any leftover output and clean up. */ - /* FIXME looping over select() is pointless if there's only one fd that - * nothing's writing to. Just loop over read() until it's empty. */ - while (1) { - FD_ZERO(&readset); - FD_SET(ptymaster, &readset); - select_time.tv_sec = 0; - select_time.tv_usec = 0; - if (select(ptymaster + 1, &readset, NULL, NULL, &select_time) > 0) { - nread = read(ptymaster, buf, 4096); - if (nread > 0) { - write(1, buf, nread); - } - else - break; - } - else - break; - } - close(ptymaster); - - /* Return the child's exit status. */ - if (WIFEXITED(status)) - return WEXITSTATUS(status); - return 0; -}