OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [expect/] [pty_termios.c] - Blame information for rev 1776

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* pty_termios.c - routines to allocate ptys - termios version
2
 
3
Written by: Don Libes, NIST, 2/6/90
4
 
5
This file is in the public domain.  However, the author and NIST
6
would appreciate credit if you use this file or parts of it.
7
 
8
*/
9
 
10
/* Must be first, so that _XOPEN_SOURCE works.  */
11
#include "expect_cf.h"
12
 
13
#include <stdio.h>
14
#include <signal.h>
15
 
16
#if defined(SIGCLD) && !defined(SIGCHLD)
17
#define SIGCHLD SIGCLD
18
#endif
19
 
20
/*
21
   The following functions are linked from the Tcl library.  They
22
   don't cause anything else in the library to be dragged in, so it
23
   shouldn't cause any problems (e.g., bloat).
24
 
25
   The functions are relatively small but painful enough that I don't care
26
   to recode them.  You may, if you absolutely want to get rid of any
27
   vestiges of Tcl.
28
*/
29
extern char *TclGetRegError();
30
 
31
 
32
 
33
#if defined(HAVE_PTYM) && defined(HAVE_PTMX)
34
/*
35
 * HP-UX 10.0 with streams (optional) have both PTMX and PTYM.  I don't
36
 * know which is preferred but seeing as how the HP trap stuff is so
37
 * unusual, it is probably safer to stick with the native HP pty support,
38
 * too.
39
 */
40
#undef HAVE_PTMX
41
#endif
42
 
43
#ifdef HAVE_UNISTD_H
44
#  include <unistd.h>
45
#endif
46
#ifdef HAVE_INTTYPES_H
47
#  include <inttypes.h>
48
#endif
49
#include <sys/types.h>
50
#include <sys/stat.h>
51
 
52
#ifdef NO_STDLIB_H
53
#include "../compat/stdlib.h"
54
#else
55
#include <stdlib.h>
56
#endif
57
 
58
#ifdef HAVE_SYSMACROS_H
59
#include <sys/sysmacros.h>
60
#endif
61
 
62
#ifdef HAVE_PTYTRAP
63
#include <sys/ptyio.h>
64
#endif
65
 
66
#include <sys/file.h>
67
 
68
#ifdef HAVE_SYS_FCNTL_H
69
#  include <sys/fcntl.h>
70
#else
71
#  include <fcntl.h>
72
#endif
73
 
74
#if defined(_SEQUENT_)
75
#  include <sys/strpty.h>
76
#endif
77
 
78
#if defined(HAVE_PTMX) && !defined(__CYGWIN32__)
79
#  include <sys/stropts.h>
80
#endif
81
 
82
#include "exp_win.h"
83
 
84
#include "exp_tty_in.h"
85
#include "exp_rename.h"
86
#include "exp_pty.h"
87
 
88
void debuglog();
89
 
90
#include <errno.h>
91
/*extern char *sys_errlist[];*/
92
 
93
#ifndef TRUE
94
#define TRUE 1
95
#define FALSE 0
96
#endif
97
 
98
/* Convex getpty is different than older-style getpty */
99
/* Convex getpty is really just a cover function that does the traversal */
100
/* across the domain of pty names.  It makes no attempt to verify that */
101
/* they can actually be used.  Indded, the logic in the man page is */
102
/* wrong because it will allow you to allocate ptys that your own account */
103
/* already has in use. */
104
#if defined(HAVE_GETPTY) && defined(CONVEX)
105
#undef HAVE_GETPTY
106
#define HAVE_CONVEX_GETPTY
107
extern char *getpty();
108
static char *master_name;
109
static char slave_name[] = "/dev/ptyXX";
110
static char     *tty_bank;              /* ptr to char [p-z] denoting
111
                                           which bank it is */
112
static char     *tty_num;               /* ptr to char [0-f] denoting
113
                                           which number it is */
114
#endif
115
 
116
#if defined(_SEQUENT_) && !defined(HAVE_PTMX)
117
/* old-style SEQUENT, new-style uses ptmx */
118
static char *master_name, *slave_name;
119
#endif /* _SEQUENT */
120
 
121
/* very old SGIs prefer _getpty over ptc */
122
#if defined(HAVE__GETPTY) && defined(HAVE_PTC) && !defined(HAVE_GETPTY)
123
#undef HAVE_PTC
124
#endif
125
 
126
#if defined(HAVE_PTC)
127
static char slave_name[] = "/dev/ttyqXXX";
128
/* some machines (e.g., SVR4.0 StarServer) have all of these and */
129
/* HAVE_PTC works best */
130
#undef HAVE_GETPTY
131
#undef HAVE__GETPTY
132
#endif
133
 
134
#if defined(HAVE__GETPTY) || defined(HAVE_PTC_PTS) || defined(HAVE_PTMX)
135
static char *slave_name;
136
#endif
137
 
138
#if defined(HAVE_GETPTY)
139
#include <sys/vty.h>
140
static char master_name[MAXPTYNAMELEN];
141
static char slave_name[MAXPTYNAMELEN];
142
#endif
143
 
144
#if !defined(HAVE_GETPTY) && !defined(HAVE__GETPTY) && !defined(HAVE_PTC) && !defined(HAVE_PTC_PTS) && !defined(HAVE_PTMX) && !defined(HAVE_CONVEX_GETPTY) && !defined(_SEQUENT_) && !defined(HAVE_SCO_CLIST_PTYS) && !defined(HAVE_OPENPTY)
145
#ifdef HAVE_PTYM
146
                        /* strange order and missing d is intentional */
147
static char     banks[] = "pqrstuvwxyzabcefghijklo";
148
static char     master_name[] = "/dev/ptym/ptyXXXX";
149
static char     slave_name[] = "/dev/pty/ttyXXXX";
150
static char     *slave_bank;
151
static char     *slave_num;
152
#else
153
static char     banks[] = "pqrstuvwxyzPQRSTUVWXYZ";
154
static char     master_name[] = "/dev/ptyXX";
155
static char     slave_name [] = "/dev/ttyXX";
156
#endif /* HAVE_PTYM */
157
 
158
static char     *tty_type;              /* ptr to char [pt] denoting
159
                                           whether it is a pty or tty */
160
static char     *tty_bank;              /* ptr to char [p-z] denoting
161
                                           which bank it is */
162
static char     *tty_num;               /* ptr to char [0-f] denoting
163
                                           which number it is */
164
#endif
165
 
166
#if defined(HAVE_SCO_CLIST_PTYS)
167
#  define MAXPTYNAMELEN 64
168
static char master_name[MAXPTYNAMELEN];
169
static char slave_name[MAXPTYNAMELEN];
170
#endif /* HAVE_SCO_CLIST_PTYS */
171
 
172
#ifdef HAVE_OPENPTY
173
static char master_name[64];
174
static char slave_name[64];
175
#endif
176
 
177
char *exp_pty_slave_name;
178
char *exp_pty_error;
179
 
180
#if 0
181
static void
182
pty_stty(s,name)
183
char *s;                /* args to stty */
184
char *name;             /* name of pty */
185
{
186
#define MAX_ARGLIST 10240
187
        char buf[MAX_ARGLIST];  /* overkill is easier */
188
        RETSIGTYPE (*old)();    /* save old sigalarm handler */
189
        int pid;
190
 
191
        old = signal(SIGCHLD, SIG_DFL);
192
        switch (pid = fork()) {
193
        case 0: /* child */
194
                exec_stty("/bin/stty","/bin/stty",s);
195
                break;
196
        case -1: /* fail */
197
        default: /* parent */
198
                waitpid(pid);
199
                break;
200
        }
201
 
202
        signal(SIGCHLD, old);   /* restore signal handler */
203
}
204
 
205
exec_stty(s)
206
char *s;
207
{
208
        char *args[50];
209
        char *cp;
210
        int argi = 0;
211
        int quoting = FALSE;
212
        int in_token = FALSE;   /* TRUE if we are reading a token */
213
 
214
        args[0] = cp = s;
215
        while (*s) {
216
                if (quoting) {
217
                        if (*s == '\\' && *(s+1) == '"') { /* quoted quote */
218
                                s++;    /* get past " */
219
                                *cp++ = *s++;
220
                        } else  if (*s == '\"') { /* close quote */
221
                                end_token
222
                                quoting = FALSE;
223
                        } else *cp++ = *s++; /* suck up anything */
224
                } else if (*s == '\"') { /* open quote */
225
                        in_token = TRUE;
226
                        quoting = TRUE;
227
                        s++;
228
                } else if (isspace(*s)) {
229
                        end_token
230
                } else {
231
                        *cp++ = *s++;
232
                        in_token = TRUE;
233
                }
234
        }
235
        end_token
236
        args[argi] = (char *) 0; /* terminate argv */
237
        execvp(args[0],args);
238
}
239
#endif /*0*/
240
 
241
static void
242
pty_stty(s,name)
243
char *s;                /* args to stty */
244
char *name;             /* name of pty */
245
{
246
#define MAX_ARGLIST 10240
247
        char buf[MAX_ARGLIST];  /* overkill is easier */
248
        RETSIGTYPE (*old)();    /* save old sigalarm handler */
249
 
250
#ifdef STTY_READS_STDOUT
251
        sprintf(buf,"/bin/stty %s > %s",s,name);
252
#else
253
#ifdef __CYGWIN32__
254
        sprintf(buf,"stty %s < %s",s,name);
255
#else
256
        sprintf(buf,"/bin/stty %s < %s",s,name);
257
#endif
258
#endif
259
        old = signal(SIGCHLD, SIG_DFL);
260
        system(buf);
261
        signal(SIGCHLD, old);   /* restore signal handler */
262
}
263
 
264
int exp_dev_tty;        /* file descriptor to /dev/tty or -1 if none */
265
static int knew_dev_tty;/* true if we had our hands on /dev/tty at any time */
266
 
267
exp_tty exp_tty_original;
268
 
269
#define GET_TTYTYPE     0
270
#define SET_TTYTYPE     1
271
static void
272
ttytype(request,fd,ttycopy,ttyinit,s)
273
int request;
274
int fd;
275
                /* following are used only if request == SET_TTYTYPE */
276
int ttycopy;    /* true/false, copy from /dev/tty */
277
int ttyinit;    /* if true, initialize to sane state */
278
char *s;        /* stty args */
279
{
280
        if (request == GET_TTYTYPE) {
281
#ifdef HAVE_TCSETATTR
282
                if (-1 == tcgetattr(fd, &exp_tty_original)) {
283
#else
284
                if (-1 == ioctl(fd, TCGETS, (char *)&exp_tty_original)) {
285
#endif
286
                        knew_dev_tty = FALSE;
287
                        exp_dev_tty = -1;
288
                }
289
                exp_window_size_get(fd);
290
        } else {        /* type == SET_TTYTYPE */
291
                if (ttycopy && knew_dev_tty) {
292
#ifdef HAVE_TCSETATTR
293
                        (void) tcsetattr(fd, TCSADRAIN, &exp_tty_current);
294
#else
295
                        (void) ioctl(fd, TCSETS, (char *)&exp_tty_current);
296
#endif
297
 
298
                        exp_window_size_set(fd);
299
                }
300
 
301
#ifdef __CENTERLINE__
302
#undef DFLT_STTY
303
#define DFLT_STTY "sane"
304
#endif
305
 
306
/* Apollo Domain doesn't need this */
307
#ifdef DFLT_STTY
308
                if (ttyinit) {
309
                        /* overlay parms originally supplied by Makefile */
310
/* As long as BSD stty insists on stdout == stderr, we can no longer write */
311
/* diagnostics to parent stderr, since stderr has is now child's */
312
/* Maybe someday they will fix stty? */
313
/*                      debuglog("getptyslave: (default) stty %s\n",DFLT_STTY);*/
314
                        pty_stty(DFLT_STTY,slave_name);
315
                }
316
#endif
317
 
318
                /* lastly, give user chance to override any terminal parms */
319
                if (s) {
320
                        /* give user a chance to override any terminal parms */
321
/*                      debuglog("getptyslave: (user-requested) stty %s\n",s);*/
322
                        pty_stty(s,slave_name);
323
                }
324
        }
325
}
326
 
327
void
328
exp_init_pty()
329
{
330
#if !defined(HAVE_GETPTY) && !defined(HAVE__GETPTY) && !defined(HAVE_PTC) && !defined(HAVE_PTC_PTS) && !defined(HAVE_PTMX) && !defined(HAVE_CONVEX_GETPTY) && !defined(_SEQUENT_) && !defined(HAVE_SCO_CLIST_PTYS) && !defined(HAVE_OPENPTY)
331
#ifdef HAVE_PTYM
332
        static char dummy;
333
        tty_bank =  &master_name[strlen("/dev/ptym/pty")];
334
        tty_num  =  &master_name[strlen("/dev/ptym/ptyX")];
335
        slave_bank = &slave_name[strlen("/dev/pty/tty")];
336
        slave_num  = &slave_name[strlen("/dev/pty/ttyX")];
337
#else
338
        tty_bank =  &master_name[strlen("/dev/pty")];
339
        tty_num  =  &master_name[strlen("/dev/ptyp")];
340
        tty_type =   &slave_name[strlen("/dev/")];
341
#endif
342
 
343
#endif /* HAVE_PTYM */
344
 
345
 
346
        exp_dev_tty = open("/dev/tty",O_RDWR);
347
        knew_dev_tty = (exp_dev_tty != -1);
348
        if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0);
349
}
350
 
351
#ifndef R_OK
352
/* 3b2 doesn't define these according to jthomas@nmsu.edu. */
353
#define R_OK 04
354
#define W_OK 02
355
#endif
356
 
357
int
358
getptymaster()
359
{
360
        char *hex, *bank;
361
        struct stat stat_buf;
362
        int master = -1;
363
        int slave = -1;
364
        int num;
365
 
366
        exp_pty_error = 0;
367
 
368
#define TEST_PTY 1
369
 
370
#if defined(HAVE_PTMX) || defined(HAVE_PTMX_BSD)
371
#undef TEST_PTY
372
#if defined(HAVE_PTMX_BSD)
373
        if ((master = open("/dev/ptmx_bsd", O_RDWR)) == -1) return(-1);
374
#else
375
        if ((master = open("/dev/ptmx", O_RDWR)) == -1) return(-1);
376
#endif
377
        if ((slave_name = (char *)ptsname(master)) == NULL || unlockpt(master)) {
378
                close(master);
379
                return(-1);
380
        } else if (grantpt(master)) {
381
                static char buf[500];
382
                exp_pty_error = buf;
383
                sprintf(exp_pty_error,"grantpt(%d) failed - likely reason is that your system administrator (in a rage of blind passion to rid the system of security holes) removed setuid from the utility used internally by grantpt to change pty permissions.  Tell your system admin to reestablish setuid on the utility.  Get the utility name by running Expect under truss or trace.");
384
                close(master);
385
                return(-1);
386
        }
387
#ifdef TIOCFLUSH
388
        (void) ioctl(master,TIOCFLUSH,(char *)0);
389
#endif /* TIOCFLUSH */
390
 
391
        exp_pty_slave_name = slave_name;
392
        return(master);
393
#endif
394
 
395
#if defined(HAVE__GETPTY)               /* SGI needs it this way */
396
#undef TEST_PTY
397
        slave_name = _getpty(&master, O_RDWR, 0600, 0);
398
        if (slave_name == NULL)
399
                return (-1);
400
        exp_pty_slave_name = slave_name;
401
        return(master);
402
#endif
403
 
404
#if defined(HAVE_PTC) && !defined(HAVE__GETPTY) /* old SGI, version 3 */
405
#undef TEST_PTY
406
        master = open("/dev/ptc", O_RDWR);
407
        if (master >= 0) {
408
                int ptynum;
409
 
410
                if (fstat(master, &stat_buf) < 0) {
411
                        close(master);
412
                        return(-1);
413
                }
414
                ptynum = minor(stat_buf.st_rdev);
415
                sprintf(slave_name,"/dev/ttyq%d",ptynum);
416
        }
417
        exp_pty_slave_name = slave_name;
418
        return(master);
419
#endif
420
 
421
#if defined(HAVE_GETPTY) && !defined(HAVE__GETPTY)
422
#undef TEST_PTY
423
        master = getpty(master_name, slave_name, O_RDWR);
424
        /* is it really necessary to verify slave side is usable? */
425
        exp_pty_slave_name = slave_name;
426
        return master;
427
#endif
428
 
429
#if defined(HAVE_PTC_PTS)
430
#undef TEST_PTY
431
        master = open("/dev/ptc",O_RDWR);
432
        if (master >= 0) {
433
                /* never fails */
434
                slave_name = ttyname(master);
435
        }
436
        exp_pty_slave_name = slave_name;
437
        return(master);
438
#endif
439
 
440
#if defined(_SEQUENT_) && !defined(HAVE_PTMX)
441
#undef TEST_PTY
442
        /* old-style SEQUENT, new-style uses ptmx */
443
        master = getpseudotty(&slave_name, &master_name);
444
        exp_pty_slave_name = slave_name;
445
        return(master);
446
#endif /* _SEQUENT_ */
447
 
448
#if defined(HAVE_OPENPTY)
449
#undef TEST_PTY
450
        if (openpty(&master, &slave, master_name, 0, 0) != 0) {
451
                close(master);
452
                close(slave);
453
                return -1;
454
        }
455
        strcpy(slave_name, ttyname(slave));
456
        exp_pty_slave_name = slave_name;
457
        close(slave);
458
        return master;
459
#endif /* HAVE_OPENPTY */
460
 
461
#if defined(TEST_PTY)
462
        /*
463
         * all pty allocation mechanisms after this require testing
464
         */
465
        if (exp_pty_test_start() == -1) return -1;
466
 
467
#if !defined(HAVE_CONVEX_GETPTY) && !defined(HAVE_PTYM) && !defined(HAVE_SCO_CLIST_PTYS)
468
        for (bank = banks;*bank;bank++) {
469
                *tty_bank = *bank;
470
                *tty_num = '0';
471
                if (stat(master_name, &stat_buf) < 0) break;
472
                for (hex = "0123456789abcdef";*hex;hex++) {
473
                        *tty_num = *hex;
474
                        strcpy(slave_name,master_name);
475
                        *tty_type = 't';
476
                        master = exp_pty_test(master_name,slave_name,*tty_bank,tty_num);
477
                        if (master >= 0) goto done;
478
                }
479
        }
480
#endif
481
 
482
#ifdef HAVE_SCO_CLIST_PTYS
483
        for (num = 0; ; num++) {
484
            char num_str [16];
485
 
486
            sprintf (num_str, "%d", num);
487
            sprintf (master_name, "%s%s", "/dev/ptyp", num_str);
488
            if (stat (master_name, &stat_buf) < 0)
489
                break;
490
            sprintf (slave_name, "%s%s", "/dev/ttyp", num_str);
491
 
492
            master = exp_pty_test (master_name, slave_name, 0, num_str);
493
            if (master >= 0)
494
                goto done;
495
        }
496
#endif
497
 
498
#ifdef HAVE_PTYM
499
        /* systems with PTYM follow this idea:
500
 
501
           /dev/ptym/pty[a-ce-z][0-9a-f]                master pseudo terminals
502
           /dev/pty/tty[a-ce-z][0-9a-f]                 slave pseudo terminals
503
           /dev/ptym/pty[a-ce-z][0-9][0-9]              master pseudo terminals
504
           /dev/pty/tty[a-ce-z][0-9][0-9]               slave pseudo terminals
505
 
506
           SPPUX (Convex's HPUX compatible) follows the PTYM convention but
507
           extends it:
508
 
509
           /dev/ptym/pty[a-ce-z][0-9][0-9][0-9]         master pseudo terminals
510
           /dev/pty/tty[a-ce-z][0-9][0-9][0-9]          slave pseudo terminals
511
 
512
           The code does not distinguish between HPUX and SPPUX because there
513
           is no reason to.  HPUX will merely fail the extended SPPUX tests.
514
           In fact, most SPPUX systems will fail simply because few systems
515
           will actually have the extended ptys.  However, the tests are
516
           fast so it is no big deal.
517
         */
518
 
519
        /*
520
         * pty[a-ce-z][0-9a-f]
521
         */
522
 
523
        for (bank = banks;*bank;bank++) {
524
                *tty_bank = *bank;
525
                sprintf(tty_num,"0");
526
                if (stat(master_name, &stat_buf) < 0) break;
527
                *(slave_num+1) = '\0';
528
                for (hex = "0123456789abcdef";*hex;hex++) {
529
                        *tty_num = *hex;
530
                        *slave_bank = *tty_bank;
531
                        *slave_num = *tty_num;
532
                        master = exp_pty_test(master_name,slave_name,*tty_bank,tty_num);
533
                        if (master >= 0) goto done;
534
                }
535
        }
536
 
537
        /*
538
         * tty[p-za-ce-o][0-9][0-9]
539
         */
540
 
541
        for (bank = banks;*bank;bank++) {
542
                *tty_bank = *bank;
543
                sprintf(tty_num,"00");
544
                if (stat(master_name, &stat_buf) < 0) break;
545
                for (num = 0; num<100; num++) {
546
                        *slave_bank = *tty_bank;
547
                        sprintf(tty_num,"%02d",num);
548
                        strcpy(slave_num,tty_num);
549
                        master = exp_pty_test(master_name,slave_name,tty_bank,tty_num);
550
                        if (master >= 0) goto done;
551
                }
552
        }
553
 
554
        /*
555
         * tty[p-za-ce-o][0-9][0-9][0-9]
556
         */
557
        for (bank = banks;*bank;bank++) {
558
                *tty_bank = *bank;
559
                sprintf(tty_num,"000");
560
                if (stat(master_name, &stat_buf) < 0) break;
561
                for (num = 0; num<1000; num++) {
562
                        *slave_bank = *tty_bank;
563
                        sprintf(tty_num,"%03d",num);
564
                        strcpy(slave_num,tty_num);
565
                        master = exp_pty_test(master_name,slave_name,tty_bank,tty_num);
566
                        if (master >= 0) goto done;
567
                }
568
        }
569
 
570
#endif /* HAVE_PTYM */
571
 
572
#if defined(HAVE_CONVEX_GETPTY)
573
        for (;;) {
574
                if ((master_name = getpty()) == NULL) return -1;
575
 
576
                strcpy(slave_name,master_name);
577
                slave_name[5] = 't';/* /dev/ptyXY ==> /dev/ttyXY */
578
 
579
                tty_bank = &slave_name[8];
580
                tty_num = &slave_name[9];
581
                master = exp_pty_test(master_name,slave_name,*tty_bank,tty_num);
582
                if (master >= 0) goto done;
583
        }
584
#endif
585
 
586
 done:
587
        exp_pty_test_end();
588
        exp_pty_slave_name = slave_name;
589
        return(master);
590
 
591
#endif /* defined(TEST_PTY) */
592
}
593
 
594
/* if slave is opened in a child, slave_control(1) must be executed after */
595
/*   master is opened (when child is opened is irrelevent) */
596
/* if slave is opened in same proc as master, slave_control(1) must executed */
597
/*   after slave is opened */
598
/*ARGSUSED*/
599
void
600
exp_slave_control(master,control)
601
int master;
602
int control;    /* if 1, enable pty trapping of close/open/ioctl */
603
{
604
#ifdef HAVE_PTYTRAP
605
        ioctl(master, TIOCTRAP, &control);
606
#endif /* HAVE_PTYTRAP */
607
}
608
 
609
int
610
getptyslave(ttycopy,ttyinit,stty_args)
611
int ttycopy;
612
int ttyinit;
613
char *stty_args;
614
{
615
        int slave, slave2;
616
        char buf[10240];
617
 
618
        if (0 > (slave = open(slave_name, O_RDWR))) return(-1);
619
 
620
#if defined(HAVE_PTMX_BSD)
621
        if (ioctl (slave, I_LOOK, buf) != 0)
622
                if (ioctl (slave, I_PUSH, "ldterm")) {
623
                        debuglog("ioctl(%s,I_PUSH,\"ldterm\") = %s\n",Tcl_ErrnoMsg(errno));
624
        }
625
#else
626
#if defined(HAVE_PTMX) && ! defined(__CYGWIN32__)
627
        if (ioctl(slave, I_PUSH, "ptem")) {
628
                debuglog("ioctl(%s,I_PUSH,\"ptem\") = %s\n",Tcl_ErrnoMsg(errno));
629
        }
630
        if (ioctl(slave, I_PUSH, "ldterm")) {
631
                debuglog("ioctl(%s,I_PUSH,\"ldterm\") = %s\n",Tcl_ErrnoMsg(errno));
632
        }
633
        if (ioctl(slave, I_PUSH, "ttcompat")) {
634
                debuglog("ioctl(%s,I_PUSH,\"ttcompat\") = %s\n",Tcl_ErrnoMsg(errno));
635
        }
636
#endif
637
#endif
638
 
639
        if (0 == slave) {
640
                /* if opened in a new process, slave will be 0 (and */
641
                /* ultimately, 1 and 2 as well) */
642
 
643
                /* duplicate 0 onto 1 and 2 to prepare for stty */
644
                fcntl(0,F_DUPFD,1);
645
                fcntl(0,F_DUPFD,2);
646
        }
647
 
648
        ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args);
649
 
650
#if 0
651
#ifdef HAVE_PTYTRAP
652
        /* do another open, to tell master that slave is done fiddling */
653
        /* with pty and master does not have to wait to do further acks */
654
        if (0 > (slave2 = open(slave_name, O_RDWR))) return(-1);
655
        close(slave2);
656
#endif /* HAVE_PTYTRAP */
657
#endif
658
 
659
        (void) exp_pty_unlock();
660
        return(slave);
661
}
662
 
663
#ifdef HAVE_PTYTRAP
664
#include <sys/ptyio.h>
665
#include <sys/time.h>
666
 
667
/* This function attempts to deal with HP's pty interface.  This
668
function simply returns an indication of what was trapped (or -1 for
669
failure), the parent deals with the details.
670
 
671
Originally, I tried to just trap open's but that is not enough.  When
672
the pty is initialized, ioctl's are generated and if not trapped will
673
hang the child if no further trapping is done.  (This could occur if
674
parent spawns a process and then immediatley does a close.)  So
675
instead, the parent must trap the ioctl's.  It probably suffices to
676
trap the write ioctl's (and tiocsctty which some hp's need) -
677
conceivably, stty could be smart enough not to do write's if the tty
678
settings are already correct.  In that case, we'll have to rethink
679
this.
680
 
681
Suggestions from HP engineers encouraged.  I cannot imagine how this
682
interface was intended to be used!
683
 
684
*/
685
 
686
int
687
exp_wait_for_slave_open(fd)
688
int fd;
689
{
690
        fd_set excep;
691
        struct timeval t;
692
        struct request_info ioctl_info;
693
        int rc;
694
        int found = 0;
695
 
696
        int maxfds = sysconf(_SC_OPEN_MAX);
697
 
698
        t.tv_sec = 30;  /* 30 seconds */
699
        t.tv_usec = 0;
700
 
701
        FD_ZERO(&excep);
702
        FD_SET(fd,&excep);
703
 
704
        rc = select(maxfds,
705
                (SELECT_MASK_TYPE *)0,
706
                (SELECT_MASK_TYPE *)0,
707
                (SELECT_MASK_TYPE *)&excep,
708
                &t);
709
        if (rc != 1) {
710
                debuglog("spawned process never started, errno = %d\n",errno);
711
                return(-1);
712
        }
713
        if (ioctl(fd,TIOCREQCHECK,&ioctl_info) < 0) {
714
                debuglog("ioctl(TIOCREQCHECK) failed, errno = %d\n",errno);
715
                return(-1);
716
        }
717
 
718
        found = ioctl_info.request;
719
 
720
        debuglog("trapped pty op = %x",found);
721
        if (found == TIOCOPEN) {
722
                debuglog(" TIOCOPEN");
723
        } else if (found == TIOCCLOSE) {
724
                debuglog(" TIOCCLOSE");
725
        }
726
 
727
#ifdef TIOCSCTTY
728
        if (found == TIOCSCTTY) {
729
                debuglog(" TIOCSCTTY");
730
        }
731
#endif
732
 
733
        if (found & IOC_IN) {
734
                debuglog(" IOC_IN (set)");
735
        } else if (found & IOC_OUT) {
736
                debuglog(" IOC_OUT (get)");
737
        }
738
 
739
        debuglog("\n");
740
 
741
        if (ioctl(fd, TIOCREQSET, &ioctl_info) < 0) {
742
                debuglog("ioctl(TIOCREQSET) failed, errno = %d\n",errno);
743
                return(-1);
744
        }
745
        return(found);
746
}
747
#endif
748
 
749
void
750
exp_pty_exit()
751
{
752
        /* a stub so we can do weird things on the cray */
753
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.