1231990Smp/* $Header: /p/tcsh/cvsroot/tcsh/sh.print.c,v 3.36 2011/05/25 20:17:20 christos Exp $ */ 259243Sobrien/* 359243Sobrien * sh.print.c: Primitive Output routines. 459243Sobrien */ 559243Sobrien/*- 659243Sobrien * Copyright (c) 1980, 1991 The Regents of the University of California. 759243Sobrien * All rights reserved. 859243Sobrien * 959243Sobrien * Redistribution and use in source and binary forms, with or without 1059243Sobrien * modification, are permitted provided that the following conditions 1159243Sobrien * are met: 1259243Sobrien * 1. Redistributions of source code must retain the above copyright 1359243Sobrien * notice, this list of conditions and the following disclaimer. 1459243Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1559243Sobrien * notice, this list of conditions and the following disclaimer in the 1659243Sobrien * documentation and/or other materials provided with the distribution. 17100616Smp * 3. Neither the name of the University nor the names of its contributors 1859243Sobrien * may be used to endorse or promote products derived from this software 1959243Sobrien * without specific prior written permission. 2059243Sobrien * 2159243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2259243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2359243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2459243Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2559243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2659243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2759243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2859243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2959243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3059243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3159243Sobrien * SUCH DAMAGE. 3259243Sobrien */ 3359243Sobrien#include "sh.h" 3459243Sobrien 35231990SmpRCSID("$tcsh: sh.print.c,v 3.36 2011/05/25 20:17:20 christos Exp $") 3659243Sobrien 3759243Sobrien#include "ed.h" 3859243Sobrien 3959243Sobrienextern int Tty_eight_bit; 4059243Sobrien 4159243Sobrienint lbuffed = 1; /* true if line buffered */ 4259243Sobrien 43167465Smpstatic void p2dig (unsigned int); 4459243Sobrien 4559243Sobrien/* 4659243Sobrien * C Shell 4759243Sobrien */ 4859243Sobrien 4959243Sobrien#if defined(BSDLIMIT) || defined(RLIMIT_CPU) 5059243Sobrienvoid 51167465Smppsecs(unsigned long l) 5259243Sobrien{ 53145479Smp int i; 5459243Sobrien 5559243Sobrien i = (int) (l / 3600); 5659243Sobrien if (i) { 5759243Sobrien xprintf("%d:", i); 5859243Sobrien i = (int) (l % 3600); 5959243Sobrien p2dig(i / 60); 6059243Sobrien goto minsec; 6159243Sobrien } 6259243Sobrien i = (int) l; 6359243Sobrien xprintf("%d", i / 60); 6459243Sobrienminsec: 6559243Sobrien i %= 60; 6659243Sobrien xprintf(":"); 6759243Sobrien p2dig(i); 6859243Sobrien} 6959243Sobrien 7059243Sobrien#endif 7159243Sobrien 72167465Smpvoid /* PWP: print mm:ss.dd, l is in sec*100 */ 7359243Sobrien#ifdef BSDTIMES 74167465Smppcsecs(unsigned long l) 7559243Sobrien#else /* BSDTIMES */ 7659243Sobrien# ifndef POSIX 77167465Smppcsecs(time_t l) 7859243Sobrien# else /* POSIX */ 79167465Smppcsecs(clock_t l) 8059243Sobrien# endif /* POSIX */ 8159243Sobrien#endif /* BSDTIMES */ 8259243Sobrien{ 83145479Smp int i; 8459243Sobrien 8559243Sobrien i = (int) (l / 360000); 8659243Sobrien if (i) { 8759243Sobrien xprintf("%d:", i); 8859243Sobrien i = (int) ((l % 360000) / 100); 8959243Sobrien p2dig(i / 60); 9059243Sobrien goto minsec; 9159243Sobrien } 9259243Sobrien i = (int) (l / 100); 9359243Sobrien xprintf("%d", i / 60); 9459243Sobrienminsec: 9559243Sobrien i %= 60; 9659243Sobrien xprintf(":"); 9759243Sobrien p2dig(i); 9859243Sobrien xprintf("."); 9959243Sobrien p2dig((int) (l % 100)); 10059243Sobrien} 10159243Sobrien 10259243Sobrienstatic void 103167465Smpp2dig(unsigned i) 10459243Sobrien{ 10559243Sobrien 106145479Smp xprintf("%u%u", i / 10, i % 10); 10759243Sobrien} 10859243Sobrien 10959243Sobrienchar linbuf[2048]; /* was 128 */ 11059243Sobrienchar *linp = linbuf; 111145479Smpint output_raw = 0; /* PWP */ 112145479Smpint xlate_cr = 0; /* HE */ 11359243Sobrien 114167465Smp/* For cleanup_push() */ 115167465Smpvoid 116167465Smpoutput_raw_restore(void *xorig) 117167465Smp{ 118167465Smp int *orig; 119167465Smp 120167465Smp orig = xorig; 121167465Smp output_raw = *orig; 122167465Smp} 123167465Smp 124145479Smp#ifdef WIDE_STRINGS 12559243Sobrienvoid 126145479Smpputwraw(Char c) 127145479Smp{ 128145479Smp char buf[MB_LEN_MAX]; 129145479Smp size_t i, len; 130145479Smp 131145479Smp len = one_wctomb(buf, c & CHAR); 132145479Smp for (i = 0; i < len; i++) 133145479Smp putraw((unsigned char)buf[i] | (c & ~CHAR)); 134145479Smp} 135145479Smp 136145479Smpvoid 137145479Smpxputwchar(Char c) 138145479Smp{ 139145479Smp char buf[MB_LEN_MAX]; 140145479Smp size_t i, len; 141145479Smp 142145479Smp len = one_wctomb(buf, c & CHAR); 143145479Smp for (i = 0; i < len; i++) 144145479Smp xputchar((unsigned char)buf[i] | (c & ~CHAR)); 145145479Smp} 146145479Smp#endif 147145479Smp 148145479Smpvoid 149167465Smpxputchar(int c) 15059243Sobrien{ 151167465Smp int atr; 15259243Sobrien 153167465Smp atr = c & ATTRIBUTES & TRIM; 15459243Sobrien c &= CHAR | QUOTE; 15559243Sobrien if (!output_raw && (c & QUOTE) == 0) { 156167465Smp if (iscntrl(c) && (ASC(c) < 0x80 || MB_CUR_MAX == 1)) { 157167465Smp if (c != '\t' && c != '\n' 15859243Sobrien#ifdef COLORCAT 159167465Smp && !(adrof(STRcolorcat) && c == CTL_ESC('\033')) 16059243Sobrien#endif 161167465Smp && (xlate_cr || c != '\r')) 162145479Smp { 16359243Sobrien xputchar('^' | atr); 16459243Sobrien if (c == CTL_ESC('\177')) 16559243Sobrien c = '?'; 16659243Sobrien else 167167465Smp /* Note: for IS_ASCII, this compiles to: c = c | 0100 */ 168167465Smp c = CTL_ESC(ASC(c)|0100); 16959243Sobrien } 17059243Sobrien } 171167465Smp else if (!isprint(c) && (ASC(c) < 0x80 || MB_CUR_MAX == 1)) { 17259243Sobrien xputchar('\\' | atr); 17359243Sobrien xputchar((((c >> 6) & 7) + '0') | atr); 17459243Sobrien xputchar((((c >> 3) & 7) + '0') | atr); 17559243Sobrien c = (c & 7) + '0'; 17659243Sobrien } 17759243Sobrien (void) putraw(c | atr); 17859243Sobrien } 17959243Sobrien else { 18059243Sobrien c &= TRIM; 18159243Sobrien if (haderr ? (didfds ? is2atty : isdiagatty) : 18259243Sobrien (didfds ? is1atty : isoutatty)) 18359243Sobrien SetAttributes(c | atr); 18459243Sobrien (void) putpure(c); 18559243Sobrien } 18659243Sobrien if (lbuffed && (c & CHAR) == '\n') 18759243Sobrien flush(); 18859243Sobrien} 18959243Sobrien 19059243Sobrienint 191167465Smpputraw(int c) 19259243Sobrien{ 19359243Sobrien if (haderr ? (didfds ? is2atty : isdiagatty) : 19459243Sobrien (didfds ? is1atty : isoutatty)) { 19559243Sobrien if (Tty_eight_bit == -1) 19659243Sobrien ed_set_tty_eight_bit(); 19759243Sobrien if (!Tty_eight_bit && (c & META)) { 19859243Sobrien c = (c & ~META) | STANDOUT; 19959243Sobrien } 20059243Sobrien SetAttributes(c); 20159243Sobrien } 20259243Sobrien return putpure(c); 20359243Sobrien} 20459243Sobrien 20559243Sobrienint 206167465Smpputpure(int c) 20759243Sobrien{ 20859243Sobrien c &= CHAR; 20959243Sobrien 21059243Sobrien *linp++ = (char) c; 21159243Sobrien if (linp >= &linbuf[sizeof linbuf - 10]) 21259243Sobrien flush(); 21359243Sobrien return (1); 21459243Sobrien} 21559243Sobrien 21659243Sobrienvoid 217167465Smpdrainoline(void) 21859243Sobrien{ 21959243Sobrien linp = linbuf; 22059243Sobrien} 22159243Sobrien 22259243Sobrienvoid 223167465Smpflush(void) 22459243Sobrien{ 225231990Smp int unit, oldexitset = exitset; 22659243Sobrien static int interrupted = 0; 22759243Sobrien 22859243Sobrien /* int lmode; */ 22959243Sobrien 23059243Sobrien if (linp == linbuf) 23159243Sobrien return; 23259243Sobrien if (GettingInput && !Tty_raw_mode && linp < &linbuf[sizeof linbuf - 10]) 23359243Sobrien return; 234231990Smp if (handle_intr) 235231990Smp exitset = 1; 236231990Smp 23759243Sobrien if (interrupted) { 23859243Sobrien interrupted = 0; 239167465Smp linp = linbuf; /* avoid recursion as stderror calls flush */ 240231990Smp if (handle_intr) 241231990Smp fixerror(); 242231990Smp else 243231990Smp stderror(ERR_SILENT); 24459243Sobrien } 24559243Sobrien interrupted = 1; 24659243Sobrien if (haderr) 24759243Sobrien unit = didfds ? 2 : SHDIAG; 24859243Sobrien else 24959243Sobrien unit = didfds ? 1 : SHOUT; 25059243Sobrien#ifdef COMMENT 25159243Sobrien#ifdef TIOCLGET 25259243Sobrien if (didfds == 0 && ioctl(unit, TIOCLGET, (ioctl_t) & lmode) == 0 && 25359243Sobrien lmode & LFLUSHO) { 25459243Sobrien lmode = LFLUSHO; 25559243Sobrien (void) ioctl(unit, TIOCLBIC, (ioclt_t) & lmode); 256167465Smp (void) xwrite(unit, "\n", 1); 25759243Sobrien } 25859243Sobrien#endif 25959243Sobrien#endif 260167465Smp if (xwrite(unit, linbuf, linp - linbuf) == -1) 26159243Sobrien switch (errno) { 26259243Sobrien#ifdef EIO 26359243Sobrien /* We lost our tty */ 26459243Sobrien case EIO: 26559243Sobrien#endif 26659243Sobrien#ifdef ENXIO 26759243Sobrien /* 26859243Sobrien * Deal with Digital Unix 4.0D bogocity, returning ENXIO when 26959243Sobrien * we lose our tty. 27059243Sobrien */ 27159243Sobrien case ENXIO: 27259243Sobrien#endif 27359243Sobrien /* 27459243Sobrien * IRIX 6.4 bogocity? 27559243Sobrien */ 27659243Sobrien#ifdef ENOTTY 27759243Sobrien case ENOTTY: 27859243Sobrien#endif 27959243Sobrien#ifdef EBADF 28059243Sobrien case EBADF: 28159243Sobrien#endif 28259415Sobrien#ifdef ESTALE 28359243Sobrien /* 28459415Sobrien * Lost our file descriptor, exit (IRIS4D) 28559415Sobrien */ 28659415Sobrien case ESTALE: 28759415Sobrien#endif 288231990Smp#ifdef ENOENT 28959415Sobrien /* 290231990Smp * Deal with SoFS bogocity: returns ENOENT instead of ESTALE. 291231990Smp */ 292231990Smp case ENOENT: 293231990Smp#endif 294231990Smp /* 29559243Sobrien * Over our quota, writing the history file 29659243Sobrien */ 29759243Sobrien#ifdef EDQUOT 29859243Sobrien case EDQUOT: 29959243Sobrien#endif 30059243Sobrien /* Nothing to do, but die */ 301231990Smp if (handle_intr == 0) 302231990Smp xexit(1); 303231990Smp /*FALLTHROUGH*/ 30459243Sobrien default: 305231990Smp if (handle_intr) 306231990Smp fixerror(); 307231990Smp else 308231990Smp stderror(ERR_SILENT); 30959243Sobrien break; 31059243Sobrien } 31159243Sobrien 312231990Smp exitset = oldexitset; 31359243Sobrien linp = linbuf; 31459243Sobrien interrupted = 0; 31559243Sobrien} 316