Remove ptyhelper.c because the pty module has replaced it.
This commit is contained in:
parent
2708beece7
commit
bc69ffcd64
1 changed files with 0 additions and 155 deletions
155
ptyhelper.c
155
ptyhelper.c
|
|
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <pty.h>
|
||||
#include <utmp.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/select.h>
|
||||
#include <termios.h>
|
||||
|
||||
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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue