14 #include <sys/types.h>
\r
15 #include <sys/wait.h>
\r
24 sel_rfd *netr, *ptyr, *sigr;
\r
26 sel_wfd *netw, *ptyw;
\r
31 void sigchld(int signum)
\r
33 write(signalpipe[1], "C", 1);
\r
36 void fatal(const char *fmt, ...)
\r
39 fprintf(stderr, "FIXME: ");
\r
41 vfprintf(stderr, fmt, ap);
\r
43 fprintf(stderr, "\n");
\r
47 void net_readdata(sel_rfd *rfd, void *data, size_t len)
\r
50 exit(0); /* EOF on network - client went away */
\r
51 telnet_from_net(telnet, data, len);
\r
52 if (sel_write(netw, NULL, 0) > BUF)
\r
53 sel_rfd_freeze(ptyr);
\r
54 if (sel_write(ptyw, NULL, 0) > BUF)
\r
55 sel_rfd_freeze(netr);
\r
58 void net_readerr(sel_rfd *rfd, int error)
\r
60 fprintf(stderr, "standard input: read: %s\n", strerror(errno));
\r
64 void net_written(sel_wfd *wfd, size_t bufsize)
\r
67 sel_rfd_unfreeze(ptyr);
\r
70 void net_writeerr(sel_wfd *wfd, int error)
\r
72 fprintf(stderr, "standard input: write: %s\n", strerror(errno));
\r
76 void pty_readdata(sel_rfd *rfd, void *data, size_t len)
\r
79 exit(0); /* EOF on pty */
\r
80 telnet_from_pty(telnet, data, len);
\r
81 if (sel_write(netw, NULL, 0) > BUF)
\r
82 sel_rfd_freeze(ptyr);
\r
83 if (sel_write(ptyw, NULL, 0) > BUF)
\r
84 sel_rfd_freeze(netr);
\r
87 void pty_readerr(sel_rfd *rfd, int error)
\r
89 if (error == EIO) /* means EOF, on a pty */
\r
91 fprintf(stderr, "pty: read: %s\n", strerror(errno));
\r
95 void pty_written(sel_wfd *wfd, size_t bufsize)
\r
98 sel_rfd_unfreeze(netr);
\r
101 void pty_writeerr(sel_wfd *wfd, int error)
\r
103 fprintf(stderr, "pty: write: %s\n", strerror(errno));
\r
107 void sig_readdata(sel_rfd *rfd, void *data, size_t len)
\r
114 pid_t pid = waitpid(-1, &status, WNOHANG);
\r
115 if (WIFEXITED(status) || WIFSIGNALED(status))
\r
116 exit(0); /* child process vanished */
\r
121 void sig_readerr(sel_rfd *rfd, int error)
\r
123 fprintf(stderr, "signal pipe: read: %s\n", strerror(errno));
\r
127 int main(int argc, char **argv)
\r
130 int shell_started = 0;
\r
131 char *directory = NULL;
\r
132 char **program_args = NULL;
\r
134 if (argc > 1 && argv[1][0]) {
\r
135 directory = argv[1];
\r
139 program_args = argv + 1;
\r
144 asel = sel_new(NULL);
\r
145 netr = sel_rfd_add(asel, 0, net_readdata, net_readerr, NULL);
\r
146 netw = sel_wfd_add(asel, 1, net_written, net_writeerr, NULL);
\r
147 ptyr = sel_rfd_add(asel, -1, pty_readdata, pty_readerr, NULL);
\r
148 ptyw = sel_wfd_add(asel, -1, pty_written, pty_writeerr, NULL);
\r
150 telnet = telnet_new(netw, ptyw);
\r
152 if (pipe(signalpipe) < 0) {
\r
156 sigr = sel_rfd_add(asel, signalpipe[0], sig_readdata,
\r
157 sig_readerr, NULL);
\r
159 signal(SIGCHLD, sigchld);
\r
162 struct shell_data shdata;
\r
164 ret = sel_iterate(asel, -1);
\r
165 if (!shell_started && telnet_shell_ok(telnet, &shdata)) {
\r
166 ptyfd = run_program_in_pty(&shdata, directory, program_args);
\r
167 sel_rfd_setfd(ptyr, ptyfd);
\r
168 sel_wfd_setfd(ptyw, ptyfd);
\r
171 } while (ret == 0);
\r