2 #define _XOPEN_SOURCE_EXTENDED
12 #include <sys/types.h>
14 #include <sys/ioctl.h>
26 static int pty_child_pid
;
27 static sig_atomic_t pty_child_dead
;
30 int pty_child_is_dead(void)
32 return pty_child_dead
;
35 static void pty_size(void);
37 static void sigchld_handler(int signum
)
41 pid
= waitpid(-1, &status
, WNOHANG
);
42 if (pid
== pty_child_pid
&& (WIFEXITED(status
) || WIFSIGNALED(status
)))
43 pty_child_dead
= TRUE
;
47 * Called to set up the pty.
49 * Returns an error message, or NULL on success.
51 * Also places the canonical host name into `realhost'. It must be
52 * freed by the caller.
54 static char *pty_init(char *host
, int port
, char **realhost
, int nodelay
)
57 char name
[FILENAME_MAX
];
60 pty_master_fd
= open("/dev/ptmx", O_RDWR
);
62 if (pty_master_fd
< 0) {
63 perror("/dev/ptmx: open");
67 if (grantpt(pty_master_fd
) < 0) {
72 if (unlockpt(pty_master_fd
) < 0) {
77 name
[FILENAME_MAX
-1] = '\0';
78 strncpy(name
, ptsname(pty_master_fd
), FILENAME_MAX
-1);
81 * Fork and execute the command.
95 slavefd
= open(name
, O_RDWR
);
97 perror("slave pty: open");
101 close(pty_master_fd
);
105 fcntl(slavefd
, F_SETFD
, 0); /* don't close on exec */
110 ioctl(slavefd
, TIOCSCTTY
, 1);
112 tcsetpgrp(slavefd
, pgrp
);
114 close(open(name
, O_WRONLY
, 0));
116 /* Close everything _else_, for tidiness. */
117 for (i
= 3; i
< 1024; i
++)
120 char term_env_var
[10 + sizeof(cfg
.termtype
)];
121 sprintf(term_env_var
, "TERM=%s", cfg
.termtype
);
122 putenv(term_env_var
);
125 execvp(pty_argv
[0], pty_argv
);
127 execl(getenv("SHELL"), getenv("SHELL"), NULL
);
129 * If we're here, exec has gone badly foom.
136 pty_child_dead
= FALSE
;
137 signal(SIGCHLD
, sigchld_handler
);
144 * Called to send data down the pty.
146 static int pty_send(char *buf
, int len
)
149 int ret
= write(pty_master_fd
, buf
, len
);
151 perror("write pty master");
161 * Called to query the current socket sendability status.
163 static int pty_sendbuffer(void)
169 * Called to set the size of the window
171 static void pty_size(void)
175 size
.ws_row
= (unsigned short)rows
;
176 size
.ws_col
= (unsigned short)cols
;
177 ioctl(pty_master_fd
, TIOCSWINSZ
, (void *)&size
);
182 * Send special codes.
184 static void pty_special(Telnet_Special code
)
190 static Socket
pty_socket(void)
192 return NULL
; /* shouldn't ever be needed */
195 static int pty_sendok(void)
200 static void pty_unthrottle(int backlog
)
205 static int pty_ldisc(int option
)
207 return 0; /* neither editing nor echoing */
210 static int pty_exitcode(void)
212 /* Shouldn't ever be required */
216 Backend pty_backend
= {