1 /* $Header: /src/pub/tcsh/sh.print.c,v 3.21 2002/03/08 17:36:46 christos Exp $ */ 2 /* 3 * sh.print.c: Primitive Output routines. 4 */ 5 /*- 6 * Copyright (c) 1980, 1991 The Regents of the University of California. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 #include "sh.h" 34 35 RCSID("$Id: sh.print.c,v 3.21 2002/03/08 17:36:46 christos Exp $") 36 37 #include "ed.h" 38 39 extern int Tty_eight_bit; 40 extern int Tty_raw_mode; 41 extern Char GettingInput; 42 43 int lbuffed = 1; /* true if line buffered */ 44 45 static void p2dig __P((int)); 46 47 /* 48 * C Shell 49 */ 50 51 #if defined(BSDLIMIT) || defined(RLIMIT_CPU) 52 void 53 psecs(l) 54 long l; 55 { 56 register int i; 57 58 i = (int) (l / 3600); 59 if (i) { 60 xprintf("%d:", i); 61 i = (int) (l % 3600); 62 p2dig(i / 60); 63 goto minsec; 64 } 65 i = (int) l; 66 xprintf("%d", i / 60); 67 minsec: 68 i %= 60; 69 xprintf(":"); 70 p2dig(i); 71 } 72 73 #endif 74 75 void 76 pcsecs(l) /* PWP: print mm:ss.dd, l is in sec*100 */ 77 #ifdef BSDTIMES 78 long l; 79 #else /* BSDTIMES */ 80 # ifndef POSIX 81 time_t l; 82 # else /* POSIX */ 83 clock_t l; 84 # endif /* POSIX */ 85 #endif /* BSDTIMES */ 86 { 87 register int i; 88 89 i = (int) (l / 360000); 90 if (i) { 91 xprintf("%d:", i); 92 i = (int) ((l % 360000) / 100); 93 p2dig(i / 60); 94 goto minsec; 95 } 96 i = (int) (l / 100); 97 xprintf("%d", i / 60); 98 minsec: 99 i %= 60; 100 xprintf(":"); 101 p2dig(i); 102 xprintf("."); 103 p2dig((int) (l % 100)); 104 } 105 106 static void 107 p2dig(i) 108 register int i; 109 { 110 111 xprintf("%d%d", i / 10, i % 10); 112 } 113 114 char linbuf[2048]; /* was 128 */ 115 char *linp = linbuf; 116 bool output_raw = 0; /* PWP */ 117 bool xlate_cr = 0; /* HE */ 118 119 void 120 xputchar(c) 121 register int c; 122 { 123 int atr = 0; 124 125 atr |= c & ATTRIBUTES & TRIM; 126 c &= CHAR | QUOTE; 127 if (!output_raw && (c & QUOTE) == 0) { 128 if (Iscntrl(c)) { 129 #ifdef COLORCAT 130 if (c != '\t' && c != '\n' && !(adrof(STRcolorcat) && c=='\033') && (xlate_cr || c != '\r')) { 131 #else 132 if (c != '\t' && c != '\n' && (xlate_cr || c != '\r')) { 133 #endif 134 xputchar('^' | atr); 135 #ifdef IS_ASCII 136 if (c == ASCII) 137 c = '?'; 138 else 139 c |= 0100; 140 #else 141 if (c == CTL_ESC('\177')) 142 c = '?'; 143 else 144 c =_toebcdic[_toascii[c]|0100]; 145 #endif 146 147 } 148 } 149 else if (!Isprint(c)) { 150 xputchar('\\' | atr); 151 xputchar((((c >> 6) & 7) + '0') | atr); 152 xputchar((((c >> 3) & 7) + '0') | atr); 153 c = (c & 7) + '0'; 154 } 155 (void) putraw(c | atr); 156 } 157 else { 158 c &= TRIM; 159 if (haderr ? (didfds ? is2atty : isdiagatty) : 160 (didfds ? is1atty : isoutatty)) 161 SetAttributes(c | atr); 162 (void) putpure(c); 163 } 164 if (lbuffed && (c & CHAR) == '\n') 165 flush(); 166 } 167 168 int 169 putraw(c) 170 register int c; 171 { 172 if (haderr ? (didfds ? is2atty : isdiagatty) : 173 (didfds ? is1atty : isoutatty)) { 174 if (Tty_eight_bit == -1) 175 ed_set_tty_eight_bit(); 176 if (!Tty_eight_bit && (c & META)) { 177 c = (c & ~META) | STANDOUT; 178 } 179 SetAttributes(c); 180 } 181 return putpure(c); 182 } 183 184 int 185 putpure(c) 186 register int c; 187 { 188 c &= CHAR; 189 190 *linp++ = (char) c; 191 if (linp >= &linbuf[sizeof linbuf - 10]) 192 flush(); 193 return (1); 194 } 195 196 void 197 drainoline() 198 { 199 linp = linbuf; 200 } 201 202 void 203 flush() 204 { 205 int unit; 206 static int interrupted = 0; 207 size_t sz; 208 209 /* int lmode; */ 210 211 if (linp == linbuf) 212 return; 213 if (GettingInput && !Tty_raw_mode && linp < &linbuf[sizeof linbuf - 10]) 214 return; 215 if (interrupted) { 216 interrupted = 0; 217 linp = linbuf; /* avoid resursion as stderror calls flush */ 218 stderror(ERR_SILENT); 219 } 220 interrupted = 1; 221 if (haderr) 222 unit = didfds ? 2 : SHDIAG; 223 else 224 unit = didfds ? 1 : SHOUT; 225 #ifdef COMMENT 226 #ifdef TIOCLGET 227 if (didfds == 0 && ioctl(unit, TIOCLGET, (ioctl_t) & lmode) == 0 && 228 lmode & LFLUSHO) { 229 lmode = LFLUSHO; 230 (void) ioctl(unit, TIOCLBIC, (ioclt_t) & lmode); 231 (void) write(unit, "\n", 1); 232 } 233 #endif 234 #endif 235 sz = (size_t) (linp - linbuf); 236 if (write(unit, linbuf, sz) == -1) 237 switch (errno) { 238 #ifdef EIO 239 /* We lost our tty */ 240 case EIO: 241 #endif 242 #ifdef ENXIO 243 /* 244 * Deal with Digital Unix 4.0D bogocity, returning ENXIO when 245 * we lose our tty. 246 */ 247 case ENXIO: 248 #endif 249 /* 250 * IRIX 6.4 bogocity? 251 */ 252 #ifdef ENOTTY 253 case ENOTTY: 254 #endif 255 #ifdef EBADF 256 case EBADF: 257 #endif 258 #ifdef ESTALE 259 /* 260 * Lost our file descriptor, exit (IRIS4D) 261 */ 262 case ESTALE: 263 #endif 264 /* 265 * Over our quota, writing the history file 266 */ 267 #ifdef EDQUOT 268 case EDQUOT: 269 #endif 270 /* Nothing to do, but die */ 271 xexit(1); 272 break; 273 default: 274 stderror(ERR_SILENT); 275 break; 276 } 277 278 linp = linbuf; 279 interrupted = 0; 280 } 281