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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [expect/] [exp_tty.c] - Blame information for rev 1778

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

Line No. Rev Author Line
1 578 markom
/* exp_tty.c - tty support routines */
2
 
3
#include "expect_cf.h"
4
#include <stdio.h>
5
#include <signal.h>
6
#include "string.h"
7
 
8
#ifdef HAVE_SYS_FCNTL_H
9
#  include <sys/fcntl.h>
10
#else
11
#  include <fcntl.h>
12
#endif
13
 
14
#include <sys/stat.h>
15
 
16
#ifdef HAVE_INTTYPES_H
17
#  include <inttypes.h>
18
#endif
19
#include <sys/types.h>
20
 
21
#ifdef HAVE_UNISTD_H
22
# include <unistd.h>
23
#endif
24
 
25
#ifdef HAVE_SYS_WAIT_H
26
#include <sys/wait.h>
27
#endif
28
 
29
#if defined(SIGCLD) && !defined(SIGCHLD)
30
#define SIGCHLD SIGCLD
31
#endif
32
 
33
#include "tcl.h"
34
#include "exp_prog.h"
35
#include "exp_rename.h"
36
#include "exp_tty_in.h"
37
#include "exp_log.h"
38
#include "exp_command.h"
39
 
40
static int is_raw = FALSE;
41
static int is_noecho = FALSE;
42
 
43
int exp_ioctled_devtty = FALSE;
44
int exp_stdin_is_tty;
45
int exp_stdout_is_tty;
46
 
47
/*static*/ extern exp_tty exp_tty_current, exp_tty_cooked;
48
#define tty_current exp_tty_current
49
#define tty_cooked exp_tty_cooked
50
 
51
int
52
exp_israw()
53
{
54
        return is_raw;
55
}
56
 
57
int
58
exp_isecho()
59
{
60
        return !is_noecho;
61
}
62
 
63
/* if set == 1, set it to raw, else unset it */
64
void
65
exp_tty_raw(set)
66
int set;
67
{
68
        if (set == 1) {
69
                is_raw = TRUE;
70
#if defined(HAVE_TERMIOS) || defined(HAVE_TERMIO) /* had POSIX too */
71
                tty_current.c_iflag = 0;
72
                tty_current.c_oflag = 0;
73
                tty_current.c_lflag &= ECHO;  /* disable everything but echo */
74
                tty_current.c_cc[VMIN] = 1;
75
                tty_current.c_cc[VTIME] = 0;
76
        } else {
77
                tty_current.c_iflag = tty_cooked.c_iflag;
78
                tty_current.c_oflag = tty_cooked.c_oflag;
79
/*              tty_current.c_lflag = tty_cooked.c_lflag;*/
80
/* attempt 2    tty_current.c_lflag = tty_cooked.c_lflag & ~ECHO;*/
81
                /* retain current echo setting */
82
                tty_current.c_lflag = (tty_cooked.c_lflag & ~ECHO) | (tty_current.c_lflag & ECHO);
83
                tty_current.c_cc[VMIN] = tty_cooked.c_cc[VMIN];
84
                tty_current.c_cc[VTIME] = tty_cooked.c_cc[VTIME];
85
#else
86
#  if defined(HAVE_SGTTYB)
87
                tty_current.sg_flags |= RAW;
88
        } else {
89
                tty_current.sg_flags = tty_cooked.sg_flags;
90
#  endif
91
#endif
92
                is_raw = FALSE;
93
        }
94
}
95
 
96
void
97
exp_tty_echo(set)
98
int set;
99
{
100
        if (set == 1) {
101
                is_noecho = FALSE;
102
#if defined(HAVE_TERMIOS) || defined(HAVE_TERMIO) /* had POSIX too */
103
                tty_current.c_lflag |= ECHO;
104
        } else {
105
                tty_current.c_lflag &= ~ECHO;
106
#else
107
                tty_current.sg_flags |= ECHO;
108
        } else {
109
                tty_current.sg_flags &= ~ECHO;
110
#endif
111
                is_noecho = TRUE;
112
        }
113
}
114
 
115
int
116
exp_tty_set_simple(tty)
117
exp_tty *tty;
118
{
119
#ifdef HAVE_TCSETATTR
120
        return(tcsetattr(exp_dev_tty, TCSADRAIN,tty));
121
#else
122
        return(ioctl    (exp_dev_tty, TCSETSW  ,tty));
123
#endif
124
}
125
 
126
int
127
exp_tty_get_simple(tty)
128
exp_tty *tty;
129
{
130
#ifdef HAVE_TCSETATTR
131
        return(tcgetattr(exp_dev_tty,         tty));
132
#else
133
        return(ioctl    (exp_dev_tty, TCGETS, tty));
134
#endif
135
}
136
 
137
/* returns 0 if nothing changed */
138
/* if something changed, the out parameters are changed as well */
139
int
140
exp_tty_raw_noecho(interp,tty_old,was_raw,was_echo)
141
Tcl_Interp *interp;
142
exp_tty *tty_old;
143
int *was_raw, *was_echo;
144
{
145
        if (exp_disconnected) return(0);
146
        if (is_raw && is_noecho) return(0);
147
        if (exp_dev_tty == -1) return(0);
148
 
149
        *tty_old = tty_current;         /* save old parameters */
150
        *was_raw = is_raw;
151
        *was_echo = !is_noecho;
152
        debuglog("tty_raw_noecho: was raw = %d  echo = %d\r\n",is_raw,!is_noecho);
153
 
154
        exp_tty_raw(1);
155
        exp_tty_echo(-1);
156
 
157
        if (exp_tty_set_simple(&tty_current) == -1) {
158
                errorlog("ioctl(raw): %s\r\n",Tcl_PosixError(interp));
159
                exp_exit(interp,1);
160
        }
161
 
162
        exp_ioctled_devtty = TRUE;
163
        return(1);
164
}
165
 
166
/* returns 0 if nothing changed */
167
/* if something changed, the out parameters are changed as well */
168
int
169
exp_tty_cooked_echo(interp,tty_old,was_raw,was_echo)
170
Tcl_Interp *interp;
171
exp_tty *tty_old;
172
int *was_raw, *was_echo;
173
{
174
        if (exp_disconnected) return(0);
175
        if (!is_raw && !is_noecho) return(0);
176
        if (exp_dev_tty == -1) return(0);
177
 
178
        *tty_old = tty_current;         /* save old parameters */
179
        *was_raw = is_raw;
180
        *was_echo = !is_noecho;
181
        debuglog("tty_cooked_echo: was raw = %d  echo = %d\r\n",is_raw,!is_noecho);
182
 
183
        exp_tty_raw(-1);
184
        exp_tty_echo(1);
185
 
186
        if (exp_tty_set_simple(&tty_current) == -1) {
187
                errorlog("ioctl(noraw): %s\r\n",Tcl_PosixError(interp));
188
                exp_exit(interp,1);
189
        }
190
        exp_ioctled_devtty = TRUE;
191
 
192
        return(1);
193
}
194
 
195
void
196
exp_tty_set(interp,tty,raw,echo)
197
Tcl_Interp *interp;
198
exp_tty *tty;
199
int raw;
200
int echo;
201
{
202
        if (exp_tty_set_simple(tty) == -1) {
203
                errorlog("ioctl(set): %s\r\n",Tcl_PosixError(interp));
204
                exp_exit(interp,1);
205
        }
206
        is_raw = raw;
207
        is_noecho = !echo;
208
        tty_current = *tty;
209
        debuglog("tty_set: raw = %d, echo = %d\r\n",is_raw,!is_noecho);
210
        exp_ioctled_devtty = TRUE;
211
}
212
 
213
#if 0
214
/* avoids scoping problems */
215
void
216
exp_update_cooked_from_current() {
217
        tty_cooked = tty_current;
218
}
219
 
220
int
221
exp_update_real_tty_from_current() {
222
        return(exp_tty_set_simple(&tty_current));
223
}
224
 
225
int
226
exp_update_current_from_real_tty() {
227
        return(exp_tty_get_simple(&tty_current));
228
}
229
#endif
230
 
231
void
232
exp_init_stdio()
233
{
234
        exp_stdin_is_tty = isatty(0);
235
        exp_stdout_is_tty = isatty(1);
236
 
237
        setbuf(stdout,(char *)0);        /* unbuffer stdout */
238
}
239
 
240
/*ARGSUSED*/
241
void
242
exp_tty_break(interp,fd)
243
Tcl_Interp *interp;
244
int fd;
245
{
246
#ifdef POSIX
247
        tcsendbreak(fd,0);
248
#else
249
# ifdef TIOCSBRK
250
        ioctl(fd,TIOCSBRK,0);
251
        exp_dsleep(interp,0.25); /* sleep for at least a quarter of a second */
252
        ioctl(fd,TIOCCBRK,0);
253
# else
254
        /* dunno how to do this - ignore */
255
# endif
256
#endif
257
}
258
 
259
/* take strings with newlines and insert carriage-returns.  This allows user */
260
/* to write send_user strings without always putting in \r. */
261
/* If len == 0, use strlen to compute it */
262
/* NB: if terminal is not in raw mode, nothing is done. */
263
char *
264
exp_cook(s,len)
265
char *s;
266
int *len;       /* current and new length of s */
267
{
268
        static int destlen = 0;
269
        static char *dest = 0;
270
        char *d;                /* ptr into dest */
271
        unsigned int need;
272
 
273
        if (s == 0) return("<null>");
274
 
275
        if (!is_raw) return(s);
276
 
277
        /* worst case is every character takes 2 to represent */
278
        need = 1 + 2*(len?*len:strlen(s));
279
        if (need > destlen) {
280
                if (dest) ckfree(dest);
281
                dest = ckalloc(need);
282
                destlen = need;
283
        }
284
 
285
        for (d = dest;*s;s++) {
286
                if (*s == '\n') {
287
                        *d++ = '\r';
288
                        *d++ = '\n';
289
                } else {
290
                        *d++ = *s;
291
                }
292
        }
293
        *d = '\0';
294
        if (len) *len = d-dest;
295
        return(dest);
296
}
297
 
298
/* this stupidity because Tcl needs commands in writable space */
299
static char exec_cmd[] = "exec";
300
static char stty_cmd[] = "/bin/stty";
301
 
302
static int              /* returns TCL_whatever */
303
exec_stty(interp,argc,argv,devtty)
304
Tcl_Interp *interp;
305
int argc;
306
char **argv;
307
int devtty;             /* if true, redirect to /dev/tty */
308
{
309
        char **new_argv;
310
        int i;
311
        int rc;
312
 
313
        /* insert "system" at front, null at end, */
314
        /* and optional redirect in middle, hence "+3" */
315
        new_argv = (char **)ckalloc((3+argc)*sizeof(char *));
316
        new_argv[0] = exec_cmd;
317
        new_argv[1] = stty_cmd;
318
        for (i=1;i<argc;i++) {
319
                new_argv[i+1] = argv[i];
320
        }
321
        if (devtty) new_argv[++i] =
322
#ifdef STTY_READS_STDOUT
323
                ">/dev/tty";
324
#else
325
                "</dev/tty";
326
#endif
327
 
328
        new_argv[i+1] = (char *)0;
329
 
330
        Tcl_ResetResult(interp);
331
 
332
        /* normally, I wouldn't set one of Tcl's own variables, but in this */
333
        /* case, I only only want to see if Tcl resets it to non-NONE, */
334
        /* and I don't know any other way of doing it */
335
        Tcl_SetVar(interp,"errorCode","NONE",0);
336
        rc = Tcl_ExecCmd((ClientData)0,interp,argc+1+devtty,new_argv);
337
 
338
        ckfree((char *)new_argv);
339
 
340
        /* if stty-reads-stdout, stty will fail since Exec */
341
        /* will detect the stderr.  Only by examining errorCode */
342
        /* can we tell if a real error occurred. */
343
 
344
#ifdef STTY_READS_STDOUT
345
        if (rc == TCL_ERROR) {
346
                char *ec = Tcl_GetVar(interp,"errorCode",TCL_GLOBAL_ONLY);
347
                if (ec && !streq(ec,"NONE")) return TCL_ERROR;
348
        }
349
#endif
350
        return TCL_OK;
351
}
352
 
353
/*ARGSUSED*/
354
static int
355
Exp_SttyCmd(clientData, interp, argc, argv)
356
ClientData clientData;
357
Tcl_Interp *interp;
358
int argc;
359
char **argv;
360
{
361
        /* redirection symbol is not counted as a stty arg in terms */
362
        /* of recognition. */
363
        int saw_unknown_stty_arg = FALSE;
364
        int saw_known_stty_arg = FALSE;
365
        int no_args = TRUE;
366
 
367
        int rc = TCL_OK;
368
        int cooked = FALSE;
369
        int was_raw, was_echo;
370
 
371
 
372
        char **redirect;        /* location of "<" */
373
        char *infile = 0;
374
        int fd;                 /* (slave) fd of infile */
375
        int master = -1;        /* master fd of infile */
376
        char **argv0 = argv;
377
 
378
        for (argv=argv0+1;*argv;argv++) {
379
                if (argv[0][0] == '<') {
380
                        redirect = argv;
381
                        infile = *(argv+1);
382
                        if (!infile) {
383
                                errorlog("usage: < ttyname");
384
                                return TCL_ERROR;
385
                        }
386
                        if (streq(infile,"/dev/tty")) {
387
                                infile = 0;
388
                                *argv = 0;
389
                                *(argv+1) = 0;
390
                                argc -= 2;
391
                        } else {
392
                                master = exp_trap_off(infile);
393
                                if (-1 == (fd = open(infile,2))) {
394
                                        errorlog("couldn't open %s: %s",
395
                                         infile,Tcl_PosixError(interp));
396
                                        return TCL_ERROR;
397
                                }
398
                        }
399
                        break;
400
                }
401
        }
402
 
403
        if (!infile) {          /* work on /dev/tty */
404
                was_raw = exp_israw();
405
                was_echo = exp_isecho();
406
 
407
                exp_ioctled_devtty = TRUE;
408
 
409
                for (argv=argv0+1;*argv;argv++) {
410
                        if (streq(*argv,"raw") ||
411
                            streq(*argv,"-cooked")) {
412
                                exp_tty_raw(1);
413
                                saw_known_stty_arg = TRUE;
414
                                no_args = FALSE;
415
                        } else if (streq(*argv,"-raw") ||
416
                                   streq(*argv,"cooked")) {
417
                                cooked = TRUE;
418
                                exp_tty_raw(-1);
419
                                saw_known_stty_arg = TRUE;
420
                                no_args = FALSE;
421
                        } else if (streq(*argv,"echo")) {
422
                                exp_tty_echo(1);
423
                                saw_known_stty_arg = TRUE;
424
                                no_args = FALSE;
425
                        } else if (streq(*argv,"-echo")) {
426
                                exp_tty_echo(-1);
427
                                saw_known_stty_arg = TRUE;
428
                                no_args = FALSE;
429
                        } else if (streq(*argv,"rows")) {
430
                                if (*(argv+1)) {
431
                                        exp_win_rows_set(*(argv+1));
432
                                        argv++;
433
                                        no_args = FALSE;
434
                                } else {
435
                                        exp_win_rows_get(interp->result);
436
                                        return TCL_OK;
437
                                }
438
                        } else if (streq(*argv,"columns")) {
439
                                if (*(argv+1)) {
440
                                        exp_win_columns_set(*(argv+1));
441
                                        argv++;
442
                                        no_args = FALSE;
443
                                } else {
444
                                        exp_win_columns_get(interp->result);
445
                                        return TCL_OK;
446
                                }
447
                        } else {
448
                                saw_unknown_stty_arg = TRUE;
449
                        }
450
                }
451
                /* if any unknown args, let real stty try */
452
                if (saw_unknown_stty_arg || no_args) {
453
                        /* let real stty try */
454
                        rc = exec_stty(interp,argc,argv0,1);
455
 
456
                        /* find out what weird options user asked for */
457
                        if (exp_tty_get_simple(&tty_current) == -1) {
458
                                exp_error(interp,"stty: ioctl(get): %s\r\n",Tcl_PosixError(interp));
459
                                rc = TCL_ERROR;
460
                        }
461
                        if (cooked) {
462
                                /* find out user's new defn of 'cooked' */
463
                                tty_cooked = tty_current;
464
                        }
465
                } else if (saw_known_stty_arg) {
466
                        if (exp_tty_set_simple(&tty_current) == -1) {
467
                            if (exp_disconnected || (exp_dev_tty == -1) || !isatty(exp_dev_tty)) {
468
                                errorlog("stty: impossible in this context\n");
469
                                errorlog("are you disconnected or in a batch, at, or cron script?");
470
                                /* user could've conceivably closed /dev/tty as well */
471
                            }
472
                            exp_error(interp,"stty: ioctl(user): %s\r\n",Tcl_PosixError(interp));
473
                            rc = TCL_ERROR;
474
                        }
475
                }
476
 
477
                /* if no result, make a crude one */
478
                if (interp->result[0] == '\0') {
479
                        sprintf(interp->result,"%sraw %secho",
480
                                (was_raw?"":"-"),
481
                                (was_echo?"":"-"));
482
                }
483
        } else {
484
                /* a different tty */
485
 
486
                /* temporarily zap redirect */
487
                char *redirect_save = *redirect;
488
                *redirect = 0;
489
 
490
                for (argv=argv0+1;*argv;argv++) {
491
                        if (streq(*argv,"rows")) {
492
                                if (*(argv+1)) {
493
                                        exp_win2_rows_set(fd,*(argv+1));
494
                                        argv++;
495
                                        no_args = FALSE;
496
                                } else {
497
                                        exp_win2_rows_get(fd,interp->result);
498
                                        goto done;
499
                                }
500
                        } else if (streq(*argv,"columns")) {
501
                                if (*(argv+1)) {
502
                                        exp_win2_columns_set(fd,*(argv+1));
503
                                        argv++;
504
                                        no_args = FALSE;
505
                                } else {
506
                                        exp_win2_columns_get(fd,interp->result);
507
                                        goto done;
508
                                }
509
                        } else if (streq(*argv,"<")) {
510
                                break;
511
                        } else {
512
                                saw_unknown_stty_arg = TRUE;
513
                                break;
514
                        }
515
                }
516
 
517
                /* restore redirect */
518
                *redirect = redirect_save;
519
 
520
                close(fd);      /* no more use for this, from now on */
521
                                /* pass by name */
522
 
523
                if (saw_unknown_stty_arg || no_args) {
524
#ifdef STTY_READS_STDOUT
525
                        /* switch "<" to ">" */
526
                        char original_redirect_char = (*redirect)[0];
527
                        (*redirect)[0] = '>';
528
                        /* stderr unredirected so we can get it directly! */
529
#endif
530
                        rc = exec_stty(interp,argc,argv0,0);
531
#ifdef STTY_READS_STDOUT
532
                        /* restore redirect - don't know if necessary */
533
                        (*redirect)[0] = original_redirect_char;
534
#endif
535
                }
536
        }
537
 done:
538
        exp_trap_on(master);
539
 
540
        return rc;
541
}
542
 
543
/*ARGSUSED*/
544
static int
545
Exp_SystemCmd(clientData, interp, argc, argv)
546
ClientData clientData;
547
Tcl_Interp *interp;
548
int argc;
549
char **argv;
550
{
551
        int result = TCL_OK;
552
        RETSIGTYPE (*old)();    /* save old sigalarm handler */
553
#define MAX_ARGLIST 10240
554
        int i;
555
 
556
        WAIT_STATUS_TYPE waitStatus;
557
        int systemStatus
558
;
559
        int abnormalExit = FALSE;
560
        char buf[MAX_ARGLIST];
561
        char *bufp = buf;
562
        int total_len = 0, arg_len;
563
 
564
        int stty_args_recognized = TRUE;
565
        int cmd_is_stty = FALSE;
566
        int cooked = FALSE;
567
        int was_raw, was_echo;
568
 
569
        if (argc == 1) return TCL_OK;
570
 
571
        if (streq(argv[1],"stty")) {
572
                debuglog("system stty is deprecated, use stty\r\n");
573
 
574
                cmd_is_stty = TRUE;
575
                was_raw = exp_israw();
576
                was_echo = exp_isecho();
577
        }
578
 
579
        if (argc > 2 && cmd_is_stty) {
580
                exp_ioctled_devtty = TRUE;
581
 
582
                for (i=2;i<argc;i++) {
583
                        if (streq(argv[i],"raw") ||
584
                            streq(argv[i],"-cooked")) {
585
                                exp_tty_raw(1);
586
                        } else if (streq(argv[i],"-raw") ||
587
                                   streq(argv[i],"cooked")) {
588
                                cooked = TRUE;
589
                                exp_tty_raw(-1);
590
                        } else if (streq(argv[i],"echo")) {
591
                                exp_tty_echo(1);
592
                        } else if (streq(argv[i],"-echo")) {
593
                                exp_tty_echo(-1);
594
                        } else stty_args_recognized = FALSE;
595
                }
596
 
597
                /* if unknown args, fall thru and let real stty have a go */
598
                if (stty_args_recognized) {
599
#ifdef HAVE_TCSETATTR
600
                        if (tcsetattr(exp_dev_tty,TCSADRAIN, &tty_current) == -1) {
601
#else
602
                        if (ioctl(exp_dev_tty, TCSETSW, &tty_current) == -1) {
603
#endif
604
                            if (exp_disconnected || (exp_dev_tty == -1) || !isatty(exp_dev_tty)) {
605
                                errorlog("system stty: impossible in this context\n");
606
                                errorlog("are you disconnected or in a batch, at, or cron script?");
607
                                /* user could've conceivably closed /dev/tty as well */
608
                            }
609
                            exp_error(interp,"system stty: ioctl(user): %s\r\n",Tcl_PosixError(interp));
610
                            return(TCL_ERROR);
611
                        }
612
                        if (cmd_is_stty) {
613
                                sprintf(interp->result,"%sraw %secho",
614
                                        (was_raw?"":"-"),
615
                                        (was_echo?"":"-"));
616
                        }
617
                        return(TCL_OK);
618
                }
619
        }
620
 
621
        for (i = 1;i<argc;i++) {
622
                total_len += (1 + (arg_len = strlen(argv[i])));
623
                if (total_len > MAX_ARGLIST) {
624
                        exp_error(interp,"args too long (>=%d chars)",
625
                                total_len);
626
                        return(TCL_ERROR);
627
                }
628
                memcpy(bufp,argv[i],arg_len);
629
                bufp += arg_len;
630
                /* no need to check bounds, we accted for it earlier */
631
                memcpy(bufp," ",1);
632
                bufp += 1;
633
        }
634
 
635
        *(bufp-1) = '\0';
636
        old = signal(SIGCHLD, SIG_DFL);
637
        systemStatus = system(buf);
638
        signal(SIGCHLD, old);   /* restore signal handler */
639
        debuglog("system(%s) = %d\r\n",buf,i);
640
 
641
        if (systemStatus == -1) {
642
                exp_error(interp,Tcl_PosixError(interp));
643
                return TCL_ERROR;
644
        }
645
        *(int *)&waitStatus = systemStatus;
646
 
647
        if (!stty_args_recognized) {
648
                /* find out what weird options user asked for */
649
#ifdef HAVE_TCSETATTR
650
                if (tcgetattr(exp_dev_tty, &tty_current) == -1) {
651
#else
652
                if (ioctl(exp_dev_tty, TCGETS, &tty_current) == -1) {
653
#endif
654
                        errorlog("ioctl(get): %s\r\n",Tcl_PosixError(interp));
655
                        exp_exit(interp,1);
656
                }
657
                if (cooked) {
658
                        /* find out user's new defn of 'cooked' */
659
                        tty_cooked = tty_current;
660
                }
661
        }
662
 
663
        if (cmd_is_stty) {
664
                sprintf(interp->result,"%sraw %secho",
665
                        (was_raw?"":"-"),
666
                        (was_echo?"":"-"));
667
        }
668
 
669
/* following macros stolen from Tcl's tclUnix.h file */
670
/* we can't include the whole thing because it depends on other macros */
671
/* that come out of Tcl's Makefile, sigh */
672
 
673
#if 0
674
 
675
#undef WIFEXITED
676
#ifndef WIFEXITED
677
#   define WIFEXITED(stat)  (((*((int *) &(stat))) & 0xff) == 0)
678
#endif
679
 
680
#undef WEXITSTATUS
681
#ifndef WEXITSTATUS
682
#   define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff)
683
#endif
684
 
685
#undef WIFSIGNALED
686
#ifndef WIFSIGNALED
687
#   define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff)))
688
#endif
689
 
690
#undef WTERMSIG
691
#ifndef WTERMSIG
692
#   define WTERMSIG(stat)    ((*((int *) &(stat))) & 0x7f)
693
#endif
694
 
695
#undef WIFSTOPPED
696
#ifndef WIFSTOPPED
697
#   define WIFSTOPPED(stat)  (((*((int *) &(stat))) & 0xff) == 0177)
698
#endif
699
 
700
#undef WSTOPSIG
701
#ifndef WSTOPSIG
702
#   define WSTOPSIG(stat)    (((*((int *) &(stat))) >> 8) & 0xff)
703
#endif
704
 
705
#endif /* 0 */
706
 
707
/* stolen from Tcl.    Again, this is embedded in another routine */
708
/* (CleanupChildren in tclUnixAZ.c) that we can't use directly. */
709
 
710
        if (!WIFEXITED(waitStatus) || (WEXITSTATUS(waitStatus) != 0)) {
711
            char msg1[20], msg2[20];
712
            int pid = 0; /* fake a pid, since system() won't tell us */
713
 
714
            result = TCL_ERROR;
715
            sprintf(msg1, "%d", pid);
716
            if (WIFEXITED(waitStatus)) {
717
                sprintf(msg2, "%d", WEXITSTATUS(waitStatus));
718
                Tcl_SetErrorCode(interp, "CHILDSTATUS", msg1, msg2,
719
                        (char *) NULL);
720
                abnormalExit = TRUE;
721
            } else if (WIFSIGNALED(waitStatus)) {
722
                char *p;
723
 
724
                p = Tcl_SignalMsg((int) (WTERMSIG(waitStatus)));
725
                Tcl_SetErrorCode(interp, "CHILDKILLED", msg1,
726
                        Tcl_SignalId((int) (WTERMSIG(waitStatus))), p,
727
                        (char *) NULL);
728
                Tcl_AppendResult(interp, "child killed: ", p, "\n",
729
                        (char *) NULL);
730
            } else if (WIFSTOPPED(waitStatus)) {
731
                char *p;
732
 
733
                p = Tcl_SignalMsg((int) (WSTOPSIG(waitStatus)));
734
                Tcl_SetErrorCode(interp, "CHILDSUSP", msg1,
735
                        Tcl_SignalId((int) (WSTOPSIG(waitStatus))), p, (char *) NULL);
736
                Tcl_AppendResult(interp, "child suspended: ", p, "\n",
737
                        (char *) NULL);
738
            } else {
739
                Tcl_AppendResult(interp,
740
                        "child wait status didn't make sense\n",
741
                        (char *) NULL);
742
            }
743
        }
744
 
745
    if (abnormalExit && (*interp->result == 0)) {
746
        Tcl_AppendResult(interp, "child process exited abnormally",
747
                (char *) NULL);
748
    }
749
 
750
    return result;
751
}
752
 
753
static struct exp_cmd_data
754
cmd_data[]  = {
755
{"stty",        exp_proc(Exp_SttyCmd),  0,       0},
756
{"system",      exp_proc(Exp_SystemCmd),        0,       0},
757
{0}};
758
 
759
void
760
exp_init_tty_cmds(interp)
761
struct Tcl_Interp *interp;
762
{
763
        exp_create_commands(interp,cmd_data);
764
}

powered by: WebSVN 2.1.0

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