1 /*
2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
8
9 /*
10 * Copyright (c) 1980 Regents of the University of California.
11 * All rights reserved. The Berkeley Software License Agreement
12 * specifies the terms and conditions for redistribution.
13 */
14
15 #pragma ident "%Z%%M% %I% %E% SMI"
16
17 #include "sh.h"
18
19 void p2dig_ull(unsigned long long);
20 void p2dig_int(int);
21 void flush(void);
22 void Putchar(tchar);
23
24
25 /*
26 * C Shell
27 */
28
29 void
psecs_ull(unsigned long long l)30 psecs_ull(unsigned long long l)
31 {
32 unsigned long long i;
33
34 i = l / 3600;
35 if (i) {
36 printf("%llu:", i);
37 i = l % 3600;
38 p2dig_ull(i / 60);
39 goto minsec;
40 }
41 i = l;
42 printf("%llu", i / 60);
43 minsec:
44 i %= 60;
45 printf(":");
46 p2dig_ull(i);
47 }
48
49 void
psecs_int(int l)50 psecs_int(int l)
51 {
52 int i;
53
54 i = l / 3600;
55 if (i) {
56 printf("%d:", i);
57 i = l % 3600;
58 p2dig_int(i / 60);
59 goto minsec;
60 }
61 i = l;
62 printf("%d", i / 60);
63 minsec:
64 i %= 60;
65 printf(":");
66 p2dig_int(i);
67 }
68
69 void
p2dig_ull(unsigned long long i)70 p2dig_ull(unsigned long long i)
71 {
72 printf("%llu%llu", i / 10, i % 10);
73 }
74
75 void
p2dig_int(int i)76 p2dig_int(int i)
77 {
78 printf("%d%d", i / 10, i % 10);
79 }
80
81 char linbuf[128];
82 char *linp = linbuf;
83
84 #ifdef MBCHAR
85
86 /*
87 * putbyte() send a byte to SHOUT. No interpretation is done
88 * except an un-QUOTE'd control character, which is displayed
89 * as ^x.
90 */
91 void
putbyte(int c)92 putbyte(int c)
93 {
94
95 if ((c & QUOTE) == 0 && (c == 0177 || c < ' ' && c != '\t' &&
96 c != '\n')) {
97 putbyte('^');
98 if (c == 0177) {
99 c = '?';
100 } else {
101 c |= 'A' - 1;
102 }
103 }
104 c &= TRIM;
105 *linp++ = c;
106
107 if (c == '\n' || linp >= &linbuf[sizeof (linbuf) - 1 - MB_CUR_MAX]) {
108 /* 'cause the next Putchar() call may overflow the buffer. */
109 flush();
110 }
111 }
112
113 /*
114 * Putchar(tc) does what putbyte(c) do for a byte c.
115 * Note that putbyte(c) just send the byte c (provided c is not
116 * a control character) as it is, while Putchar(tc) may expand the
117 * character tc to some byte sequnce that represents the character
118 * in EUC form.
119 */
120 void
Putchar(tchar tc)121 Putchar(tchar tc)
122 {
123 int n;
124
125 if (isascii(tc&TRIM)) {
126 putbyte((int)tc);
127 return;
128 }
129 tc &= TRIM;
130 n = wctomb(linp, tc);
131 if (n == -1) {
132 return;
133 }
134 linp += n;
135 if (linp >= &linbuf[sizeof (linbuf) - 1 - MB_CUR_MAX]) {
136 flush();
137 }
138 }
139
140 #else /* !MBCHAR */
141
142 /*
143 * putbyte() send a byte to SHOUT. No interpretation is done
144 * except an un-QUOTE'd control character, which is displayed
145 * as ^x.
146 */
147 void
putbyte(int c)148 putbyte(int c)
149 {
150
151 if ((c & QUOTE) == 0 && (c == 0177 || c < ' ' && c != '\t' &&
152 c != '\n')) {
153 putbyte('^');
154 if (c == 0177) {
155 c = '?';
156 } else {
157 c |= 'A' - 1;
158 }
159 }
160 c &= TRIM;
161 *linp++ = c;
162 if (c == '\n' || linp >= &linbuf[sizeof (linbuf) - 2]) {
163 flush();
164 }
165 }
166
167 /*
168 * Putchar(tc) does what putbyte(c) do for a byte c.
169 * For single-byte character only environment, there is no
170 * difference between Putchar() and putbyte() though.
171 */
172 void
Putchar(tchar tc)173 Putchar(tchar tc)
174 {
175 putbyte((int)tc);
176 }
177
178 #endif /* !MBCHAR */
179
180 void
draino(void)181 draino(void)
182 {
183 linp = linbuf;
184 }
185
186 void
flush(void)187 flush(void)
188 {
189 int unit;
190 int lmode;
191
192 if (linp == linbuf) {
193 return;
194 }
195 if (haderr) {
196 unit = didfds ? 2 : SHDIAG;
197 } else {
198 unit = didfds ? 1 : SHOUT;
199 }
200 #ifdef TIOCLGET
201 if (didfds == 0 && ioctl(unit, TIOCLGET, (char *)&lmode) == 0 &&
202 lmode&LFLUSHO) {
203 lmode = LFLUSHO;
204 (void) ioctl(unit, TIOCLBIC, (char *)&lmode);
205 (void) write(unit, "\n", 1);
206 }
207 #endif
208 (void) write(unit, linbuf, linp - linbuf);
209 linp = linbuf;
210 }
211
212 /*
213 * Should not be needed.
214 */
215 void
write_string(char * s)216 write_string(char *s)
217 {
218 int unit;
219 /*
220 * First let's make it sure to flush out things.
221 */
222 flush();
223
224 if (haderr) {
225 unit = didfds ? 2 : SHDIAG;
226 } else {
227 unit = didfds ? 1 : SHOUT;
228 }
229
230 (void) write(unit, s, strlen(s));
231 }
232