1 /* pty_bsd.c - routines to allocate ptys - BSD version
3 Written by: Don Libes, NIST, 2/6/90
5 Design and implementation of this program was paid for by U.S. tax
6 dollars. Therefore it is public domain. However, the author and NIST
7 would appreciate credit if this program or parts of it are used.
11 #include <stdio.h> /* tmp for debugging */
14 #if defined(SIGCLD) && !defined(SIGCHLD)
15 #define SIGCHLD SIGCLD
18 #include <sys/types.h>
20 /*** #include <sys/ioctl.h> ***/
24 #include "expect_cf.h"
25 #include "exp_rename.h"
26 #include "exp_tty_in.h"
37 static char master_name[] = "/dev/ptyXX"; /* master */
38 static char slave_name[] = "/dev/ttyXX"; /* slave */
39 static char *tty_type; /* ptr to char [pt] denoting
40 whether it is a pty or tty */
41 static char *tty_bank; /* ptr to char [p-z] denoting
43 static char *tty_num; /* ptr to char [0-f] denoting
45 char *exp_pty_slave_name;
50 char *s; /* args to stty */
51 char *name; /* name of pty */
53 #define MAX_ARGLIST 10240
54 char buf[MAX_ARGLIST]; /* overkill is easier */
55 RETSIGTYPE (*old)(); /* save old sigalarm handler */
57 #ifdef STTY_READS_STDOUT
58 sprintf(buf,"%s %s > %s",STTY_BIN,s,name);
60 sprintf(buf,"%s %s < %s",STTY_BIN,s,name);
62 old = signal(SIGCHLD, SIG_DFL);
64 signal(SIGCHLD, old); /* restore signal handler */
67 int exp_dev_tty; /* file descriptor to /dev/tty or -1 if none */
68 static int knew_dev_tty;/* true if we had our hands on /dev/tty at any time */
71 static struct winsize winsize = {0, 0};
73 #if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
74 static struct ttysize winsize = {0, 0};
77 exp_tty exp_tty_original;
82 ttytype(request,fd,ttycopy,ttyinit,s)
85 /* following are used only if request == SET_TTYTYPE */
86 int ttycopy; /* if true, copy from /dev/tty */
87 int ttyinit; /* if true, initialize to sane state */
88 char *s; /* stty args */
90 static struct tchars tc; /* special characters */
91 static struct ltchars lc; /* local special characters */
92 static struct winsize win; /* window size */
93 static int lb; /* local modes */
94 static int l; /* line discipline */
96 if (request == GET_TTYTYPE) {
97 if (-1 == ioctl(fd, TIOCGETP, (char *)&exp_tty_original)
98 || -1 == ioctl(fd, TIOCGETC, (char *)&tc)
99 || -1 == ioctl(fd, TIOCGETD, (char *)&l)
100 || -1 == ioctl(fd, TIOCGLTC, (char *)&lc)
101 || -1 == ioctl(fd, TIOCLGET, (char *)&lb)
102 || -1 == ioctl(fd, TIOCGWINSZ, (char *)&win)) {
103 knew_dev_tty = FALSE;
107 ioctl(fd,TIOCGWINSZ,&winsize);
109 #if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
110 ioctl(fd,TIOCGSIZE,&winsize);
112 } else { /* type == SET_TTYTYPE */
113 if (ttycopy && knew_dev_tty) {
114 (void) ioctl(fd, TIOCSETP, (char *)&exp_tty_current);
115 (void) ioctl(fd, TIOCSETC, (char *)&tc);
116 (void) ioctl(fd, TIOCSLTC, (char *)&lc);
117 (void) ioctl(fd, TIOCLSET, (char *)&lb);
118 (void) ioctl(fd, TIOCSETD, (char *)&l);
119 (void) ioctl(fd, TIOCSWINSZ, (char *)&win);
121 ioctl(fd,TIOCSWINSZ,&winsize);
123 #if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
124 ioctl(fd,TIOCGSIZE,&winsize);
128 #ifdef __CENTERLINE__
130 #define DFLT_STTY "sane"
133 /* Apollo Domain doesn't need this */
136 /* overlay parms originally supplied by Makefile */
137 pty_stty(DFLT_STTY,slave_name);
141 /* lastly, give user chance to override any terminal parms */
143 pty_stty(s,slave_name);
151 tty_type = & slave_name[strlen("/dev/")];
152 tty_bank = &master_name[strlen("/dev/pty")];
153 tty_num = &master_name[strlen("/dev/ptyp")];
155 exp_dev_tty = open("/dev/tty",O_RDWR);
158 /* code to allocate force expect to get a controlling tty */
159 /* even if it doesn't start with one (i.e., under cron). */
160 /* This code is not necessary, but helpful for testing odd things. */
161 if (exp_dev_tty == -1) {
162 /* give ourselves a controlling tty */
163 int master = exp_getptymaster();
164 fcntl(master,F_SETFD,1); /* close-on-exec */
168 exp_getptyslave(exp_get_var(exp_interp,"stty_init"));
170 fcntl(0,F_DUPFD,2); /* dup 0 onto 2 */
174 knew_dev_tty = (exp_dev_tty != -1);
175 if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0);
178 /* returns fd of master end of pseudotty */
188 if (exp_pty_test_start() == -1) return -1;
190 for (bank = "pqrstuvwxyzPQRSTUVWXYZ";*bank;bank++) {
193 if (stat(master_name, &statbuf) < 0) break;
194 for (hex = "0123456789abcdef";*hex;hex++) {
197 /* generate slave name from master */
198 strcpy(slave_name,master_name);
201 master = exp_pty_test(master_name,slave_name,
203 if (master >= 0) goto done;
208 exp_pty_slave_name = slave_name;
212 /* see comment in pty_termios.c */
215 exp_slave_control(master,control)
222 exp_getptyslave(ttycopy,ttyinit,stty_args)
229 if (0 > (slave = open(slave_name, O_RDWR))) return(-1);
232 /* if opened in a new process, slave will be 0 (and */
233 /* ultimately, 1 and 2 as well) */
235 /* duplicate 0 onto 1 and 2 to prepare for stty */
240 ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args);
241 (void) exp_pty_unlock();
248 /* a stub so we can do weird things on the cray */