~mysql/mysql-server/mysql-6.0

« back to all changes in this revision

Viewing changes to cmd-line-utils/libedit/tty.c

  • Committer: vva at r18
  • Date: 2003-01-18 16:28:48 UTC
  • mto: (1403.60.3)
  • mto: This revision was merged to the branch mainline in revision 1412.
  • Revision ID: sp1r-vva@eagle.mysql.r18.ru-20030118162848-51479
changes for readline/libedit configuration

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*      $NetBSD: tty.c,v 1.15 2001/05/17 01:02:17 christos Exp $        */
 
2
 
 
3
/*-
 
4
 * Copyright (c) 1992, 1993
 
5
 *      The Regents of the University of California.  All rights reserved.
 
6
 *
 
7
 * This code is derived from software contributed to Berkeley by
 
8
 * Christos Zoulas of Cornell University.
 
9
 *
 
10
 * Redistribution and use in source and binary forms, with or without
 
11
 * modification, are permitted provided that the following conditions
 
12
 * are met:
 
13
 * 1. Redistributions of source code must retain the above copyright
 
14
 *    notice, this list of conditions and the following disclaimer.
 
15
 * 2. Redistributions in binary form must reproduce the above copyright
 
16
 *    notice, this list of conditions and the following disclaimer in the
 
17
 *    documentation and/or other materials provided with the distribution.
 
18
 * 3. All advertising materials mentioning features or use of this software
 
19
 *    must display the following acknowledgement:
 
20
 *      This product includes software developed by the University of
 
21
 *      California, Berkeley and its contributors.
 
22
 * 4. Neither the name of the University nor the names of its contributors
 
23
 *    may be used to endorse or promote products derived from this software
 
24
 *    without specific prior written permission.
 
25
 *
 
26
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 
27
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
28
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
29
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 
30
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
31
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
32
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
33
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
34
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
35
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
36
 * SUCH DAMAGE.
 
37
 */
 
38
 
 
39
#include "compat.h"
 
40
#if !defined(lint) && !defined(SCCSID)
 
41
#if 0
 
42
static char sccsid[] = "@(#)tty.c       8.1 (Berkeley) 6/4/93";
 
43
#else
 
44
__RCSID("$NetBSD: tty.c,v 1.15 2001/05/17 01:02:17 christos Exp $");
 
45
#endif
 
46
#endif /* not lint && not SCCSID */
 
47
 
 
48
/*
 
49
 * tty.c: tty interface stuff
 
50
 */
 
51
#include "sys.h"
 
52
#include "tty.h"
 
53
#include "el.h"
 
54
 
 
55
typedef struct ttymodes_t {
 
56
        const char *m_name;
 
57
        u_int m_value;
 
58
        int m_type;
 
59
}          ttymodes_t;
 
60
 
 
61
typedef struct ttymap_t {
 
62
        int nch, och;           /* Internal and termio rep of chars */
 
63
        el_action_t bind[3];    /* emacs, vi, and vi-cmd */
 
64
}        ttymap_t;
 
65
 
 
66
 
 
67
private const ttyperm_t ttyperm = {
 
68
        {
 
69
                {"iflag:", ICRNL, (INLCR | IGNCR)},
 
70
                {"oflag:", (OPOST | ONLCR), ONLRET},
 
71
                {"cflag:", 0, 0},
 
72
                {"lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN),
 
73
                (NOFLSH | ECHONL | EXTPROC | FLUSHO)},
 
74
                {"chars:", 0, 0},
 
75
        },
 
76
        {
 
77
                {"iflag:", (INLCR | ICRNL), IGNCR},
 
78
                {"oflag:", (OPOST | ONLCR), ONLRET},
 
79
                {"cflag:", 0, 0},
 
80
                {"lflag:", ISIG,
 
81
                (NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO)},
 
82
                {"chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) |
 
83
                            C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) |
 
84
                    C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0}
 
85
        },
 
86
        {
 
87
                {"iflag:", 0, IXON | IXOFF | INLCR | ICRNL},
 
88
                {"oflag:", 0, 0},
 
89
                {"cflag:", 0, 0},
 
90
                {"lflag:", 0, ISIG | IEXTEN},
 
91
                {"chars:", 0, 0},
 
92
        }
 
93
};
 
94
 
 
95
private const ttychar_t ttychar = {
 
96
        {
 
97
                CINTR, CQUIT, CERASE, CKILL,
 
98
                CEOF, CEOL, CEOL2, CSWTCH,
 
99
                CDSWTCH, CERASE2, CSTART, CSTOP,
 
100
                CWERASE, CSUSP, CDSUSP, CREPRINT,
 
101
                CDISCARD, CLNEXT, CSTATUS, CPAGE,
 
102
                CPGOFF, CKILL2, CBRK, CMIN,
 
103
                CTIME
 
104
        },
 
105
        {
 
106
                CINTR, CQUIT, CERASE, CKILL,
 
107
                _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
 
108
                _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
 
109
                _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
 
110
                CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
 
111
                _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
 
112
                0
 
113
        },
 
114
        {
 
115
                0, 0, 0, 0,
 
116
                0, 0, 0, 0,
 
117
                0, 0, 0, 0,
 
118
                0, 0, 0, 0,
 
119
                0, 0, 0, 0,
 
120
                0, 0, 0, 0,
 
121
                0
 
122
        }
 
123
};
 
124
 
 
125
private const ttymap_t tty_map[] = {
 
126
#ifdef VERASE
 
127
        {C_ERASE, VERASE,
 
128
        {ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
 
129
#endif /* VERASE */
 
130
#ifdef VERASE2
 
131
        {C_ERASE2, VERASE2,
 
132
        {ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
 
133
#endif /* VERASE2 */
 
134
#ifdef VKILL
 
135
        {C_KILL, VKILL,
 
136
        {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
 
137
#endif /* VKILL */
 
138
#ifdef VKILL2
 
139
        {C_KILL2, VKILL2,
 
140
        {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
 
141
#endif /* VKILL2 */
 
142
#ifdef VEOF
 
143
        {C_EOF, VEOF,
 
144
        {EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED}},
 
145
#endif /* VEOF */
 
146
#ifdef VWERASE
 
147
        {C_WERASE, VWERASE,
 
148
        {ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD}},
 
149
#endif /* VWERASE */
 
150
#ifdef VREPRINT
 
151
        {C_REPRINT, VREPRINT,
 
152
        {ED_REDISPLAY, ED_INSERT, ED_REDISPLAY}},
 
153
#endif /* VREPRINT */
 
154
#ifdef VLNEXT
 
155
        {C_LNEXT, VLNEXT,
 
156
        {ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}},
 
157
#endif /* VLNEXT */
 
158
        {-1, -1,
 
159
        {ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}}
 
160
};
 
161
 
 
162
private const ttymodes_t ttymodes[] = {
 
163
#ifdef  IGNBRK
 
164
        {"ignbrk", IGNBRK, MD_INP},
 
165
#endif /* IGNBRK */
 
166
#ifdef  BRKINT
 
167
        {"brkint", BRKINT, MD_INP},
 
168
#endif /* BRKINT */
 
169
#ifdef  IGNPAR
 
170
        {"ignpar", IGNPAR, MD_INP},
 
171
#endif /* IGNPAR */
 
172
#ifdef  PARMRK
 
173
        {"parmrk", PARMRK, MD_INP},
 
174
#endif /* PARMRK */
 
175
#ifdef  INPCK
 
176
        {"inpck", INPCK, MD_INP},
 
177
#endif /* INPCK */
 
178
#ifdef  ISTRIP
 
179
        {"istrip", ISTRIP, MD_INP},
 
180
#endif /* ISTRIP */
 
181
#ifdef  INLCR
 
182
        {"inlcr", INLCR, MD_INP},
 
183
#endif /* INLCR */
 
184
#ifdef  IGNCR
 
185
        {"igncr", IGNCR, MD_INP},
 
186
#endif /* IGNCR */
 
187
#ifdef  ICRNL
 
188
        {"icrnl", ICRNL, MD_INP},
 
189
#endif /* ICRNL */
 
190
#ifdef  IUCLC
 
191
        {"iuclc", IUCLC, MD_INP},
 
192
#endif /* IUCLC */
 
193
#ifdef  IXON
 
194
        {"ixon", IXON, MD_INP},
 
195
#endif /* IXON */
 
196
#ifdef  IXANY
 
197
        {"ixany", IXANY, MD_INP},
 
198
#endif /* IXANY */
 
199
#ifdef  IXOFF
 
200
        {"ixoff", IXOFF, MD_INP},
 
201
#endif /* IXOFF */
 
202
#ifdef  IMAXBEL
 
203
        {"imaxbel", IMAXBEL, MD_INP},
 
204
#endif /* IMAXBEL */
 
205
 
 
206
#ifdef  OPOST
 
207
        {"opost", OPOST, MD_OUT},
 
208
#endif /* OPOST */
 
209
#ifdef  OLCUC
 
210
        {"olcuc", OLCUC, MD_OUT},
 
211
#endif /* OLCUC */
 
212
#ifdef  ONLCR
 
213
        {"onlcr", ONLCR, MD_OUT},
 
214
#endif /* ONLCR */
 
215
#ifdef  OCRNL
 
216
        {"ocrnl", OCRNL, MD_OUT},
 
217
#endif /* OCRNL */
 
218
#ifdef  ONOCR
 
219
        {"onocr", ONOCR, MD_OUT},
 
220
#endif /* ONOCR */
 
221
#ifdef ONOEOT
 
222
        {"onoeot", ONOEOT, MD_OUT},
 
223
#endif /* ONOEOT */
 
224
#ifdef  ONLRET
 
225
        {"onlret", ONLRET, MD_OUT},
 
226
#endif /* ONLRET */
 
227
#ifdef  OFILL
 
228
        {"ofill", OFILL, MD_OUT},
 
229
#endif /* OFILL */
 
230
#ifdef  OFDEL
 
231
        {"ofdel", OFDEL, MD_OUT},
 
232
#endif /* OFDEL */
 
233
#ifdef  NLDLY
 
234
        {"nldly", NLDLY, MD_OUT},
 
235
#endif /* NLDLY */
 
236
#ifdef  CRDLY
 
237
        {"crdly", CRDLY, MD_OUT},
 
238
#endif /* CRDLY */
 
239
#ifdef  TABDLY
 
240
        {"tabdly", TABDLY, MD_OUT},
 
241
#endif /* TABDLY */
 
242
#ifdef  XTABS
 
243
        {"xtabs", XTABS, MD_OUT},
 
244
#endif /* XTABS */
 
245
#ifdef  BSDLY
 
246
        {"bsdly", BSDLY, MD_OUT},
 
247
#endif /* BSDLY */
 
248
#ifdef  VTDLY
 
249
        {"vtdly", VTDLY, MD_OUT},
 
250
#endif /* VTDLY */
 
251
#ifdef  FFDLY
 
252
        {"ffdly", FFDLY, MD_OUT},
 
253
#endif /* FFDLY */
 
254
#ifdef  PAGEOUT
 
255
        {"pageout", PAGEOUT, MD_OUT},
 
256
#endif /* PAGEOUT */
 
257
#ifdef  WRAP
 
258
        {"wrap", WRAP, MD_OUT},
 
259
#endif /* WRAP */
 
260
 
 
261
#ifdef  CIGNORE
 
262
        {"cignore", CIGNORE, MD_CTL},
 
263
#endif /* CBAUD */
 
264
#ifdef  CBAUD
 
265
        {"cbaud", CBAUD, MD_CTL},
 
266
#endif /* CBAUD */
 
267
#ifdef  CSTOPB
 
268
        {"cstopb", CSTOPB, MD_CTL},
 
269
#endif /* CSTOPB */
 
270
#ifdef  CREAD
 
271
        {"cread", CREAD, MD_CTL},
 
272
#endif /* CREAD */
 
273
#ifdef  PARENB
 
274
        {"parenb", PARENB, MD_CTL},
 
275
#endif /* PARENB */
 
276
#ifdef  PARODD
 
277
        {"parodd", PARODD, MD_CTL},
 
278
#endif /* PARODD */
 
279
#ifdef  HUPCL
 
280
        {"hupcl", HUPCL, MD_CTL},
 
281
#endif /* HUPCL */
 
282
#ifdef  CLOCAL
 
283
        {"clocal", CLOCAL, MD_CTL},
 
284
#endif /* CLOCAL */
 
285
#ifdef  LOBLK
 
286
        {"loblk", LOBLK, MD_CTL},
 
287
#endif /* LOBLK */
 
288
#ifdef  CIBAUD
 
289
        {"cibaud", CIBAUD, MD_CTL},
 
290
#endif /* CIBAUD */
 
291
#ifdef CRTSCTS
 
292
#ifdef CCTS_OFLOW
 
293
        {"ccts_oflow", CCTS_OFLOW, MD_CTL},
 
294
#else
 
295
        {"crtscts", CRTSCTS, MD_CTL},
 
296
#endif /* CCTS_OFLOW */
 
297
#endif /* CRTSCTS */
 
298
#ifdef CRTS_IFLOW
 
299
        {"crts_iflow", CRTS_IFLOW, MD_CTL},
 
300
#endif /* CRTS_IFLOW */
 
301
#ifdef CDTRCTS
 
302
        {"cdtrcts", CDTRCTS, MD_CTL},
 
303
#endif /* CDTRCTS */
 
304
#ifdef MDMBUF
 
305
        {"mdmbuf", MDMBUF, MD_CTL},
 
306
#endif /* MDMBUF */
 
307
#ifdef RCV1EN
 
308
        {"rcv1en", RCV1EN, MD_CTL},
 
309
#endif /* RCV1EN */
 
310
#ifdef XMT1EN
 
311
        {"xmt1en", XMT1EN, MD_CTL},
 
312
#endif /* XMT1EN */
 
313
 
 
314
#ifdef  ISIG
 
315
        {"isig", ISIG, MD_LIN},
 
316
#endif /* ISIG */
 
317
#ifdef  ICANON
 
318
        {"icanon", ICANON, MD_LIN},
 
319
#endif /* ICANON */
 
320
#ifdef  XCASE
 
321
        {"xcase", XCASE, MD_LIN},
 
322
#endif /* XCASE */
 
323
#ifdef  ECHO
 
324
        {"echo", ECHO, MD_LIN},
 
325
#endif /* ECHO */
 
326
#ifdef  ECHOE
 
327
        {"echoe", ECHOE, MD_LIN},
 
328
#endif /* ECHOE */
 
329
#ifdef  ECHOK
 
330
        {"echok", ECHOK, MD_LIN},
 
331
#endif /* ECHOK */
 
332
#ifdef  ECHONL
 
333
        {"echonl", ECHONL, MD_LIN},
 
334
#endif /* ECHONL */
 
335
#ifdef  NOFLSH
 
336
        {"noflsh", NOFLSH, MD_LIN},
 
337
#endif /* NOFLSH */
 
338
#ifdef  TOSTOP
 
339
        {"tostop", TOSTOP, MD_LIN},
 
340
#endif /* TOSTOP */
 
341
#ifdef  ECHOCTL
 
342
        {"echoctl", ECHOCTL, MD_LIN},
 
343
#endif /* ECHOCTL */
 
344
#ifdef  ECHOPRT
 
345
        {"echoprt", ECHOPRT, MD_LIN},
 
346
#endif /* ECHOPRT */
 
347
#ifdef  ECHOKE
 
348
        {"echoke", ECHOKE, MD_LIN},
 
349
#endif /* ECHOKE */
 
350
#ifdef  DEFECHO
 
351
        {"defecho", DEFECHO, MD_LIN},
 
352
#endif /* DEFECHO */
 
353
#ifdef  FLUSHO
 
354
        {"flusho", FLUSHO, MD_LIN},
 
355
#endif /* FLUSHO */
 
356
#ifdef  PENDIN
 
357
        {"pendin", PENDIN, MD_LIN},
 
358
#endif /* PENDIN */
 
359
#ifdef  IEXTEN
 
360
        {"iexten", IEXTEN, MD_LIN},
 
361
#endif /* IEXTEN */
 
362
#ifdef  NOKERNINFO
 
363
        {"nokerninfo", NOKERNINFO, MD_LIN},
 
364
#endif /* NOKERNINFO */
 
365
#ifdef  ALTWERASE
 
366
        {"altwerase", ALTWERASE, MD_LIN},
 
367
#endif /* ALTWERASE */
 
368
#ifdef  EXTPROC
 
369
        {"extproc", EXTPROC, MD_LIN},
 
370
#endif /* EXTPROC */
 
371
 
 
372
#if defined(VINTR)
 
373
        {"intr", C_SH(C_INTR), MD_CHAR},
 
374
#endif /* VINTR */
 
375
#if defined(VQUIT)
 
376
        {"quit", C_SH(C_QUIT), MD_CHAR},
 
377
#endif /* VQUIT */
 
378
#if defined(VERASE)
 
379
        {"erase", C_SH(C_ERASE), MD_CHAR},
 
380
#endif /* VERASE */
 
381
#if defined(VKILL)
 
382
        {"kill", C_SH(C_KILL), MD_CHAR},
 
383
#endif /* VKILL */
 
384
#if defined(VEOF)
 
385
        {"eof", C_SH(C_EOF), MD_CHAR},
 
386
#endif /* VEOF */
 
387
#if defined(VEOL)
 
388
        {"eol", C_SH(C_EOL), MD_CHAR},
 
389
#endif /* VEOL */
 
390
#if defined(VEOL2)
 
391
        {"eol2", C_SH(C_EOL2), MD_CHAR},
 
392
#endif /* VEOL2 */
 
393
#if defined(VSWTCH)
 
394
        {"swtch", C_SH(C_SWTCH), MD_CHAR},
 
395
#endif /* VSWTCH */
 
396
#if defined(VDSWTCH)
 
397
        {"dswtch", C_SH(C_DSWTCH), MD_CHAR},
 
398
#endif /* VDSWTCH */
 
399
#if defined(VERASE2)
 
400
        {"erase2", C_SH(C_ERASE2), MD_CHAR},
 
401
#endif /* VERASE2 */
 
402
#if defined(VSTART)
 
403
        {"start", C_SH(C_START), MD_CHAR},
 
404
#endif /* VSTART */
 
405
#if defined(VSTOP)
 
406
        {"stop", C_SH(C_STOP), MD_CHAR},
 
407
#endif /* VSTOP */
 
408
#if defined(VWERASE)
 
409
        {"werase", C_SH(C_WERASE), MD_CHAR},
 
410
#endif /* VWERASE */
 
411
#if defined(VSUSP)
 
412
        {"susp", C_SH(C_SUSP), MD_CHAR},
 
413
#endif /* VSUSP */
 
414
#if defined(VDSUSP)
 
415
        {"dsusp", C_SH(C_DSUSP), MD_CHAR},
 
416
#endif /* VDSUSP */
 
417
#if defined(VREPRINT)
 
418
        {"reprint", C_SH(C_REPRINT), MD_CHAR},
 
419
#endif /* VREPRINT */
 
420
#if defined(VDISCARD)
 
421
        {"discard", C_SH(C_DISCARD), MD_CHAR},
 
422
#endif /* VDISCARD */
 
423
#if defined(VLNEXT)
 
424
        {"lnext", C_SH(C_LNEXT), MD_CHAR},
 
425
#endif /* VLNEXT */
 
426
#if defined(VSTATUS)
 
427
        {"status", C_SH(C_STATUS), MD_CHAR},
 
428
#endif /* VSTATUS */
 
429
#if defined(VPAGE)
 
430
        {"page", C_SH(C_PAGE), MD_CHAR},
 
431
#endif /* VPAGE */
 
432
#if defined(VPGOFF)
 
433
        {"pgoff", C_SH(C_PGOFF), MD_CHAR},
 
434
#endif /* VPGOFF */
 
435
#if defined(VKILL2)
 
436
        {"kill2", C_SH(C_KILL2), MD_CHAR},
 
437
#endif /* VKILL2 */
 
438
#if defined(VBRK)
 
439
        {"brk", C_SH(C_BRK), MD_CHAR},
 
440
#endif /* VBRK */
 
441
#if defined(VMIN)
 
442
        {"min", C_SH(C_MIN), MD_CHAR},
 
443
#endif /* VMIN */
 
444
#if defined(VTIME)
 
445
        {"time", C_SH(C_TIME), MD_CHAR},
 
446
#endif /* VTIME */
 
447
        {NULL, 0, -1},
 
448
};
 
449
 
 
450
 
 
451
 
 
452
#define tty_getty(el, td)       tcgetattr((el)->el_infd, (td))
 
453
#define tty_setty(el, td)       tcsetattr((el)->el_infd, TCSADRAIN, (td))
 
454
 
 
455
#define tty__gettabs(td)        ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
 
456
#define tty__geteightbit(td)    (((td)->c_cflag & CSIZE) == CS8)
 
457
#define tty__cooked_mode(td)    ((td)->c_lflag & ICANON)
 
458
 
 
459
private void    tty__getchar(struct termios *, unsigned char *);
 
460
private void    tty__setchar(struct termios *, unsigned char *);
 
461
private speed_t tty__getspeed(struct termios *);
 
462
private int     tty_setup(EditLine *);
 
463
 
 
464
#define t_qu    t_ts
 
465
 
 
466
 
 
467
/* tty_setup():
 
468
 *      Get the tty parameters and initialize the editing state
 
469
 */
 
470
private int
 
471
tty_setup(EditLine *el)
 
472
{
 
473
        int rst = 1;
 
474
 
 
475
        if (el->el_flags & EDIT_DISABLED)
 
476
                return (0);
 
477
 
 
478
        if (tty_getty(el, &el->el_tty.t_ed) == -1) {
 
479
#ifdef DEBUG_TTY
 
480
                (void) fprintf(el->el_errfile,
 
481
                    "tty_setup: tty_getty: %s\n", strerror(errno));
 
482
#endif /* DEBUG_TTY */
 
483
                return (-1);
 
484
        }
 
485
        el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
 
486
 
 
487
        el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
 
488
        el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
 
489
        el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
 
490
 
 
491
        el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
 
492
        el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
 
493
 
 
494
        el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
 
495
        el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
 
496
 
 
497
        el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
 
498
        el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
 
499
 
 
500
        el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
 
501
        el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
 
502
 
 
503
        /*
 
504
         * Reset the tty chars to reasonable defaults
 
505
         * If they are disabled, then enable them.
 
506
         */
 
507
        if (rst) {
 
508
                if (tty__cooked_mode(&el->el_tty.t_ts)) {
 
509
                        tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
 
510
                        /*
 
511
                         * Don't affect CMIN and CTIME for the editor mode
 
512
                         */
 
513
                        for (rst = 0; rst < C_NCC - 2; rst++)
 
514
                                if (el->el_tty.t_c[TS_IO][rst] !=
 
515
                                      el->el_tty.t_vdisable
 
516
                                    && el->el_tty.t_c[ED_IO][rst] !=
 
517
                                      el->el_tty.t_vdisable)
 
518
                                        el->el_tty.t_c[ED_IO][rst] =
 
519
                                            el->el_tty.t_c[TS_IO][rst];
 
520
                        for (rst = 0; rst < C_NCC; rst++)
 
521
                                if (el->el_tty.t_c[TS_IO][rst] !=
 
522
                                    el->el_tty.t_vdisable)
 
523
                                        el->el_tty.t_c[EX_IO][rst] =
 
524
                                            el->el_tty.t_c[TS_IO][rst];
 
525
                }
 
526
                tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
 
527
                if (tty_setty(el, &el->el_tty.t_ex) == -1) {
 
528
#ifdef DEBUG_TTY
 
529
                        (void) fprintf(el->el_errfile,
 
530
                            "tty_setup: tty_setty: %s\n",
 
531
                            strerror(errno));
 
532
#endif /* DEBUG_TTY */
 
533
                        return (-1);
 
534
                }
 
535
        } else
 
536
                tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
 
537
 
 
538
        el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
 
539
        el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
 
540
 
 
541
        el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
 
542
        el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
 
543
 
 
544
        el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
 
545
        el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
 
546
 
 
547
        el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
 
548
        el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
 
549
 
 
550
        tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
 
551
        tty_bind_char(el, 1);
 
552
        return (0);
 
553
}
 
554
 
 
555
protected int
 
556
tty_init(EditLine *el)
 
557
{
 
558
 
 
559
        el->el_tty.t_mode = EX_IO;
 
560
        el->el_tty.t_vdisable = _POSIX_VDISABLE;
 
561
        (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
 
562
        (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
 
563
        return (tty_setup(el));
 
564
}
 
565
 
 
566
 
 
567
/* tty_end():
 
568
 *      Restore the tty to its original settings
 
569
 */
 
570
protected void
 
571
/*ARGSUSED*/
 
572
tty_end(EditLine *el __attribute__((unused)))
 
573
{
 
574
 
 
575
        /* XXX: Maybe reset to an initial state? */
 
576
}
 
577
 
 
578
 
 
579
/* tty__getspeed():
 
580
 *      Get the tty speed
 
581
 */
 
582
private speed_t
 
583
tty__getspeed(struct termios *td)
 
584
{
 
585
        speed_t spd;
 
586
 
 
587
        if ((spd = cfgetispeed(td)) == 0)
 
588
                spd = cfgetospeed(td);
 
589
        return (spd);
 
590
}
 
591
 
 
592
 
 
593
/* tty__getchar():
 
594
 *      Get the tty characters
 
595
 */
 
596
private void
 
597
tty__getchar(struct termios *td, unsigned char *s)
 
598
{
 
599
 
 
600
#ifdef VINTR
 
601
        s[C_INTR] = td->c_cc[VINTR];
 
602
#endif /* VINTR */
 
603
#ifdef VQUIT
 
604
        s[C_QUIT] = td->c_cc[VQUIT];
 
605
#endif /* VQUIT */
 
606
#ifdef VERASE
 
607
        s[C_ERASE] = td->c_cc[VERASE];
 
608
#endif /* VERASE */
 
609
#ifdef VKILL
 
610
        s[C_KILL] = td->c_cc[VKILL];
 
611
#endif /* VKILL */
 
612
#ifdef VEOF
 
613
        s[C_EOF] = td->c_cc[VEOF];
 
614
#endif /* VEOF */
 
615
#ifdef VEOL
 
616
        s[C_EOL] = td->c_cc[VEOL];
 
617
#endif /* VEOL */
 
618
#ifdef VEOL2
 
619
        s[C_EOL2] = td->c_cc[VEOL2];
 
620
#endif /* VEOL2 */
 
621
#ifdef VSWTCH
 
622
        s[C_SWTCH] = td->c_cc[VSWTCH];
 
623
#endif /* VSWTCH */
 
624
#ifdef VDSWTCH
 
625
        s[C_DSWTCH] = td->c_cc[VDSWTCH];
 
626
#endif /* VDSWTCH */
 
627
#ifdef VERASE2
 
628
        s[C_ERASE2] = td->c_cc[VERASE2];
 
629
#endif /* VERASE2 */
 
630
#ifdef VSTART
 
631
        s[C_START] = td->c_cc[VSTART];
 
632
#endif /* VSTART */
 
633
#ifdef VSTOP
 
634
        s[C_STOP] = td->c_cc[VSTOP];
 
635
#endif /* VSTOP */
 
636
#ifdef VWERASE
 
637
        s[C_WERASE] = td->c_cc[VWERASE];
 
638
#endif /* VWERASE */
 
639
#ifdef VSUSP
 
640
        s[C_SUSP] = td->c_cc[VSUSP];
 
641
#endif /* VSUSP */
 
642
#ifdef VDSUSP
 
643
        s[C_DSUSP] = td->c_cc[VDSUSP];
 
644
#endif /* VDSUSP */
 
645
#ifdef VREPRINT
 
646
        s[C_REPRINT] = td->c_cc[VREPRINT];
 
647
#endif /* VREPRINT */
 
648
#ifdef VDISCARD
 
649
        s[C_DISCARD] = td->c_cc[VDISCARD];
 
650
#endif /* VDISCARD */
 
651
#ifdef VLNEXT
 
652
        s[C_LNEXT] = td->c_cc[VLNEXT];
 
653
#endif /* VLNEXT */
 
654
#ifdef VSTATUS
 
655
        s[C_STATUS] = td->c_cc[VSTATUS];
 
656
#endif /* VSTATUS */
 
657
#ifdef VPAGE
 
658
        s[C_PAGE] = td->c_cc[VPAGE];
 
659
#endif /* VPAGE */
 
660
#ifdef VPGOFF
 
661
        s[C_PGOFF] = td->c_cc[VPGOFF];
 
662
#endif /* VPGOFF */
 
663
#ifdef VKILL2
 
664
        s[C_KILL2] = td->c_cc[VKILL2];
 
665
#endif /* KILL2 */
 
666
#ifdef VMIN
 
667
        s[C_MIN] = td->c_cc[VMIN];
 
668
#endif /* VMIN */
 
669
#ifdef VTIME
 
670
        s[C_TIME] = td->c_cc[VTIME];
 
671
#endif /* VTIME */
 
672
}                               /* tty__getchar */
 
673
 
 
674
 
 
675
/* tty__setchar():
 
676
 *      Set the tty characters
 
677
 */
 
678
private void
 
679
tty__setchar(struct termios *td, unsigned char *s)
 
680
{
 
681
 
 
682
#ifdef VINTR
 
683
        td->c_cc[VINTR] = s[C_INTR];
 
684
#endif /* VINTR */
 
685
#ifdef VQUIT
 
686
        td->c_cc[VQUIT] = s[C_QUIT];
 
687
#endif /* VQUIT */
 
688
#ifdef VERASE
 
689
        td->c_cc[VERASE] = s[C_ERASE];
 
690
#endif /* VERASE */
 
691
#ifdef VKILL
 
692
        td->c_cc[VKILL] = s[C_KILL];
 
693
#endif /* VKILL */
 
694
#ifdef VEOF
 
695
        td->c_cc[VEOF] = s[C_EOF];
 
696
#endif /* VEOF */
 
697
#ifdef VEOL
 
698
        td->c_cc[VEOL] = s[C_EOL];
 
699
#endif /* VEOL */
 
700
#ifdef VEOL2
 
701
        td->c_cc[VEOL2] = s[C_EOL2];
 
702
#endif /* VEOL2 */
 
703
#ifdef VSWTCH
 
704
        td->c_cc[VSWTCH] = s[C_SWTCH];
 
705
#endif /* VSWTCH */
 
706
#ifdef VDSWTCH
 
707
        td->c_cc[VDSWTCH] = s[C_DSWTCH];
 
708
#endif /* VDSWTCH */
 
709
#ifdef VERASE2
 
710
        td->c_cc[VERASE2] = s[C_ERASE2];
 
711
#endif /* VERASE2 */
 
712
#ifdef VSTART
 
713
        td->c_cc[VSTART] = s[C_START];
 
714
#endif /* VSTART */
 
715
#ifdef VSTOP
 
716
        td->c_cc[VSTOP] = s[C_STOP];
 
717
#endif /* VSTOP */
 
718
#ifdef VWERASE
 
719
        td->c_cc[VWERASE] = s[C_WERASE];
 
720
#endif /* VWERASE */
 
721
#ifdef VSUSP
 
722
        td->c_cc[VSUSP] = s[C_SUSP];
 
723
#endif /* VSUSP */
 
724
#ifdef VDSUSP
 
725
        td->c_cc[VDSUSP] = s[C_DSUSP];
 
726
#endif /* VDSUSP */
 
727
#ifdef VREPRINT
 
728
        td->c_cc[VREPRINT] = s[C_REPRINT];
 
729
#endif /* VREPRINT */
 
730
#ifdef VDISCARD
 
731
        td->c_cc[VDISCARD] = s[C_DISCARD];
 
732
#endif /* VDISCARD */
 
733
#ifdef VLNEXT
 
734
        td->c_cc[VLNEXT] = s[C_LNEXT];
 
735
#endif /* VLNEXT */
 
736
#ifdef VSTATUS
 
737
        td->c_cc[VSTATUS] = s[C_STATUS];
 
738
#endif /* VSTATUS */
 
739
#ifdef VPAGE
 
740
        td->c_cc[VPAGE] = s[C_PAGE];
 
741
#endif /* VPAGE */
 
742
#ifdef VPGOFF
 
743
        td->c_cc[VPGOFF] = s[C_PGOFF];
 
744
#endif /* VPGOFF */
 
745
#ifdef VKILL2
 
746
        td->c_cc[VKILL2] = s[C_KILL2];
 
747
#endif /* VKILL2 */
 
748
#ifdef VMIN
 
749
        td->c_cc[VMIN] = s[C_MIN];
 
750
#endif /* VMIN */
 
751
#ifdef VTIME
 
752
        td->c_cc[VTIME] = s[C_TIME];
 
753
#endif /* VTIME */
 
754
}                               /* tty__setchar */
 
755
 
 
756
 
 
757
/* tty_bind_char():
 
758
 *      Rebind the editline functions
 
759
 */
 
760
protected void
 
761
tty_bind_char(EditLine *el, int force)
 
762
{
 
763
 
 
764
        unsigned char *t_n = el->el_tty.t_c[ED_IO];
 
765
        unsigned char *t_o = el->el_tty.t_ed.c_cc;
 
766
        unsigned char new[2], old[2];
 
767
        const ttymap_t *tp;
 
768
        el_action_t *map, *alt;
 
769
        const el_action_t *dmap, *dalt;
 
770
        new[1] = old[1] = '\0';
 
771
 
 
772
        map = el->el_map.key;
 
773
        alt = el->el_map.alt;
 
774
        if (el->el_map.type == MAP_VI) {
 
775
                dmap = el->el_map.vii;
 
776
                dalt = el->el_map.vic;
 
777
        } else {
 
778
                dmap = el->el_map.emacs;
 
779
                dalt = NULL;
 
780
        }
 
781
 
 
782
        for (tp = tty_map; tp->nch != -1; tp++) {
 
783
                new[0] = t_n[tp->nch];
 
784
                old[0] = t_o[tp->och];
 
785
                if (new[0] == old[0] && !force)
 
786
                        continue;
 
787
                /* Put the old default binding back, and set the new binding */
 
788
                key_clear(el, map, (char *)old);
 
789
                map[old[0]] = dmap[old[0]];
 
790
                key_clear(el, map, (char *)new);
 
791
                /* MAP_VI == 1, MAP_EMACS == 0... */
 
792
                map[new[0]] = tp->bind[el->el_map.type];
 
793
                if (dalt) {
 
794
                        key_clear(el, alt, (char *)old);
 
795
                        alt[old[0]] = dalt[old[0]];
 
796
                        key_clear(el, alt, (char *)new);
 
797
                        alt[new[0]] = tp->bind[el->el_map.type + 1];
 
798
                }
 
799
        }
 
800
}
 
801
 
 
802
 
 
803
/* tty_rawmode():
 
804
 *      Set terminal into 1 character at a time mode.
 
805
 */
 
806
protected int
 
807
tty_rawmode(EditLine *el)
 
808
{
 
809
 
 
810
        if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
 
811
                return (0);
 
812
 
 
813
        if (el->el_flags & EDIT_DISABLED)
 
814
                return (0);
 
815
 
 
816
        if (tty_getty(el, &el->el_tty.t_ts) == -1) {
 
817
#ifdef DEBUG_TTY
 
818
                (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n",
 
819
                    strerror(errno));
 
820
#endif /* DEBUG_TTY */
 
821
                return (-1);
 
822
        }
 
823
        /*
 
824
         * We always keep up with the eight bit setting and the speed of the
 
825
         * tty. But only we only believe changes that are made to cooked mode!
 
826
         */
 
827
        el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
 
828
        el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
 
829
 
 
830
        if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
 
831
            tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
 
832
                (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
 
833
                (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
 
834
                (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
 
835
                (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
 
836
        }
 
837
        if (tty__cooked_mode(&el->el_tty.t_ts)) {
 
838
                if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
 
839
                        el->el_tty.t_ex.c_cflag =
 
840
                            el->el_tty.t_ts.c_cflag;
 
841
                        el->el_tty.t_ex.c_cflag &=
 
842
                            ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
 
843
                        el->el_tty.t_ex.c_cflag |=
 
844
                            el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
 
845
 
 
846
                        el->el_tty.t_ed.c_cflag =
 
847
                            el->el_tty.t_ts.c_cflag;
 
848
                        el->el_tty.t_ed.c_cflag &=
 
849
                            ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
 
850
                        el->el_tty.t_ed.c_cflag |=
 
851
                            el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
 
852
                }
 
853
                if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
 
854
                    (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
 
855
                        el->el_tty.t_ex.c_lflag =
 
856
                            el->el_tty.t_ts.c_lflag;
 
857
                        el->el_tty.t_ex.c_lflag &=
 
858
                            ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
 
859
                        el->el_tty.t_ex.c_lflag |=
 
860
                            el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
 
861
 
 
862
                        el->el_tty.t_ed.c_lflag =
 
863
                            el->el_tty.t_ts.c_lflag;
 
864
                        el->el_tty.t_ed.c_lflag &=
 
865
                            ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
 
866
                        el->el_tty.t_ed.c_lflag |=
 
867
                            el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
 
868
                }
 
869
                if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
 
870
                    (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
 
871
                        el->el_tty.t_ex.c_iflag =
 
872
                            el->el_tty.t_ts.c_iflag;
 
873
                        el->el_tty.t_ex.c_iflag &=
 
874
                            ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
 
875
                        el->el_tty.t_ex.c_iflag |=
 
876
                            el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
 
877
 
 
878
                        el->el_tty.t_ed.c_iflag =
 
879
                            el->el_tty.t_ts.c_iflag;
 
880
                        el->el_tty.t_ed.c_iflag &=
 
881
                            ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
 
882
                        el->el_tty.t_ed.c_iflag |=
 
883
                            el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
 
884
                }
 
885
                if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
 
886
                    (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
 
887
                        el->el_tty.t_ex.c_oflag =
 
888
                            el->el_tty.t_ts.c_oflag;
 
889
                        el->el_tty.t_ex.c_oflag &=
 
890
                            ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
 
891
                        el->el_tty.t_ex.c_oflag |=
 
892
                            el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
 
893
 
 
894
                        el->el_tty.t_ed.c_oflag =
 
895
                            el->el_tty.t_ts.c_oflag;
 
896
                        el->el_tty.t_ed.c_oflag &=
 
897
                            ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
 
898
                        el->el_tty.t_ed.c_oflag |=
 
899
                            el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
 
900
                }
 
901
                if (tty__gettabs(&el->el_tty.t_ex) == 0)
 
902
                        el->el_tty.t_tabs = 0;
 
903
                else
 
904
                        el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
 
905
 
 
906
                {
 
907
                        int i;
 
908
 
 
909
                        tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
 
910
                        /*
 
911
                         * Check if the user made any changes.
 
912
                         * If he did, then propagate the changes to the
 
913
                         * edit and execute data structures.
 
914
                         */
 
915
                        for (i = 0; i < C_NCC; i++)
 
916
                                if (el->el_tty.t_c[TS_IO][i] !=
 
917
                                    el->el_tty.t_c[EX_IO][i])
 
918
                                        break;
 
919
 
 
920
                        if (i != C_NCC) {
 
921
                                /*
 
922
                                 * Propagate changes only to the unprotected
 
923
                                 * chars that have been modified just now.
 
924
                                 */
 
925
                                for (i = 0; i < C_NCC; i++) {
 
926
                                        if (!((el->el_tty.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i)))
 
927
                                            && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
 
928
                                                el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
 
929
                                        if (el->el_tty.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i))
 
930
                                                el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
 
931
                                }
 
932
                                tty_bind_char(el, 0);
 
933
                                tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
 
934
 
 
935
                                for (i = 0; i < C_NCC; i++) {
 
936
                                        if (!((el->el_tty.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i)))
 
937
                                            && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
 
938
                                                el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
 
939
                                        if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i))
 
940
                                                el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
 
941
                                }
 
942
                                tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
 
943
                        }
 
944
                }
 
945
        }
 
946
        if (tty_setty(el, &el->el_tty.t_ed) == -1) {
 
947
#ifdef DEBUG_TTY
 
948
                (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
 
949
                    strerror(errno));
 
950
#endif /* DEBUG_TTY */
 
951
                return (-1);
 
952
        }
 
953
        el->el_tty.t_mode = ED_IO;
 
954
        return (0);
 
955
}
 
956
 
 
957
 
 
958
/* tty_cookedmode():
 
959
 *      Set the tty back to normal mode
 
960
 */
 
961
protected int
 
962
tty_cookedmode(EditLine *el)
 
963
{                               /* set tty in normal setup */
 
964
 
 
965
        if (el->el_tty.t_mode == EX_IO)
 
966
                return (0);
 
967
 
 
968
        if (el->el_flags & EDIT_DISABLED)
 
969
                return (0);
 
970
 
 
971
        if (tty_setty(el, &el->el_tty.t_ex) == -1) {
 
972
#ifdef DEBUG_TTY
 
973
                (void) fprintf(el->el_errfile,
 
974
                    "tty_cookedmode: tty_setty: %s\n",
 
975
                    strerror(errno));
 
976
#endif /* DEBUG_TTY */
 
977
                return (-1);
 
978
        }
 
979
        el->el_tty.t_mode = EX_IO;
 
980
        return (0);
 
981
}
 
982
 
 
983
 
 
984
/* tty_quotemode():
 
985
 *      Turn on quote mode
 
986
 */
 
987
protected int
 
988
tty_quotemode(EditLine *el)
 
989
{
 
990
        if (el->el_tty.t_mode == QU_IO)
 
991
                return (0);
 
992
 
 
993
        el->el_tty.t_qu = el->el_tty.t_ed;
 
994
 
 
995
        el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask;
 
996
        el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask;
 
997
 
 
998
        el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask;
 
999
        el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask;
 
1000
 
 
1001
        el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask;
 
1002
        el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask;
 
1003
 
 
1004
        el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask;
 
1005
        el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask;
 
1006
 
 
1007
        if (tty_setty(el, &el->el_tty.t_qu) == -1) {
 
1008
#ifdef DEBUG_TTY
 
1009
                (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
 
1010
                    strerror(errno));
 
1011
#endif /* DEBUG_TTY */
 
1012
                return (-1);
 
1013
        }
 
1014
        el->el_tty.t_mode = QU_IO;
 
1015
        return (0);
 
1016
}
 
1017
 
 
1018
 
 
1019
/* tty_noquotemode():
 
1020
 *      Turn off quote mode
 
1021
 */
 
1022
protected int
 
1023
tty_noquotemode(EditLine *el)
 
1024
{
 
1025
 
 
1026
        if (el->el_tty.t_mode != QU_IO)
 
1027
                return (0);
 
1028
        if (tty_setty(el, &el->el_tty.t_ed) == -1) {
 
1029
#ifdef DEBUG_TTY
 
1030
                (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
 
1031
                    strerror(errno));
 
1032
#endif /* DEBUG_TTY */
 
1033
                return (-1);
 
1034
        }
 
1035
        el->el_tty.t_mode = ED_IO;
 
1036
        return (0);
 
1037
}
 
1038
 
 
1039
 
 
1040
/* tty_stty():
 
1041
 *      Stty builtin
 
1042
 */
 
1043
protected int
 
1044
/*ARGSUSED*/
 
1045
tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv)
 
1046
{
 
1047
        const ttymodes_t *m;
 
1048
        char x;
 
1049
        const char *d;
 
1050
        int aflag = 0;
 
1051
        const char *s;
 
1052
        const char *name;
 
1053
        int z = EX_IO;
 
1054
 
 
1055
        if (argv == NULL)
 
1056
                return (-1);
 
1057
        name = *argv++;
 
1058
 
 
1059
        while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
 
1060
                switch (argv[0][1]) {
 
1061
                case 'a':
 
1062
                        aflag++;
 
1063
                        argv++;
 
1064
                        break;
 
1065
                case 'd':
 
1066
                        argv++;
 
1067
                        z = ED_IO;
 
1068
                        break;
 
1069
                case 'x':
 
1070
                        argv++;
 
1071
                        z = EX_IO;
 
1072
                        break;
 
1073
                case 'q':
 
1074
                        argv++;
 
1075
                        z = QU_IO;
 
1076
                        break;
 
1077
                default:
 
1078
                        (void) fprintf(el->el_errfile,
 
1079
                            "%s: Unknown switch `%c'.\n",
 
1080
                            name, argv[0][1]);
 
1081
                        return (-1);
 
1082
                }
 
1083
 
 
1084
        if (!argv || !*argv) {
 
1085
                int i = -1;
 
1086
                int len = 0, st = 0, cu;
 
1087
                for (m = ttymodes; m->m_name; m++) {
 
1088
                        if (m->m_type != i) {
 
1089
                                (void) fprintf(el->el_outfile, "%s%s",
 
1090
                                    i != -1 ? "\n" : "",
 
1091
                                    el->el_tty.t_t[z][m->m_type].t_name);
 
1092
                                i = m->m_type;
 
1093
                                st = len =
 
1094
                                    strlen(el->el_tty.t_t[z][m->m_type].t_name);
 
1095
                        }
 
1096
                        x = (el->el_tty.t_t[z][i].t_setmask & m->m_value)
 
1097
                            ?  '+' : '\0';
 
1098
                        x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
 
1099
                            ? '-' : x;
 
1100
 
 
1101
                        if (x != '\0' || aflag) {
 
1102
 
 
1103
                                cu = strlen(m->m_name) + (x != '\0') + 1;
 
1104
 
 
1105
                                if (len + cu >= el->el_term.t_size.h) {
 
1106
                                        (void) fprintf(el->el_outfile, "\n%*s",
 
1107
                                            st, "");
 
1108
                                        len = st + cu;
 
1109
                                } else
 
1110
                                        len += cu;
 
1111
 
 
1112
                                if (x != '\0')
 
1113
                                        (void) fprintf(el->el_outfile, "%c%s ",
 
1114
                                            x, m->m_name);
 
1115
                                else
 
1116
                                        (void) fprintf(el->el_outfile, "%s ",
 
1117
                                            m->m_name);
 
1118
                        }
 
1119
                }
 
1120
                (void) fprintf(el->el_outfile, "\n");
 
1121
                return (0);
 
1122
        }
 
1123
        while (argv && (s = *argv++)) {
 
1124
                switch (*s) {
 
1125
                case '+':
 
1126
                case '-':
 
1127
                        x = *s++;
 
1128
                        break;
 
1129
                default:
 
1130
                        x = '\0';
 
1131
                        break;
 
1132
                }
 
1133
                d = s;
 
1134
                for (m = ttymodes; m->m_name; m++)
 
1135
                        if (strcmp(m->m_name, d) == 0)
 
1136
                                break;
 
1137
 
 
1138
                if (!m->m_name) {
 
1139
                        (void) fprintf(el->el_errfile,
 
1140
                            "%s: Invalid argument `%s'.\n", name, d);
 
1141
                        return (-1);
 
1142
                }
 
1143
                switch (x) {
 
1144
                case '+':
 
1145
                        el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
 
1146
                        el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
 
1147
                        break;
 
1148
                case '-':
 
1149
                        el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
 
1150
                        el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
 
1151
                        break;
 
1152
                default:
 
1153
                        el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
 
1154
                        el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
 
1155
                        break;
 
1156
                }
 
1157
        }
 
1158
        return (0);
 
1159
}
 
1160
 
 
1161
 
 
1162
#ifdef notyet
 
1163
/* tty_printchar():
 
1164
 *      DEbugging routine to print the tty characters
 
1165
 */
 
1166
private void
 
1167
tty_printchar(EditLine *el, unsigned char *s)
 
1168
{
 
1169
        ttyperm_t *m;
 
1170
        int i;
 
1171
 
 
1172
        for (i = 0; i < C_NCC; i++) {
 
1173
                for (m = el->el_tty.t_t; m->m_name; m++)
 
1174
                        if (m->m_type == MD_CHAR && C_SH(i) == m->m_value)
 
1175
                                break;
 
1176
                if (m->m_name)
 
1177
                        (void) fprintf(el->el_errfile, "%s ^%c ",
 
1178
                            m->m_name, s[i] + 'A' - 1);
 
1179
                if (i % 5 == 0)
 
1180
                        (void) fprintf(el->el_errfile, "\n");
 
1181
        }
 
1182
        (void) fprintf(el->el_errfile, "\n");
 
1183
}
 
1184
#endif /* notyet */