2
* ed.init.c: Editor initializations
5
* Copyright (c) 1980, 1991 The Regents of the University of California.
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
11
* 1. Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
* 3. All advertising materials mentioning features or use of this software
17
* must display the following acknowledgement:
18
* This product includes software developed by the University of
19
* California, Berkeley and its contributors.
20
* 4. Neither the name of the University nor the names of its contributors
21
* may be used to endorse or promote products derived from this software
22
* without specific prior written permission.
24
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTS_ION)
31
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45
/* ed.init.c -- init routines for the line editor */
46
/* #define DEBUG_TTY */
48
int Tty_raw_mode = 0; /* Last tty change was to raw mode */
49
int MacroLvl = -1; /* pointer to current macro nesting level; */
51
static int Tty_quote_mode = 0; /* Last tty change was to quote mode */
52
static unsigned char vdisable; /* The value of _POSIX_VDISABLE from
55
int Tty_eight_bit = -1; /* does the tty handle eight bits */
57
extern bool GotTermCaps;
59
static ttydata_t extty, edtty, tstty;
63
#define SHTTY (insource ? OLDSTD : SHIN)
65
#define uc unsigned char
66
static unsigned char ttychars[NN_IO][C_NCC] = {
68
(uc)CINTR, (uc)CQUIT, (uc)CERASE, (uc)CKILL,
69
(uc)CEOF, (uc)CEOL, (uc)CEOL2, (uc)CSWTCH,
70
(uc)CDSWTCH, (uc)CERASE2, (uc)CSTART, (uc)CSTOP,
71
(uc)CWERASE, (uc)CSUSP, (uc)CDSUSP, (uc)CREPRINT,
72
(uc)CDISCARD, (uc)CLNEXT, (uc)CSTATUS, (uc)CPAGE,
73
(uc)CPGOFF, (uc)CKILL2, (uc)CBRK, (uc)CMIN,
77
CINTR, CQUIT, CERASE, CKILL,
78
_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
79
_POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
80
_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
81
CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
82
_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
98
check_window_size(force)
106
/* don't want to confuse things here */
108
omask = sigblock(sigmask(SIG_WINDOW)) & ~sigmask(SIG_WINDOW);
110
(void) sighold(SIG_WINDOW);
113
* From: bret@shark.agps.lanl.gov (Bret Thaeler) Avoid sunview bug, where a
114
* partially hidden window gets a SIG_WINDOW every time the text is
117
if (GetSize(&lins, &cols) || force) {
123
ChangeSize(lins, cols);
127
ChangeSize(lins, cols);
130
(void) sigsetmask(omask); /* can change it again */
132
(void) sigrelse(SIG_WINDOW);
142
/* If we were called as a signal handler, restore it. */
144
sigset(snum, window_change);
145
#endif /* UNRELSIGS */
146
check_window_size(0);
152
#endif /* SIG_WINDOW */
155
ed_set_tty_eight_bit()
157
if (tty_getty(SHTTY, &extty) == -1) {
159
xprintf("ed_set_tty_eight_bit: tty_getty: %s\n", strerror(errno));
160
#endif /* DEBUG_TTY */
163
Tty_eight_bit = tty_geteightbit(&extty);
171
static int havesetup = 0;
172
struct varent *imode;
174
if (havesetup) /* if we have never been called */
177
#if defined(POSIX) && defined(_PC_VDISABLE) && !defined(BSD4_4) && \
182
if ((pcret = fpathconf(SHTTY, _PC_VDISABLE)) == -1L)
183
vdisable = (unsigned char) _POSIX_VDISABLE;
185
vdisable = (unsigned char) pcret;
186
if (vdisable != (unsigned char) _POSIX_VDISABLE && rst != 0)
187
for (rst = 0; rst < C_NCC; rst++) {
188
if (ttychars[ED_IO][rst] == (unsigned char) _POSIX_VDISABLE)
189
ttychars[ED_IO][rst] = vdisable;
190
if (ttychars[EX_IO][rst] == (unsigned char) _POSIX_VDISABLE)
191
ttychars[EX_IO][rst] = vdisable;
194
#else /* ! POSIX || !_PC_VDISABLE || BSD4_4 || WINNT */
195
vdisable = (unsigned char) _POSIX_VDISABLE;
196
#endif /* POSIX && _PC_VDISABLE && !BSD4_4 && !WINNT */
198
if ((imode = adrof(STRinputmode)) != NULL) {
199
if (!Strcmp(*(imode->vec), STRinsert))
200
inputmode = MODE_INSERT;
201
else if (!Strcmp(*(imode->vec), STRoverwrite))
202
inputmode = MODE_REPLACE;
205
inputmode = MODE_INSERT;
211
if (tty_getty(SHTTY, &extty) == -1) {
213
xprintf("ed_Setup: tty_getty: %s\n", strerror(errno));
214
# endif /* DEBUG_TTY */
218
tstty = edtty = extty;
220
T_Speed = tty_getspeed(&extty);
221
T_Tabs = tty_gettabs(&extty);
222
Tty_eight_bit = tty_geteightbit(&extty);
224
# if defined(POSIX) || defined(TERMIO)
225
extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
226
extty.d_t.c_iflag |= ttylist[EX_IO][M_INPUT].t_setmask;
228
extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
229
extty.d_t.c_oflag |= ttylist[EX_IO][M_OUTPUT].t_setmask;
231
extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
232
extty.d_t.c_cflag |= ttylist[EX_IO][M_CONTROL].t_setmask;
234
extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
235
extty.d_t.c_lflag |= ttylist[EX_IO][M_LINED].t_setmask;
237
# if defined(IRIX3_3) && SYSVREL < 4
238
extty.d_t.c_line = NTTYDISC;
239
# endif /* IRIX3_3 && SYSVREL < 4 */
241
# else /* GSTTY */ /* V7, Berkeley style tty */
243
if (T_Tabs) { /* order of &= and |= is important to XTABS */
244
extty.d_t.sg_flags &= ~(ttylist[EX_IO][M_CONTROL].t_clrmask|XTABS);
245
extty.d_t.sg_flags |= ttylist[EX_IO][M_CONTROL].t_setmask;
248
extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
249
extty.d_t.sg_flags |= (ttylist[EX_IO][M_CONTROL].t_setmask|XTABS);
252
extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
253
extty.d_lb |= ttylist[EX_IO][M_LOCAL].t_setmask;
257
* Reset the tty chars to reasonable defaults
258
* If they are disabled, then enable them.
261
if (tty_cooked_mode(&tstty)) {
262
tty_getchar(&tstty, ttychars[TS_IO]);
264
* Don't affect CMIN and CTIME for the editor mode
266
for (rst = 0; rst < C_NCC - 2; rst++)
267
if (ttychars[TS_IO][rst] != vdisable &&
268
ttychars[ED_IO][rst] != vdisable)
269
ttychars[ED_IO][rst] = ttychars[TS_IO][rst];
270
for (rst = 0; rst < C_NCC; rst++)
271
if (ttychars[TS_IO][rst] != vdisable &&
272
ttychars[EX_IO][rst] != vdisable)
273
ttychars[EX_IO][rst] = ttychars[TS_IO][rst];
275
tty_setchar(&extty, ttychars[EX_IO]);
276
if (tty_setty(SHTTY, &extty) == -1) {
278
xprintf("ed_Setup: tty_setty: %s\n", strerror(errno));
279
# endif /* DEBUG_TTY */
284
tty_setchar(&extty, ttychars[EX_IO]);
287
(void) sigset(SIG_WINDOW, window_change); /* for window systems */
292
xprintf("rst received in ed_Setup() %d\n", rst);
302
ResetInLine(1); /* reset the input pointers */
303
GettingInput = 0; /* just in case */
304
LastKill = KillBuf; /* no kill buffer */
307
CheckMaps(); /* do a little error checking on key maps */
310
if (ed_Setup(0) == -1)
314
* if we have been called before but GotTermCaps isn't set, our TERM has
315
* changed, so get new termcaps and try again
319
GetTermCaps(); /* does the obvious, but gets term type each
323
# if defined(TERMIO) || defined(POSIX)
324
edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
325
edtty.d_t.c_iflag |= ttylist[ED_IO][M_INPUT].t_setmask;
327
edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
328
edtty.d_t.c_oflag |= ttylist[ED_IO][M_OUTPUT].t_setmask;
330
edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
331
edtty.d_t.c_cflag |= ttylist[ED_IO][M_CONTROL].t_setmask;
333
edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
334
edtty.d_t.c_lflag |= ttylist[ED_IO][M_LINED].t_setmask;
337
# if defined(IRIX3_3) && SYSVREL < 4
338
edtty.d_t.c_line = NTTYDISC;
339
# endif /* IRIX3_3 && SYSVREL < 4 */
343
if (T_Tabs) { /* order of &= and |= is important to XTABS */
344
edtty.d_t.sg_flags &= ~(ttylist[ED_IO][M_CONTROL].t_clrmask | XTABS);
345
edtty.d_t.sg_flags |= ttylist[ED_IO][M_CONTROL].t_setmask;
348
edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
349
edtty.d_t.sg_flags |= (ttylist[ED_IO][M_CONTROL].t_setmask | XTABS);
352
edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
353
edtty.d_lb |= ttylist[ED_IO][M_LOCAL].t_setmask;
354
# endif /* POSIX || TERMIO */
356
tty_setchar(&edtty, ttychars[ED_IO]);
361
* Check and re-init the line. set the terminal into 1 char at a time mode.
373
tty_setdisc(SHTTY, ED_IO);
376
if (tty_getty(SHTTY, &tstty) == -1) {
378
xprintf("Rawmode: tty_getty: %s\n", strerror(errno));
379
# endif /* DEBUG_TTY */
384
* We always keep up with the eight bit setting and the speed of the
385
* tty. But only we only believe changes that are made to cooked mode!
387
# if defined(POSIX) || defined(TERMIO)
388
Tty_eight_bit = tty_geteightbit(&tstty);
389
T_Speed = tty_getspeed(&tstty);
393
* Fix from: Steven (Steve) B. Green <xrsbg@charney.gsfc.nasa.gov>
394
* Speed was not being set up correctly under POSIX.
396
if (tty_getspeed(&extty) != T_Speed || tty_getspeed(&edtty) != T_Speed) {
397
(void) cfsetispeed(&extty.d_t, T_Speed);
398
(void) cfsetospeed(&extty.d_t, T_Speed);
399
(void) cfsetispeed(&edtty.d_t, T_Speed);
400
(void) cfsetospeed(&edtty.d_t, T_Speed);
405
T_Speed = tty_getspeed(&tstty);
406
Tty_eight_bit = tty_geteightbit(&tstty);
408
if (extty.d_t.sg_ispeed != tstty.d_t.sg_ispeed) {
409
extty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
410
edtty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
413
if (extty.d_t.sg_ospeed != tstty.d_t.sg_ospeed) {
414
extty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
415
edtty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
417
# endif /* POSIX || TERMIO */
419
if (tty_cooked_mode(&tstty)) {
421
* re-test for some things here (like maybe the user typed
424
if (tty_gettabs(&tstty) == 0)
429
# if defined(POSIX) || defined(TERMIO)
430
extty.d_t.c_cflag = tstty.d_t.c_cflag;
431
extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
432
extty.d_t.c_cflag |= ttylist[EX_IO][M_CONTROL].t_setmask;
434
edtty.d_t.c_cflag = tstty.d_t.c_cflag;
435
edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
436
edtty.d_t.c_cflag |= ttylist[ED_IO][M_CONTROL].t_setmask;
438
extty.d_t.c_lflag = tstty.d_t.c_lflag;
439
extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
440
extty.d_t.c_lflag |= ttylist[EX_IO][M_LINED].t_setmask;
442
edtty.d_t.c_lflag = tstty.d_t.c_lflag;
443
edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
444
edtty.d_t.c_lflag |= ttylist[ED_IO][M_LINED].t_setmask;
446
extty.d_t.c_iflag = tstty.d_t.c_iflag;
447
extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
448
extty.d_t.c_iflag |= ttylist[EX_IO][M_INPUT].t_setmask;
450
edtty.d_t.c_iflag = tstty.d_t.c_iflag;
451
edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
452
edtty.d_t.c_iflag |= ttylist[ED_IO][M_INPUT].t_setmask;
454
extty.d_t.c_oflag = tstty.d_t.c_oflag;
455
extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
456
extty.d_t.c_oflag |= ttylist[EX_IO][M_OUTPUT].t_setmask;
458
edtty.d_t.c_oflag = tstty.d_t.c_oflag;
459
edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
460
edtty.d_t.c_oflag |= ttylist[ED_IO][M_OUTPUT].t_setmask;
464
extty.d_t.sg_flags = tstty.d_t.sg_flags;
466
extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
467
extty.d_t.sg_flags |= ttylist[EX_IO][M_CONTROL].t_setmask;
469
if (T_Tabs) /* order of &= and |= is important to XTABS */
470
extty.d_t.sg_flags &= ~XTABS;
472
extty.d_t.sg_flags |= XTABS;
474
extty.d_lb = tstty.d_lb;
475
extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
476
extty.d_lb |= ttylist[EX_IO][M_LOCAL].t_setmask;
478
edtty.d_t.sg_flags = extty.d_t.sg_flags;
479
if (T_Tabs) { /* order of &= and |= is important to XTABS */
480
edtty.d_t.sg_flags &=
481
~(ttylist[ED_IO][M_CONTROL].t_clrmask|XTABS);
482
edtty.d_t.sg_flags |= ttylist[ED_IO][M_CONTROL].t_setmask;
485
edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
486
edtty.d_t.sg_flags |=
487
(ttylist[ED_IO][M_CONTROL].t_setmask|XTABS);
490
edtty.d_lb = tstty.d_lb;
491
edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
492
edtty.d_lb |= ttylist[ED_IO][M_LOCAL].t_setmask;
494
# endif /* TERMIO || POSIX */
500
tty_getchar(&tstty, ttychars[TS_IO]);
502
* Check if the user made any changes.
503
* If he did, then propagate the changes to the
504
* edit and execute data structures.
506
for (i = 0; i < C_NCC; i++)
507
if (ttychars[TS_IO][i] != ttychars[EX_IO][i])
510
if (i != C_NCC || didsetty) {
513
* Propagate changes only to the unprotected chars
514
* that have been modified just now.
516
for (i = 0; i < C_NCC; i++) {
517
if (!((ttylist[ED_IO][M_CHAR].t_setmask & C_SH(i))) &&
518
(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
519
ttychars[ED_IO][i] = ttychars[TS_IO][i];
520
if (ttylist[ED_IO][M_CHAR].t_clrmask & C_SH(i))
521
ttychars[ED_IO][i] = vdisable;
523
tty_setchar(&edtty, ttychars[ED_IO]);
525
for (i = 0; i < C_NCC; i++) {
526
if (!((ttylist[EX_IO][M_CHAR].t_setmask & C_SH(i))) &&
527
(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
528
ttychars[EX_IO][i] = ttychars[TS_IO][i];
529
if (ttylist[EX_IO][M_CHAR].t_clrmask & C_SH(i))
530
ttychars[EX_IO][i] = vdisable;
532
tty_setchar(&extty, ttychars[EX_IO]);
537
if (tty_setty(SHTTY, &edtty) == -1) {
539
xprintf("Rawmode: tty_setty: %s\n", strerror(errno));
540
# endif /* DEBUG_TTY */
545
flush(); /* flush any buffered output */
551
{ /* set tty in normal setup */
555
signalfun_t orig_intr;
558
tty_setdisc(SHTTY, EX_IO);
564
/* hold this for reseting tty */
566
orig_intr = (signalfun_t) signal(SIGINT, SIG_IGN);
570
* sigset doesn't return the previous handler if the signal is held,
571
* it will return SIG_HOLD instead. So instead of restoring the
572
* the signal we would end up installing a blocked SIGINT with a
573
* SIG_IGN signal handler. This is what happened when Cookedmode
574
* was called from sched_run, disabling interrupt for the rest
577
* This is what we do:
578
* - if the signal is blocked, keep it that way
579
* - else set it to SIG_IGN
581
* Casper Dik (casper@fwi.uva.nl)
583
orig_intr = (signalfun_t) sigset(SIGINT, SIG_HOLD);
584
if (orig_intr != SIG_HOLD)
585
(void) sigset(SIGINT, SIG_IGN); /* returns SIG_HOLD */
586
# else /* !SIG_HOLD */
588
* No SIG_HOLD; probably no reliable signals as well.
590
orig_intr = (signalfun_t) sigset(SIGINT, SIG_IGN);
591
# endif /* SIG_HOLD */
592
# endif /* BSDSIGS */
593
if (tty_setty(SHTTY, &extty) == -1) {
595
xprintf("Cookedmode: tty_setty: %s\n", strerror(errno));
596
# endif /* DEBUG_TTY */
600
(void) signal(SIGINT, orig_intr); /* take these again */
602
(void) sigset(SIGINT, orig_intr); /* take these again */
603
# endif /* BSDSIGS */
614
Cursor = InputBuf; /* reset cursor */
616
InputLim = &InputBuf[INBUFSIZE - 2];
619
CurrentKeyMap = CcKeyMap;
625
LastKill = KillBuf; /* no kill buffer */
627
LastCmd = F_UNASSIGNED; /* previous command executed */
629
MacroLvl = -1; /* no currently active macros */
632
static Char *Input_Line = NULL;
640
* *Everyone* else has an int, but SunOS wants long!
641
* This breaks where int != long (alpha)
647
xfree((ptr_t) Input_Line);
653
#if defined(FIONREAD) && !defined(OREO)
654
(void) ioctl(SHIN, FIONREAD, (ioctl_t) &chrs);
658
chrs = read(SHIN, buf, (size_t) min(chrs, BUFSIZE - 1));
661
Input_Line = Strsave(str2short(buf));
662
PushMacro(Input_Line);
665
/* need to print errno message in case file is migrated */
667
stderror(ERR_SYSTEM, progname, strerror(errno));
670
#endif /* FIONREAD && !OREO */
675
* Bugfix (in Swedish) by:
677
* SICS, PO Box 1263, S-163 13 SPANGA, SWEDEN
678
* {mcvax,munnari,cernvax,diku,inria,prlb2,penet,ukc,unido}!enea!sics.se!jw
679
* Internet: jw@sics.se
681
* (via Hans J Albertsson (thanks))
692
#if defined(TERMIO) || defined(POSIX)
693
qutty.d_t.c_iflag &= ~ttylist[QU_IO][M_INPUT].t_clrmask;
694
qutty.d_t.c_iflag |= ttylist[QU_IO][M_INPUT].t_setmask;
696
qutty.d_t.c_oflag &= ~ttylist[QU_IO][M_OUTPUT].t_clrmask;
697
qutty.d_t.c_oflag |= ttylist[QU_IO][M_OUTPUT].t_setmask;
699
qutty.d_t.c_cflag &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
700
qutty.d_t.c_cflag |= ttylist[QU_IO][M_CONTROL].t_setmask;
702
qutty.d_t.c_lflag &= ~ttylist[QU_IO][M_LINED].t_clrmask;
703
qutty.d_t.c_lflag |= ttylist[QU_IO][M_LINED].t_setmask;
705
qutty.d_t.sg_flags &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
706
qutty.d_t.sg_flags |= ttylist[QU_IO][M_CONTROL].t_setmask;
707
qutty.d_lb &= ~ttylist[QU_IO][M_LOCAL].t_clrmask;
708
qutty.d_lb |= ttylist[QU_IO][M_LOCAL].t_setmask;
710
#endif /* TERMIO || POSIX */
711
if (tty_setty(SHTTY, &qutty) == -1) {
713
xprintf("QuoteModeOn: tty_setty: %s\n", strerror(errno));
714
#endif /* DEBUG_TTY */
728
if (tty_setty(SHTTY, &edtty) == -1) {
730
xprintf("QuoteModeOff: tty_setty: %s\n", strerror(errno));
731
#endif /* DEBUG_TTY */