1c80476e4SDavid E. O'Brien /*
2c80476e4SDavid E. O'Brien * sh.print.c: Primitive Output routines.
3c80476e4SDavid E. O'Brien */
4c80476e4SDavid E. O'Brien /*-
5c80476e4SDavid E. O'Brien * Copyright (c) 1980, 1991 The Regents of the University of California.
6c80476e4SDavid E. O'Brien * All rights reserved.
7c80476e4SDavid E. O'Brien *
8c80476e4SDavid E. O'Brien * Redistribution and use in source and binary forms, with or without
9c80476e4SDavid E. O'Brien * modification, are permitted provided that the following conditions
10c80476e4SDavid E. O'Brien * are met:
11c80476e4SDavid E. O'Brien * 1. Redistributions of source code must retain the above copyright
12c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer.
13c80476e4SDavid E. O'Brien * 2. Redistributions in binary form must reproduce the above copyright
14c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer in the
15c80476e4SDavid E. O'Brien * documentation and/or other materials provided with the distribution.
1629301572SMark Peek * 3. Neither the name of the University nor the names of its contributors
17c80476e4SDavid E. O'Brien * may be used to endorse or promote products derived from this software
18c80476e4SDavid E. O'Brien * without specific prior written permission.
19c80476e4SDavid E. O'Brien *
20c80476e4SDavid E. O'Brien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21c80476e4SDavid E. O'Brien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22c80476e4SDavid E. O'Brien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23c80476e4SDavid E. O'Brien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24c80476e4SDavid E. O'Brien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25c80476e4SDavid E. O'Brien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26c80476e4SDavid E. O'Brien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27c80476e4SDavid E. O'Brien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28c80476e4SDavid E. O'Brien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29c80476e4SDavid E. O'Brien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30c80476e4SDavid E. O'Brien * SUCH DAMAGE.
31c80476e4SDavid E. O'Brien */
32c80476e4SDavid E. O'Brien #include "sh.h"
33c80476e4SDavid E. O'Brien #include "ed.h"
34c80476e4SDavid E. O'Brien
35c80476e4SDavid E. O'Brien extern int Tty_eight_bit;
36c80476e4SDavid E. O'Brien
37c80476e4SDavid E. O'Brien int lbuffed = 1; /* true if line buffered */
38c80476e4SDavid E. O'Brien
3945e5710bSMark Peek static void p2dig (unsigned int);
40c80476e4SDavid E. O'Brien
41c80476e4SDavid E. O'Brien /*
42c80476e4SDavid E. O'Brien * C Shell
43c80476e4SDavid E. O'Brien */
44c80476e4SDavid E. O'Brien
45c80476e4SDavid E. O'Brien #if defined(BSDLIMIT) || defined(RLIMIT_CPU)
46c80476e4SDavid E. O'Brien void
psecs(unsigned long l)4745e5710bSMark Peek psecs(unsigned long l)
48c80476e4SDavid E. O'Brien {
4923338178SMark Peek int i;
50c80476e4SDavid E. O'Brien
51c80476e4SDavid E. O'Brien i = (int) (l / 3600);
52c80476e4SDavid E. O'Brien if (i) {
53c80476e4SDavid E. O'Brien xprintf("%d:", i);
54c80476e4SDavid E. O'Brien i = (int) (l % 3600);
55c80476e4SDavid E. O'Brien p2dig(i / 60);
56c80476e4SDavid E. O'Brien goto minsec;
57c80476e4SDavid E. O'Brien }
58c80476e4SDavid E. O'Brien i = (int) l;
59c80476e4SDavid E. O'Brien xprintf("%d", i / 60);
60c80476e4SDavid E. O'Brien minsec:
61c80476e4SDavid E. O'Brien i %= 60;
62c80476e4SDavid E. O'Brien xprintf(":");
63c80476e4SDavid E. O'Brien p2dig(i);
64c80476e4SDavid E. O'Brien }
65c80476e4SDavid E. O'Brien
66c80476e4SDavid E. O'Brien #endif
67c80476e4SDavid E. O'Brien
6845e5710bSMark Peek void /* PWP: print mm:ss.dd, l is in sec*100 */
69c80476e4SDavid E. O'Brien #ifdef BSDTIMES
pcsecs(unsigned long l)7045e5710bSMark Peek pcsecs(unsigned long l)
71c80476e4SDavid E. O'Brien #else /* BSDTIMES */
72c80476e4SDavid E. O'Brien # ifndef POSIX
7345e5710bSMark Peek pcsecs(time_t l)
74c80476e4SDavid E. O'Brien # else /* POSIX */
7545e5710bSMark Peek pcsecs(clock_t l)
76c80476e4SDavid E. O'Brien # endif /* POSIX */
77c80476e4SDavid E. O'Brien #endif /* BSDTIMES */
78c80476e4SDavid E. O'Brien {
7923338178SMark Peek int i;
80c80476e4SDavid E. O'Brien
81c80476e4SDavid E. O'Brien i = (int) (l / 360000);
82c80476e4SDavid E. O'Brien if (i) {
83c80476e4SDavid E. O'Brien xprintf("%d:", i);
84c80476e4SDavid E. O'Brien i = (int) ((l % 360000) / 100);
85c80476e4SDavid E. O'Brien p2dig(i / 60);
86c80476e4SDavid E. O'Brien goto minsec;
87c80476e4SDavid E. O'Brien }
88c80476e4SDavid E. O'Brien i = (int) (l / 100);
89c80476e4SDavid E. O'Brien xprintf("%d", i / 60);
90c80476e4SDavid E. O'Brien minsec:
91c80476e4SDavid E. O'Brien i %= 60;
92c80476e4SDavid E. O'Brien xprintf(":");
93c80476e4SDavid E. O'Brien p2dig(i);
94c80476e4SDavid E. O'Brien xprintf(".");
95c80476e4SDavid E. O'Brien p2dig((int) (l % 100));
96c80476e4SDavid E. O'Brien }
97c80476e4SDavid E. O'Brien
98c80476e4SDavid E. O'Brien static void
p2dig(unsigned i)9945e5710bSMark Peek p2dig(unsigned i)
100c80476e4SDavid E. O'Brien {
101c80476e4SDavid E. O'Brien
10223338178SMark Peek xprintf("%u%u", i / 10, i % 10);
103c80476e4SDavid E. O'Brien }
104c80476e4SDavid E. O'Brien
105c80476e4SDavid E. O'Brien char linbuf[2048]; /* was 128 */
106c80476e4SDavid E. O'Brien char *linp = linbuf;
10723338178SMark Peek int output_raw = 0; /* PWP */
10823338178SMark Peek int xlate_cr = 0; /* HE */
10923338178SMark Peek
11045e5710bSMark Peek /* For cleanup_push() */
11145e5710bSMark Peek void
output_raw_restore(void * xorig)11245e5710bSMark Peek output_raw_restore(void *xorig)
11345e5710bSMark Peek {
11445e5710bSMark Peek int *orig;
11545e5710bSMark Peek
11645e5710bSMark Peek orig = xorig;
11745e5710bSMark Peek output_raw = *orig;
11845e5710bSMark Peek }
11945e5710bSMark Peek
12023338178SMark Peek #ifdef WIDE_STRINGS
12123338178SMark Peek void
putwraw(Char c)12223338178SMark Peek putwraw(Char c)
12323338178SMark Peek {
12423338178SMark Peek char buf[MB_LEN_MAX];
12523338178SMark Peek size_t i, len;
12623338178SMark Peek
12723338178SMark Peek len = one_wctomb(buf, c & CHAR);
12823338178SMark Peek for (i = 0; i < len; i++)
12923338178SMark Peek putraw((unsigned char)buf[i] | (c & ~CHAR));
13023338178SMark Peek }
13123338178SMark Peek
13223338178SMark Peek void
xputwchar(Char c)13323338178SMark Peek xputwchar(Char c)
13423338178SMark Peek {
13523338178SMark Peek char buf[MB_LEN_MAX];
13623338178SMark Peek size_t i, len;
13723338178SMark Peek
13823338178SMark Peek len = one_wctomb(buf, c & CHAR);
13923338178SMark Peek for (i = 0; i < len; i++)
14023338178SMark Peek xputchar((unsigned char)buf[i] | (c & ~CHAR));
14123338178SMark Peek }
14223338178SMark Peek #endif
143c80476e4SDavid E. O'Brien
144c80476e4SDavid E. O'Brien void
xputchar(int c)14545e5710bSMark Peek xputchar(int c)
146c80476e4SDavid E. O'Brien {
14745e5710bSMark Peek int atr;
148c80476e4SDavid E. O'Brien
14945e5710bSMark Peek atr = c & ATTRIBUTES & TRIM;
150c80476e4SDavid E. O'Brien c &= CHAR | QUOTE;
151c80476e4SDavid E. O'Brien if (!output_raw && (c & QUOTE) == 0) {
15245e5710bSMark Peek if (iscntrl(c) && (ASC(c) < 0x80 || MB_CUR_MAX == 1)) {
15345e5710bSMark Peek if (c != '\t' && c != '\n'
154c80476e4SDavid E. O'Brien #ifdef COLORCAT
15545e5710bSMark Peek && !(adrof(STRcolorcat) && c == CTL_ESC('\033'))
156c80476e4SDavid E. O'Brien #endif
15745e5710bSMark Peek && (xlate_cr || c != '\r'))
15823338178SMark Peek {
159c80476e4SDavid E. O'Brien xputchar('^' | atr);
160c80476e4SDavid E. O'Brien if (c == CTL_ESC('\177'))
161c80476e4SDavid E. O'Brien c = '?';
162c80476e4SDavid E. O'Brien else
16345e5710bSMark Peek /* Note: for IS_ASCII, this compiles to: c = c | 0100 */
16445e5710bSMark Peek c = CTL_ESC(ASC(c)|0100);
165c80476e4SDavid E. O'Brien }
166c80476e4SDavid E. O'Brien }
16745e5710bSMark Peek else if (!isprint(c) && (ASC(c) < 0x80 || MB_CUR_MAX == 1)) {
168c80476e4SDavid E. O'Brien xputchar('\\' | atr);
169c80476e4SDavid E. O'Brien xputchar((((c >> 6) & 7) + '0') | atr);
170c80476e4SDavid E. O'Brien xputchar((((c >> 3) & 7) + '0') | atr);
171c80476e4SDavid E. O'Brien c = (c & 7) + '0';
172c80476e4SDavid E. O'Brien }
173c80476e4SDavid E. O'Brien (void) putraw(c | atr);
174c80476e4SDavid E. O'Brien }
175c80476e4SDavid E. O'Brien else {
176c80476e4SDavid E. O'Brien c &= TRIM;
177c80476e4SDavid E. O'Brien if (haderr ? (didfds ? is2atty : isdiagatty) :
178c80476e4SDavid E. O'Brien (didfds ? is1atty : isoutatty))
179c80476e4SDavid E. O'Brien SetAttributes(c | atr);
180c80476e4SDavid E. O'Brien (void) putpure(c);
181c80476e4SDavid E. O'Brien }
182c80476e4SDavid E. O'Brien if (lbuffed && (c & CHAR) == '\n')
183c80476e4SDavid E. O'Brien flush();
184c80476e4SDavid E. O'Brien }
185c80476e4SDavid E. O'Brien
186c80476e4SDavid E. O'Brien int
putraw(int c)18745e5710bSMark Peek putraw(int c)
188c80476e4SDavid E. O'Brien {
189c80476e4SDavid E. O'Brien if (haderr ? (didfds ? is2atty : isdiagatty) :
190c80476e4SDavid E. O'Brien (didfds ? is1atty : isoutatty)) {
191c80476e4SDavid E. O'Brien if (Tty_eight_bit == -1)
192c80476e4SDavid E. O'Brien ed_set_tty_eight_bit();
193c80476e4SDavid E. O'Brien if (!Tty_eight_bit && (c & META)) {
194c80476e4SDavid E. O'Brien c = (c & ~META) | STANDOUT;
195c80476e4SDavid E. O'Brien }
196c80476e4SDavid E. O'Brien SetAttributes(c);
197c80476e4SDavid E. O'Brien }
198c80476e4SDavid E. O'Brien return putpure(c);
199c80476e4SDavid E. O'Brien }
200c80476e4SDavid E. O'Brien
201c80476e4SDavid E. O'Brien int
putpure(int c)20245e5710bSMark Peek putpure(int c)
203c80476e4SDavid E. O'Brien {
204c80476e4SDavid E. O'Brien c &= CHAR;
205c80476e4SDavid E. O'Brien
206c80476e4SDavid E. O'Brien *linp++ = (char) c;
207c80476e4SDavid E. O'Brien if (linp >= &linbuf[sizeof linbuf - 10])
208c80476e4SDavid E. O'Brien flush();
209c80476e4SDavid E. O'Brien return (1);
210c80476e4SDavid E. O'Brien }
211c80476e4SDavid E. O'Brien
212c80476e4SDavid E. O'Brien void
drainoline(void)21345e5710bSMark Peek drainoline(void)
214c80476e4SDavid E. O'Brien {
215c80476e4SDavid E. O'Brien linp = linbuf;
216c80476e4SDavid E. O'Brien }
217c80476e4SDavid E. O'Brien
218c80476e4SDavid E. O'Brien void
flush(void)21945e5710bSMark Peek flush(void)
220c80476e4SDavid E. O'Brien {
2219ccc37e3SMark Peek int unit, oldexitset = exitset;
222c80476e4SDavid E. O'Brien static int interrupted = 0;
223c80476e4SDavid E. O'Brien
224c80476e4SDavid E. O'Brien /* int lmode; */
225c80476e4SDavid E. O'Brien
226c80476e4SDavid E. O'Brien if (linp == linbuf)
227c80476e4SDavid E. O'Brien return;
228c80476e4SDavid E. O'Brien if (GettingInput && !Tty_raw_mode && linp < &linbuf[sizeof linbuf - 10])
229c80476e4SDavid E. O'Brien return;
230*19d2e3deSDmitry Chagin if (handle_interrupt)
2319ccc37e3SMark Peek exitset = 1;
2329ccc37e3SMark Peek
233c80476e4SDavid E. O'Brien if (interrupted) {
234c80476e4SDavid E. O'Brien interrupted = 0;
23545e5710bSMark Peek linp = linbuf; /* avoid recursion as stderror calls flush */
236*19d2e3deSDmitry Chagin if (handle_interrupt)
2379ccc37e3SMark Peek fixerror();
2389ccc37e3SMark Peek else
239c80476e4SDavid E. O'Brien stderror(ERR_SILENT);
240c80476e4SDavid E. O'Brien }
241c80476e4SDavid E. O'Brien interrupted = 1;
242c80476e4SDavid E. O'Brien if (haderr)
243c80476e4SDavid E. O'Brien unit = didfds ? 2 : SHDIAG;
244c80476e4SDavid E. O'Brien else
245c80476e4SDavid E. O'Brien unit = didfds ? 1 : SHOUT;
246c80476e4SDavid E. O'Brien #ifdef COMMENT
247c80476e4SDavid E. O'Brien #ifdef TIOCLGET
248c80476e4SDavid E. O'Brien if (didfds == 0 && ioctl(unit, TIOCLGET, (ioctl_t) & lmode) == 0 &&
249c80476e4SDavid E. O'Brien lmode & LFLUSHO) {
250c80476e4SDavid E. O'Brien lmode = LFLUSHO;
251c80476e4SDavid E. O'Brien (void) ioctl(unit, TIOCLBIC, (ioclt_t) & lmode);
25245e5710bSMark Peek (void) xwrite(unit, "\n", 1);
253c80476e4SDavid E. O'Brien }
254c80476e4SDavid E. O'Brien #endif
255c80476e4SDavid E. O'Brien #endif
25645e5710bSMark Peek if (xwrite(unit, linbuf, linp - linbuf) == -1)
257c80476e4SDavid E. O'Brien switch (errno) {
258c80476e4SDavid E. O'Brien #ifdef EIO
259c80476e4SDavid E. O'Brien /* We lost our tty */
260c80476e4SDavid E. O'Brien case EIO:
261c80476e4SDavid E. O'Brien #endif
262c80476e4SDavid E. O'Brien #ifdef ENXIO
263c80476e4SDavid E. O'Brien /*
264c80476e4SDavid E. O'Brien * Deal with Digital Unix 4.0D bogocity, returning ENXIO when
265c80476e4SDavid E. O'Brien * we lose our tty.
266c80476e4SDavid E. O'Brien */
267c80476e4SDavid E. O'Brien case ENXIO:
268c80476e4SDavid E. O'Brien #endif
269c80476e4SDavid E. O'Brien /*
270c80476e4SDavid E. O'Brien * IRIX 6.4 bogocity?
271c80476e4SDavid E. O'Brien */
272c80476e4SDavid E. O'Brien #ifdef ENOTTY
273c80476e4SDavid E. O'Brien case ENOTTY:
274c80476e4SDavid E. O'Brien #endif
275c80476e4SDavid E. O'Brien #ifdef EBADF
276c80476e4SDavid E. O'Brien case EBADF:
277c80476e4SDavid E. O'Brien #endif
2788e66bd9eSDavid E. O'Brien #ifdef ESTALE
2798e66bd9eSDavid E. O'Brien /*
2808e66bd9eSDavid E. O'Brien * Lost our file descriptor, exit (IRIS4D)
2818e66bd9eSDavid E. O'Brien */
2828e66bd9eSDavid E. O'Brien case ESTALE:
2838e66bd9eSDavid E. O'Brien #endif
2849ccc37e3SMark Peek #ifdef ENOENT
2859ccc37e3SMark Peek /*
2869ccc37e3SMark Peek * Deal with SoFS bogocity: returns ENOENT instead of ESTALE.
2879ccc37e3SMark Peek */
2889ccc37e3SMark Peek case ENOENT:
2899ccc37e3SMark Peek #endif
290c80476e4SDavid E. O'Brien /*
291c80476e4SDavid E. O'Brien * Over our quota, writing the history file
292c80476e4SDavid E. O'Brien */
293c80476e4SDavid E. O'Brien #ifdef EDQUOT
294c80476e4SDavid E. O'Brien case EDQUOT:
295c80476e4SDavid E. O'Brien #endif
296c80476e4SDavid E. O'Brien /* Nothing to do, but die */
297*19d2e3deSDmitry Chagin if (handle_interrupt == 0)
298c80476e4SDavid E. O'Brien xexit(1);
2999ccc37e3SMark Peek /*FALLTHROUGH*/
300c80476e4SDavid E. O'Brien default:
301*19d2e3deSDmitry Chagin if (handle_interrupt)
3029ccc37e3SMark Peek fixerror();
3039ccc37e3SMark Peek else
304c80476e4SDavid E. O'Brien stderror(ERR_SILENT);
305c80476e4SDavid E. O'Brien break;
306c80476e4SDavid E. O'Brien }
307c80476e4SDavid E. O'Brien
3089ccc37e3SMark Peek exitset = oldexitset;
309c80476e4SDavid E. O'Brien linp = linbuf;
310c80476e4SDavid E. O'Brien interrupted = 0;
311c80476e4SDavid E. O'Brien }
312