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 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 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 70 p2dig_ull(unsigned long long i) 71 { 72 printf("%llu%llu", i / 10, i % 10); 73 } 74 75 void 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 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 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 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 173 Putchar(tchar tc) 174 { 175 putbyte((int)tc); 176 } 177 178 #endif /* !MBCHAR */ 179 180 void 181 draino(void) 182 { 183 linp = linbuf; 184 } 185 186 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 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