2 #define _XOPEN_SOURCE_EXTENDED
11 #include <sys/ioctl.h>
25 static void pty_size(void);
28 * Called to set up the pty.
30 * Returns an error message, or NULL on success.
32 * Also places the canonical host name into `realhost'. It must be
33 * freed by the caller.
35 static char *pty_init(char *host
, int port
, char **realhost
, int nodelay
)
38 char name
[FILENAME_MAX
];
41 pty_master_fd
= open("/dev/ptmx", O_RDWR
);
43 if (pty_master_fd
< 0) {
44 perror("/dev/ptmx: open");
48 if (grantpt(pty_master_fd
) < 0) {
53 if (unlockpt(pty_master_fd
) < 0) {
58 name
[FILENAME_MAX
-1] = '\0';
59 strncpy(name
, ptsname(pty_master_fd
), FILENAME_MAX
-1);
61 slavefd
= open(name
, O_RDWR
);
63 perror("slave pty: open");
68 * Fork and execute the command.
85 fcntl(slavefd
, F_SETFD
, 0); /* don't close on exec */
91 tcsetpgrp(slavefd
, getpgrp());
92 /* Close everything _else_, for tidiness. */
93 for (i
= 3; i
< 1024; i
++)
96 execvp(pty_argv
[0], pty_argv
);
98 execl(getenv("SHELL"), getenv("SHELL"), NULL
);
100 * If we're here, exec has gone badly foom.
112 * Called to send data down the pty.
114 static int pty_send(char *buf
, int len
)
117 int ret
= write(pty_master_fd
, buf
, len
);
119 perror("write pty master");
129 * Called to query the current socket sendability status.
131 static int pty_sendbuffer(void)
137 * Called to set the size of the window
139 static void pty_size(void)
143 size
.ws_row
= (unsigned short)rows
;
144 size
.ws_col
= (unsigned short)cols
;
145 ioctl(pty_master_fd
, TIOCSWINSZ
, (void *)&size
);
150 * Send special codes.
152 static void pty_special(Telnet_Special code
)
158 static Socket
pty_socket(void)
160 return NULL
; /* shouldn't ever be needed */
163 static int pty_sendok(void)
168 static void pty_unthrottle(int backlog
)
173 static int pty_ldisc(int option
)
175 return 0; /* neither editing nor echoing */
178 static int pty_exitcode(void)
180 /* Shouldn't ever be required */
184 Backend pty_backend
= {