Fix LTO build
[platform/upstream/expect.git] / pty_sgttyb.c
1 /* pty_bsd.c - routines to allocate ptys - BSD version
2
3 Written by: Don Libes, NIST, 2/6/90
4
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.
8
9 */
10
11 #include <stdio.h>              /* tmp for debugging */
12 #include <signal.h>
13
14 #if defined(SIGCLD) && !defined(SIGCHLD)
15 #define SIGCHLD SIGCLD
16 #endif
17
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 /*** #include <sys/ioctl.h> ***/
21 #include <sys/file.h>
22 #include <signal.h>
23 #include <setjmp.h>
24 #include "expect_cf.h"
25 #include "exp_rename.h"
26 #include "exp_tty_in.h"
27 #include "exp_pty.h"
28
29 void expDiagLog();
30 void expDiagLogU();
31
32 #ifndef TRUE
33 #define TRUE 1
34 #define FALSE 0
35 #endif
36
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
42                                            which bank it is */
43 static char     *tty_num;               /* ptr to char [0-f] denoting
44                                            which number it is */
45 char *exp_pty_slave_name;
46 char *exp_pty_error;
47
48 static void
49 pty_stty(s,name)
50 char *s;                /* args to stty */
51 char *name;             /* name of pty */
52 {
53 #define MAX_ARGLIST 10240
54         char buf[MAX_ARGLIST];  /* overkill is easier */
55         RETSIGTYPE (*old)();    /* save old sigalarm handler */
56
57 #ifdef STTY_READS_STDOUT
58         sprintf(buf,"%s %s > %s",STTY_BIN,s,name);
59 #else
60         sprintf(buf,"%s %s < %s",STTY_BIN,s,name);
61 #endif
62         old = signal(SIGCHLD, SIG_DFL);
63         system(buf);
64         signal(SIGCHLD, old);   /* restore signal handler */
65 }
66
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 */
69
70 #ifdef TIOCGWINSZ
71 static struct winsize winsize = {0, 0};
72 #endif
73 #if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
74 static struct ttysize winsize = {0, 0};
75 #endif
76
77 exp_tty exp_tty_original;
78
79 #define GET_TTYTYPE     0
80 #define SET_TTYTYPE     1
81 static void
82 ttytype(request,fd,ttycopy,ttyinit,s)
83 int request;
84 int fd;
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 */
89 {
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 */
95
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;
104                         exp_dev_tty = -1;
105                 }
106 #ifdef TIOCGWINSZ
107                 ioctl(fd,TIOCGWINSZ,&winsize);
108 #endif
109 #if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
110                 ioctl(fd,TIOCGSIZE,&winsize);
111 #endif
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);
120 #ifdef TIOCSWINSZ
121                         ioctl(fd,TIOCSWINSZ,&winsize);
122 #endif
123 #if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
124                         ioctl(fd,TIOCGSIZE,&winsize);
125 #endif
126                 }
127
128 #ifdef __CENTERLINE__
129 #undef DFLT_STTY
130 #define DFLT_STTY "sane"
131 #endif
132
133 /* Apollo Domain doesn't need this */
134 #ifdef DFLT_STTY
135                 if (ttyinit) {
136                         /* overlay parms originally supplied by Makefile */
137                         pty_stty(DFLT_STTY,slave_name);
138                 }
139 #endif
140
141                 /* lastly, give user chance to override any terminal parms */
142                 if (s) {
143                         pty_stty(s,slave_name);
144                 }
145         }
146 }
147
148 void
149 exp_init_pty()
150 {
151         tty_type = & slave_name[strlen("/dev/")];
152         tty_bank = &master_name[strlen("/dev/pty")];
153         tty_num  = &master_name[strlen("/dev/ptyp")];
154
155         exp_dev_tty = open("/dev/tty",O_RDWR);
156
157 #if experimental
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 */
165                 setpgrp(0,0);
166                 close(0);
167                 close(1);
168                 exp_getptyslave(exp_get_var(exp_interp,"stty_init"));
169                 close(2);
170                 fcntl(0,F_DUPFD,2);             /* dup 0 onto 2 */
171         }
172 #endif
173
174         knew_dev_tty = (exp_dev_tty != -1);
175         if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0);
176 }
177
178 /* returns fd of master end of pseudotty */
179 int
180 exp_getptymaster()
181 {
182         int master = -1;
183         char *hex, *bank;
184         struct stat statbuf;
185
186         exp_pty_error = 0;
187
188         if (exp_pty_test_start() == -1) return -1;
189
190         for (bank = "pqrstuvwxyzPQRSTUVWXYZ";*bank;bank++) {
191                 *tty_bank = *bank;
192                 *tty_num = '0';
193                 if (stat(master_name, &statbuf) < 0) break;
194                 for (hex = "0123456789abcdef";*hex;hex++) {
195                         *tty_num = *hex;
196
197                         /* generate slave name from master */
198                         strcpy(slave_name,master_name);
199                         *tty_type = 't';
200
201                         master = exp_pty_test(master_name,slave_name,
202                                                 *tty_bank,tty_num);
203                         if (master >= 0) goto done;
204                 }
205         }
206  done:
207         exp_pty_test_end();
208         exp_pty_slave_name = slave_name;
209         return(master);
210 }
211
212 /* see comment in pty_termios.c */
213 /*ARGSUSED*/
214 void
215 exp_slave_control(master,control)
216 int master;
217 int control;
218 {
219 }
220
221 int
222 exp_getptyslave(ttycopy,ttyinit,stty_args)
223 int ttycopy;
224 int ttyinit;
225 char *stty_args;
226 {
227         int slave;
228
229         if (0 > (slave = open(slave_name, O_RDWR))) return(-1);
230
231         if (0 == slave) {
232                 /* if opened in a new process, slave will be 0 (and */
233                 /* ultimately, 1 and 2 as well) */
234
235                 /* duplicate 0 onto 1 and 2 to prepare for stty */
236                 fcntl(0,F_DUPFD,1);
237                 fcntl(0,F_DUPFD,2);
238         }
239
240         ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args);
241         (void) exp_pty_unlock();
242         return(slave);
243 }
244
245 void
246 exp_pty_exit()
247 {
248         /* a stub so we can do weird things on the cray */
249 }