Fix warnings on FreeBSD
[oweals/cde.git] / cde / lib / DtTerm / TermPrim / TermPrimSetPty.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 #ifndef lint
24 #ifdef  VERBOSE_REV_INFO
25 static char rcs_id[] = "$TOG: TermPrimSetPty.c /main/2 1998/04/03 17:11:24 mgreess $";
26 #endif  /* VERBOSE_REV_INFO */
27 #endif  /* lint */
28
29 /*                                                                      *
30  * (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company               *
31  * (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
32  * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.                *
33  * (c) Copyright 1993, 1994, 1996 Novell, Inc.                          *
34  * (c) Copyright 1996 Digital Equipment Corporation.                    *
35  * (c) Copyright 1996 FUJITSU LIMITED.                                  *
36  * (c) Copyright 1996 Hitachi.                                          *
37  */
38
39 #include "TermHeader.h"
40 #include "TermPrimOSDepI.h"
41 #include "TermPrimDebug.h"
42 #include <fcntl.h>
43 #ifdef  ALPHA_ARCHITECTURE
44 #include <sys/ioctl.h>
45 #include <sys/ttydev.h>
46 #endif /* ALPHA_ARCHITECTURE */
47 #include <termios.h>
48 #ifdef  USE_PTYS
49 #ifdef  HP_ARCHITECTURE
50 #include <sys/ptyio.h>
51 #endif  /* HP_ARCHITECTURE */
52 #endif  /* USE_PTYS */
53 #if     defined(HP_ARCHITECTURE) && !(OSMAJORVERSION > 9)
54 #include <bsdtty.h>
55 #endif  /* defined(HP_ARCHITECTURE) && !(OSMAJORVERSION > 9) */
56
57 #if defined (USE_SETCSMAP)
58 #include <langinfo.h>
59 #include <sys/param.h>
60 #endif   /* (USE_SETCSMAP) */
61
62 #ifdef  USE_SRIOCSREDIR
63 #include <sys/strredir.h>
64 #include <sys/stat.h>
65 #endif  /* USE_SRIOCSREDIR */
66
67 #ifdef  USE_TIOCCONS
68 #ifdef  IBM_ARCHITECTURE
69 #include <sys/ioctl.h>
70 #endif  /* IBM_ARCHITECTURE */
71 #include <sys/stat.h>
72 #endif  /* USE_TIOCCONS */
73
74 #if defined(LINUX_ARCHITECTURE) || defined(OPENBSD_ARCHITECTURE)
75 #include <sys/ioctl.h>
76 #endif /* LINUX_ARCHITECTURE */
77
78 #ifdef  USE_STREAMS
79 #include <sys/types.h>
80 #include <stropts.h>
81 #include <sys/conf.h>
82 #endif  /* USE_STREAMS */
83
84 #if defined (USE_CSWIDTH)
85 #include <sys/ioctl.h>
86 #include <sys/eucioctl.h>
87 #endif   /* (USE_CSWIDTH) */
88
89 #include <sys/wait.h>
90 #include <ctype.h>
91 #include <errno.h>
92 #include <signal.h>
93 #include <Xm/Xm.h>
94
95 #define XTTYMODE_intr    0
96 #define XTTYMODE_quit    1
97 #define XTTYMODE_erase   2
98 #define XTTYMODE_kill    3
99 #define XTTYMODE_eof     4
100 #define XTTYMODE_eol     5
101 #define XTTYMODE_swtch   6
102 #define XTTYMODE_start   7
103 #define XTTYMODE_stop    8
104 #define XTTYMODE_brk     9
105 #define XTTYMODE_susp   10
106 #define XTTYMODE_dsusp  11
107 #define XTTYMODE_rprnt  12
108 #define XTTYMODE_flush  13
109 #define XTTYMODE_weras  14
110 #define XTTYMODE_lnext  15
111 #define NXTTYMODES      16
112
113 #if defined(CSRG_BASED)
114 #ifdef TAB3
115 #undef TAB3
116 #endif
117 #ifdef TABDLY
118 #undef TABDLY
119 #endif
120 #define TAB3    0x00000000
121 #define NLDLY   0x00000000
122 #define CRDLY   0x00000000
123 #define TABDLY  0x00000000
124 #define BSDLY   0x00000000
125 #define VTDLY   0x00000000
126 #define FFDLY   0x00000000
127 #define CBAUD   0x00000000
128 #endif
129 typedef struct _ttyMode
130 {
131     char    *name;
132     int      len;
133     int      set;
134     char     value;
135 }
136 ttyMode;
137
138 ttyMode _DtTermPrimTtyModeList[] = 
139 {
140     { "intr" , 4, 0, '\0' }, /* tchars.t_intrc ; VINTR   */
141     { "quit" , 4, 0, '\0' }, /* tchars.t_quitc ; VQUIT   */
142     { "erase", 5, 0, '\0' }, /* sgttyb.sg_erase ; VERASE */
143     { "kill" , 4, 0, '\0' }, /* sgttyb.sg_kill ; VKILL   */
144     { "eof"  , 3, 0, '\0' }, /* tchars.t_eofc ; VEOF     */
145     { "eol"  , 3, 0, '\0' }, /* VEOL                     */
146     { "swtch", 5, 0, '\0' }, /* VSWTCH                   */
147     { "start", 5, 0, '\0' }, /* tchars.t_startc          */
148     { "stop" , 4, 0, '\0' }, /* tchars.t_stopc           */
149     { "brk"  , 3, 0, '\0' }, /* tchars.t_brkc            */
150     { "susp" , 4, 0, '\0' }, /* ltchars.t_suspc          */
151     { "dsusp", 5, 0, '\0' }, /* ltchars.t_dsuspc         */
152     { "rprnt", 5, 0, '\0' }, /* ltchars.t_rprntc         */
153     { "flush", 5, 0, '\0' }, /* ltchars.t_flushc         */
154     { "weras", 5, 0, '\0' }, /* ltchars.t_werasc         */
155     { "lnext", 5, 0, '\0' }, /* ltchars.t_lnextc         */
156     {    NULL, 0, 0, '\0' }, /* NULL terminate the array */
157 };
158
159 static int
160 parseTtyModes
161 (
162     char    *modeString,
163     ttyMode *modeList
164 )
165 {
166     ttyMode    *pMode;
167     int         c;
168     int         modeCount = 0;
169
170     /*
171     ** Search to the end of the.
172     */
173
174     while (1) {
175         /*
176         ** Skip white space,  if this is the end of the list,
177         ** return.
178         */
179         while (*modeString && isascii(*modeString) && isspace(*modeString))
180         {
181              modeString++;
182         }
183
184         if (!*modeString) 
185         {
186             DebugF('p', 2, fprintf(stderr,
187                     ">>parseTtyModes() hit end of mode string, return=%d\n",
188                     modeCount));
189             return(modeCount);
190         }
191
192         /*
193         ** Otherwise, see if 'modeString' is in the list of mode names.
194         */
195         for (pMode = modeList; pMode->name; pMode++)
196         {
197             DebugF('p', 2, fprintf(stderr,
198                     ">>parseTtyModes() comparing %.*s to %s\n",
199                     pMode->len, modeString, pMode->name));
200             if (strncmp(modeString, pMode->name, pMode->len) == 0)
201             {
202                 DebugF('p', 2, fprintf(stderr, ">>parseTtyModes() match!\n"));
203                 break;
204             }
205         }
206         if (!pMode->name) 
207         {
208             DebugF('p', 2, fprintf(stderr, ">>parseTtyModes() no match\n"));
209             return(-1);
210         }
211
212         /*
213         ** Now look for a value for the setting.
214         ** (Skip white space, return an error if no value.)
215         */
216         modeString += pMode->len;
217         while (*modeString && isascii(*modeString) && isspace(*modeString))
218         {
219             modeString++;
220         }
221         if (!*modeString)
222         {
223             DebugF('p', 2, fprintf(stderr,
224                     ">>parseTtyModes() missing value\n"));
225             return(-1);
226         }
227         /*
228         ** Make sure we handle control characters correctly.
229         */
230         if (*modeString == '^')
231         {
232             modeString++;
233             /*
234             ** keep control bits
235             */
236             c = ((*modeString == '?') ? 0177 : *modeString & 31);
237         } 
238         else
239         {
240             c = *modeString;
241         }
242         /*
243         ** Set the values, and get go back for more.
244         */
245         pMode->value = c;
246         pMode->set   = 1;
247         modeCount++;
248         modeString++;
249     }
250     /* return(modeCount); */
251 }
252
253 #if defined (USE_CSWIDTH)
254 #define FIND_NUMBER(x, cp) \
255 { \
256     x = 0; \
257     while (*cp && isdigit(*cp)) \
258     { \
259         x *= 10; \
260         x += (*cp - '0'); \
261         cp++; \
262     } \
263 }
264
265 /*
266 ** parse the cswidth string
267 ** it should be in the form: X1[[:Y1][,X2[:Y2][,X3[:Y3]]]]
268 */
269 static void
270 parseCSWidth
271 (
272     char *cp,
273     eucioc_t *wp
274 )
275 {
276     int x;
277     int i;
278     
279     /*
280     ** set all cs widths to 0
281     */
282     wp->eucw[1] = wp->eucw[2] = wp->eucw[3] = 0;
283     wp->scrw[1] = wp->scrw[2] = wp->scrw[3] = 0;
284     if (!cp)
285     {
286         return;
287     }
288
289     DebugF('p', 4, fprintf(stderr,
290             ">>parseCSWidth(): csWidthString %s\n", cp));
291
292     for (i = 1; i <= 3; i++)
293     {
294         /*
295         ** read Xn
296         */
297         FIND_NUMBER(x, cp);
298         wp->eucw[i] = x;
299         if (!*cp)
300         {
301             wp->scrw[i] = wp->eucw[i];
302             return;
303         }
304
305         /*
306         ** Yn might exist
307         */
308         if (*cp == ':')
309         {
310             cp++;
311             FIND_NUMBER(x, cp);
312             wp->scrw[i] = x;
313             if (!*cp)
314             {
315                 return;
316             }
317         }
318         else
319         {
320             wp->scrw[i] = wp->eucw[i];
321         }
322         cp++;
323     }
324     DebugF('p', 4, fprintf(stderr,"parseCSWidth():"));
325     DebugF('p', 4, fprintf(stderr,
326             "    eucw[1] : %d, scrw[1] : %d\n", wp->eucw[1], wp->scrw[1]));
327     DebugF('p', 4, fprintf(stderr,
328             "    eucw[2] : %d, scrw[2] : %d\n", wp->eucw[2], wp->scrw[2]));
329     DebugF('p', 4, fprintf(stderr,
330             "    eucw[3] : %d, scrw[3] : %d\n", wp->eucw[3], wp->scrw[3]));
331 }
332 #endif   /* (USE_CSWIDTH) */
333
334 void _DtTermPrimPtySendBreak(int pty, int msec)
335 {
336 #if     defined(USE_TIOCBREAK)
337     (void) ioctl(pty, TIOCBREAK, 0);
338 #elif   defined(USE_TCSBRK)
339     (void) ioctl(pty, TCSBRK, 0);
340 #elif   defined(USE_TCSENDBREAK)
341     (void) tcsendbreak(pty, 0);
342 #else   /* none specified... */
343     There is no RS232 break code specified for this architecture.  See
344     TermPrimOSDepI.h for a list of #defines...
345 #endif  /* rs232 break definition... */
346 }
347
348 void _DtTermPrimPtySetWindowSize(int pty, short pixelWidth, short pixelHeight,
349         short characterRows, short characterColumns)
350 {
351     struct winsize ws;
352
353     ws.ws_row = characterRows;
354     ws.ws_col = characterColumns;
355     ws.ws_xpixel = pixelWidth;
356     ws.ws_ypixel = pixelHeight;
357     (void) ioctl(pty, TIOCSWINSZ, &ws);
358 }
359
360 static struct termios refTio;
361 static int refValid = 0;
362
363 #if defined (USE_CSWIDTH)
364 /*
365 ** default width settings for ldterm
366 */
367 static eucioc_t refWp;
368 #endif   /* (USE_CSWIDTH) */
369
370 void
371 _DtTermPrimPtyGetDefaultModes()
372 {
373     int tty = -1;
374     int refTty = -1;
375
376 #if defined (USE_CSWIDTH)
377     struct strioctl i_str;
378 #endif   /* (USE_CSWIDTH) */
379
380     _DtTermProcessLock();
381     if (!refValid) {
382         /* see if we can get a reference tty to get our base reference from...
383          */
384         if ((tty = open("/dev/tty", O_RDONLY, 0)) >= 0) {
385             if (!tcgetattr(tty, &refTio)) {
386                 /* we got a valid reference tty... */
387                 DebugF('p', 3, fprintf(stderr,
388                         ">>_DtTermPrimPtyGetDefaultModes() valid reference \"/dev/tty\"\n"));
389                 refValid = 1;
390             }
391         }
392
393         if (!refValid) {
394             for (refTty = 0; refTty < 3; refTty++) {
395                 if (!tcgetattr(refTty, &refTio)) {
396                     DebugF('p', 3, fprintf(stderr,
397                             ">>_DtTermPrimPtyGetDefaultModes() valid reference \fd %d\n", refTty));
398                     refValid = 1;
399                     break;
400                 }
401             }
402         }
403
404 #if defined (USE_CSWIDTH)
405         if (refValid && (MB_CUR_MAX > 1))
406         {
407             /*
408             ** we are in a wide character locale, get the current
409             ** width settings...
410             */
411             i_str.ic_cmd    = EUC_WGET;
412             i_str.ic_timout = 0;
413             i_str.ic_len    = sizeof(struct eucioc);
414             i_str.ic_dp     = (char *)&refWp;
415             (void)ioctl(refTty, I_STR, &i_str);
416         }
417 #endif   /* (USE_CSWIDTH) */
418
419         /* all done...
420          */
421         /* close off the "/dev/tty" fd... */
422         if (tty >= 0) {
423             (void) close(tty);
424         }
425     }
426     _DtTermProcessUnlock();
427 }
428
429 void
430 _DtTermPrimPtyInit
431 (
432     int   pty,
433     char *modeString,
434     char *csWidthString
435 )
436 {
437     struct termios tio;
438
439 #if defined (USE_CSWIDTH)
440     struct strioctl i_str;
441     eucioc_t        wp;
442 #endif   /* (USE_CSWIDTH) */
443
444 #if defined (USE_SETCSMAP)
445     /*
446     ** set thing up so we can use setcsmap()
447     ** for the time being, this is IBM specific
448     */
449     char path[MAXPATHLEN];
450     int  oldStdin = -1;
451 #endif   /* (USE_SETCSMAP) */
452
453 #ifdef  NOTDEF
454 #ifdef  USE_STREAMS
455     if (ioctl(pty, I_PUSH, "ptem") < 0) {
456         (void) perror("I_PUSH ptem");
457     }
458
459     if (ioctl(pty, I_PUSH, "ldterm") < 0) {
460         (void) perror("I_PUSH ldterm");
461     }
462
463     if (ioctl(pty, I_PUSH, "ttcompat") < 0) {
464         (void) perror("I_PUSH ttcompat");
465     }
466 #endif  /* USE_STREAMS */
467 #endif  /* NOTDEF */
468
469     if (refValid) {
470         /* we will start from the reference tty...
471          */
472         /* we already got the termios structure.  No need to get again... */
473         DebugF('p', 3, fprintf(stderr,
474                 ">>_DtTermPrimPtyInit() using refTio\n"));
475         tio = refTio;
476
477 #if defined (USE_CSWIDTH)
478         /*
479         ** use the cs width information from the reference...
480         */
481         wp  = refWp;
482 #endif   /* (USE_CSWIDTH) */
483         
484         /* DKS: are there any other terminal states we need to get?... */
485     } else {
486         /* let's set a reasonable default... */
487         DebugF('p', 3, fprintf(stderr,
488                 ">>_DtTermPrimPtyInit() generating default termio\n"));
489         (void) memset(&tio, '\0', sizeof(tio));
490
491         tio.c_iflag       = ICRNL | IXON   | IXOFF;
492         tio.c_oflag       = OPOST | ONLCR  | TAB3;
493         tio.c_cflag       = B9600 | CS8    | CREAD | PARENB | HUPCL;
494         tio.c_lflag       = ISIG|ICANON|ECHO|ECHOE|ECHOK|IEXTEN|ECHOCTL|ECHOKE;
495         /* DKS: this is termio specific.  Do we need it?...
496         tio.c_line        = 0;
497         */
498         tio.c_cc[VINTR]   = 0x7f;         /* DEL          */
499         tio.c_cc[VQUIT]   = '\\' & 0x3f;  /* '^\'         */
500         tio.c_cc[VERASE]  = '#';          /* '#'          */
501         tio.c_cc[VKILL]   = '@';          /* '@'          */
502         tio.c_cc[VEOF]    = 'D' & 0x3f;   /* '^D'         */
503         tio.c_cc[VEOL]    = '@' & 0x3f;   /* '^@'         */
504 #ifdef VSWITCH
505         tio.c_cc[VSWITCH] = '@' & 0x3f;   /* '^@'         */
506 #endif  /* VSWITCH */
507
508 #if defined (USE_CSWIDTH)
509         /*
510         ** get the cs width information from the resource
511         */
512         parseCSWidth(csWidthString, &wp);
513 #endif   /* (USE_CSWIDTH) */
514
515     }
516
517     /* now, let's clean up certain flags... */
518     /* input: nl->nl, don't ignore cr, cr->nl
519      *        turn on IXOFF pacing so that we can do paste without
520      *        overflowing the buffer...
521      */
522     tio.c_iflag &= ~(INLCR | IGNCR);
523     tio.c_iflag |=   ICRNL | IXOFF;
524
525     /* output: cr->cr, nl is not return, no delays, nl->cr/nl
526      */
527     tio.c_oflag &= ~(OCRNL | ONLRET | NLDLY | CRDLY | TABDLY |
528                      BSDLY | VTDLY  | FFDLY);
529     tio.c_oflag |=   ONLCR;
530
531     /* baud rate is 9600 (nice default), turn off clocal and turn on
532      * hupcl so that the last close will SIGHUP processes running on
533      * the tty...
534      */
535     tio.c_cflag &= ~(CBAUD | CLOCAL);
536     tio.c_cflag |= B9600 | HUPCL;
537
538     /* enable signals, canonical processing (erase, kill, etc), echo...
539      */
540     tio.c_lflag |= ISIG | ICANON | ECHO | IEXTEN | ECHOCTL | ECHOKE;
541
542     /* reset EOL to the default value (ksh mucks this up sometimes)...
543      */
544     tio.c_cc[VEOL] = '@' & 0x3f;                        /* '^@' */
545
546     /* reset EOF to the default value (ksh and csh muck with this)... */
547     tio.c_cc[VEOF] = 'D' & 0x3f;                        /* '^D' */
548
549     /* 
550     ** Now its time to handle the ttyModes
551     ** Decide if the user supplied a ttyModes resource, if so then
552     ** parse it and if it was a legal mode string, pass the parse result
553     */
554 #define TMODE(ind,var) if (_DtTermPrimTtyModeList[ind].set) var = _DtTermPrimTtyModeList[ind].value;
555
556     _DtTermProcessLock();
557     if (modeString)
558     {
559         if (parseTtyModes(modeString, _DtTermPrimTtyModeList) < 0)
560         {
561             /*
562             ** NOTE: should we prepend the program name to this string?
563             */
564             fprintf(stderr, "Bad tty modes \"%s\"\n", modeString);
565         }
566         else
567         {
568             TMODE (XTTYMODE_intr,  tio.c_cc[VINTR]);
569             TMODE (XTTYMODE_quit,  tio.c_cc[VQUIT]);
570             TMODE (XTTYMODE_erase, tio.c_cc[VERASE]);
571             TMODE (XTTYMODE_kill,  tio.c_cc[VKILL]);
572             TMODE (XTTYMODE_eof,   tio.c_cc[VEOF]);
573             TMODE (XTTYMODE_eol,   tio.c_cc[VEOL]);
574
575 #if     defined(HP_ARCHITECTURE)
576             TMODE (XTTYMODE_swtch, tio.c_cc[VSWTCH]);
577             TMODE (XTTYMODE_susp,  tio.c_cc[VSUSP]);
578 #if     OSMAJORVERSION > 9
579             /* HP-UX 10.0 supports the new, extended c_cc[] array...
580              */
581             TMODE (XTTYMODE_start, tio.c_cc[VSTART]);
582             TMODE (XTTYMODE_stop,  tio.c_cc[VSTOP]);
583             TMODE (XTTYMODE_dsusp, tio.c_cc[VDSUSP]);
584 #ifdef  NOTDEF
585             /* the following two parameters are not supported by
586              * HP-UX 10.0.
587              */
588             TMODE (XTTYMODE_rprnt, tio.c_cc[VREPRINT]);
589             TMODE (XTTYMODE_flush, tio.c_cc[VDISCARD]);
590 #endif  /* NOTDEF */
591             TMODE (XTTYMODE_weras, tio.c_cc[VWERASE]);
592             TMODE (XTTYMODE_lnext, tio.c_cc[VLNEXT]);
593 #else   /* OSMAJORVERSION > 9 */
594             {
595                 /* With HP-UX 9.0 (and earlier) we need to set dsuspc
596                  * via the ltchars array.  In addition, we have no support
597                  * for rprnt, flush, weras, and lnext...
598                  */
599                 struct ltchars ltc;
600
601                 if (!ioctl(pty, TIOCGLTC, &ltc)) {
602                     TMODE (XTTYMODE_dsusp, ltc.t_dsuspc);
603                     (void) ioctl(pty, TIOCSLTC, &ltc);
604                 }
605             }
606 #endif  /* OSMAJORVERSION > 9 */
607
608 #elif   defined(IBM_ARCHITECTURE)
609             TMODE (XTTYMODE_start, tio.c_cc[VSTRT]);
610             TMODE (XTTYMODE_stop,  tio.c_cc[VSTOP]);
611             TMODE (XTTYMODE_susp,  tio.c_cc[VSUSP]);
612             TMODE (XTTYMODE_dsusp, tio.c_cc[VDSUSP]);
613             TMODE (XTTYMODE_rprnt, tio.c_cc[VREPRINT]);
614             TMODE (XTTYMODE_flush, tio.c_cc[VDISCRD]);
615             TMODE (XTTYMODE_weras, tio.c_cc[VWERSE]);
616             TMODE (XTTYMODE_lnext, tio.c_cc[VLNEXT]);
617
618 #elif   defined(SUN_ARCHITECTURE)
619             TMODE (XTTYMODE_swtch, tio.c_cc[VSWTCH]);
620             TMODE (XTTYMODE_start, tio.c_cc[VSTART]);
621             TMODE (XTTYMODE_stop,  tio.c_cc[VSTOP]);
622             TMODE (XTTYMODE_susp,  tio.c_cc[VSUSP]);
623             TMODE (XTTYMODE_dsusp, tio.c_cc[VDSUSP]);
624             TMODE (XTTYMODE_rprnt, tio.c_cc[VREPRINT]);
625             TMODE (XTTYMODE_flush, tio.c_cc[VDISCARD]);
626             TMODE (XTTYMODE_weras, tio.c_cc[VWERASE]);
627             TMODE (XTTYMODE_lnext, tio.c_cc[VLNEXT]);
628
629 #elif   defined(ALPHA_ARCHITECTURE)
630             TMODE (XTTYMODE_start, tio.c_cc[VSTART]);
631             TMODE (XTTYMODE_stop,  tio.c_cc[VSTOP]);
632             TMODE (XTTYMODE_susp,  tio.c_cc[VSUSP]);
633             TMODE (XTTYMODE_dsusp, tio.c_cc[VDSUSP]);
634             TMODE (XTTYMODE_rprnt, tio.c_cc[VREPRINT]);
635             TMODE (XTTYMODE_flush, tio.c_cc[VDISCARD]);
636             TMODE (XTTYMODE_weras, tio.c_cc[VWERASE]);
637             TMODE (XTTYMODE_lnext, tio.c_cc[VLNEXT]);
638 #endif
639         }
640 #undef TMODE
641     }
642     _DtTermProcessUnlock();
643     
644     (void) tcsetattr(pty, TCSADRAIN, &tio);
645
646 #if defined (USE_CSWIDTH)
647     if (MB_CUR_MAX > 1)
648     {
649         /*
650         ** we are in a wide character locale, set the cs
651         ** width settings...
652         */
653         i_str.ic_cmd    = EUC_WSET;
654         i_str.ic_timout = 0;
655         i_str.ic_len    = sizeof(struct eucioc);
656         i_str.ic_dp     = (char *)&wp;
657         (void)ioctl(pty, I_STR, &i_str);
658     }
659 #endif   /* (USE_CSWIDTH) */
660
661 #if defined (USE_SETCSMAP)
662     /*
663     ** NOTE:
664     **     Setcsmap() only operates on STDIN, so we have to do some
665     **     munging around to map the pty to STDIN in order to get
666     **     the desired result.  This may seem wasteful, but it 
667     **     makes it easier to encapsulate the OS dependencies in
668     **     this function.
669     */
670     if (pty != 0)
671     {
672         oldStdin = fcntl(0, F_DUPFD, 1);
673         (void) close(0);
674         (void) dup(pty);
675     }
676
677     sprintf(path, "%s%s", CSMAP_DIR, nl_langinfo(CODESET));
678     if(access(path, E_ACC|R_ACC) == 0)
679     {
680         setcsmap(path);
681     }
682         
683     if (pty != 0)
684     {
685         (void) close(0);
686         if (oldStdin >= 0)
687         {
688             (void) dup(oldStdin);
689             (void) close(oldStdin);
690         }
691     }
692 #endif   /* (USE_SETCSMAP) */
693 }
694
695
696 #if     defined(USE_TIOCCONS)
697 #ifndef CONSOLE_DEVICE
698 #define CONSOLE_DEVICE  "/dev/console"
699 #endif  /* CONSOLE_DEVICE */
700 void _DtTermPrimPtyConsoleModeEnable(int pty)
701 {
702     struct stat           st;
703     int                   one = 1;
704
705     /* check to see if we are the owner of the device... */
706     if (!stat(CONSOLE_DEVICE, &st)) {
707         /* stat succeeded... */
708         if (st.st_uid == getuid()) {
709             /* we are the owner, check the access... */
710             if (!access(CONSOLE_DEVICE, R_OK | W_OK)) {
711                 /* and we can read/write it... */
712                 /* we need to be setuid root... */
713                 (void) _DtTermPrimToggleSuidRoot(True);
714
715                 if (ioctl(pty, TIOCCONS, &one)) {
716                     /* failure, errno was set... */
717                     (void) perror(CONSOLE_DEVICE);
718                     (void) fprintf(stderr,
719                             "attempt to make tty the console failed\n");
720                 }
721                 /* we no longer need to be suid root... */
722                 (void) _DtTermPrimToggleSuidRoot(False);
723             } else {
724                 /* we can't read/write it... */
725                 (void) perror(CONSOLE_DEVICE);
726                 (void) fprintf(stderr, "-C console access denied\n");
727             }
728         } else {
729             /* we are not the owner -- return an access owner... */
730             errno = EACCES;
731             (void) perror(CONSOLE_DEVICE);
732             (void) fprintf(stderr, "-C console access denied\n");
733         }
734     } else {
735         /* we were unable to stat the file, errno is already set,
736          * failure...
737          */
738         (void) perror(CONSOLE_DEVICE);
739         (void) fprintf(stderr, "-C console access denied\n");
740     }
741 }
742
743
744 #elif   defined(USE_SRIOCSREDIR)
745 #ifndef CONSOLE_DEVICE
746 #define CONSOLE_DEVICE  "/dev/console"
747 #endif  /* CONSOLE_DEVICE */
748 void _DtTermPrimPtyConsoleModeEnable(int pty)
749 {
750     struct stat           st;
751     int                   consoleFd;
752
753     /* check to see if we are the owner of the device... */
754     if (!stat(CONSOLE_DEVICE, &st)) {
755         /* stat succeeded... */
756         if (st.st_uid == getuid()) {
757             /* we are the owner, open the file... */
758             if ((consoleFd = open("/dev/console", O_RDWR | O_NOCTTY)) >= 0) {
759                 if (ioctl(consoleFd, SRIOCSREDIR, pty) == -1) {
760                 (void) perror(CONSOLE_DEVICE);
761                     (void) fprintf(stderr,
762                             "attempt to make tty the console failed\n");
763                 }
764                 (void) close(consoleFd);
765             } else {
766                 /* we can't open it for reading and writing... */
767                 (void) perror(CONSOLE_DEVICE);
768                 (void) fprintf(stderr, "-C console access denied\n");
769             }
770         } else {
771             /* we are not the owner -- return an access owner... */
772             errno = EACCES;
773             (void) perror(CONSOLE_DEVICE);
774             (void) fprintf(stderr, "-C console access denied\n");
775         }
776     } else {
777         /* we were unable to stat the file, errno is already set,
778          * failure...
779          */
780         (void) perror(CONSOLE_DEVICE);
781         (void) fprintf(stderr, "-C console access denied\n");
782     }
783 }
784
785
786 #else
787 void _DtTermPrimPtyConsoleModeEnable(int pty)
788 {
789     (void) fprintf(stderr,
790             "-C console access not supported on this architecture\n");
791 }
792 #endif