sh.print.c revision 100616
1100616Smp/* $Header: /src/pub/tcsh/sh.print.c,v 3.21 2002/03/08 17:36:46 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
35100616SmpRCSID("$Id: sh.print.c,v 3.21 2002/03/08 17:36:46 christos Exp $")
3659243Sobrien
3759243Sobrien#include "ed.h"
3859243Sobrien
3959243Sobrienextern int Tty_eight_bit;
4059243Sobrienextern int Tty_raw_mode;
4159243Sobrienextern Char GettingInput;
4259243Sobrien
4359243Sobrienint     lbuffed = 1;		/* true if line buffered */
4459243Sobrien
4559243Sobrienstatic	void	p2dig	__P((int));
4659243Sobrien
4759243Sobrien/*
4859243Sobrien * C Shell
4959243Sobrien */
5059243Sobrien
5159243Sobrien#if defined(BSDLIMIT) || defined(RLIMIT_CPU)
5259243Sobrienvoid
5359243Sobrienpsecs(l)
5459243Sobrien    long    l;
5559243Sobrien{
5659243Sobrien    register int i;
5759243Sobrien
5859243Sobrien    i = (int) (l / 3600);
5959243Sobrien    if (i) {
6059243Sobrien	xprintf("%d:", i);
6159243Sobrien	i = (int) (l % 3600);
6259243Sobrien	p2dig(i / 60);
6359243Sobrien	goto minsec;
6459243Sobrien    }
6559243Sobrien    i = (int) l;
6659243Sobrien    xprintf("%d", i / 60);
6759243Sobrienminsec:
6859243Sobrien    i %= 60;
6959243Sobrien    xprintf(":");
7059243Sobrien    p2dig(i);
7159243Sobrien}
7259243Sobrien
7359243Sobrien#endif
7459243Sobrien
7559243Sobrienvoid
7659243Sobrienpcsecs(l)			/* PWP: print mm:ss.dd, l is in sec*100 */
7759243Sobrien#ifdef BSDTIMES
7859243Sobrien    long    l;
7959243Sobrien#else /* BSDTIMES */
8059243Sobrien# ifndef POSIX
8159243Sobrien    time_t  l;
8259243Sobrien# else /* POSIX */
8359243Sobrien    clock_t l;
8459243Sobrien# endif /* POSIX */
8559243Sobrien#endif /* BSDTIMES */
8659243Sobrien{
8759243Sobrien    register int i;
8859243Sobrien
8959243Sobrien    i = (int) (l / 360000);
9059243Sobrien    if (i) {
9159243Sobrien	xprintf("%d:", i);
9259243Sobrien	i = (int) ((l % 360000) / 100);
9359243Sobrien	p2dig(i / 60);
9459243Sobrien	goto minsec;
9559243Sobrien    }
9659243Sobrien    i = (int) (l / 100);
9759243Sobrien    xprintf("%d", i / 60);
9859243Sobrienminsec:
9959243Sobrien    i %= 60;
10059243Sobrien    xprintf(":");
10159243Sobrien    p2dig(i);
10259243Sobrien    xprintf(".");
10359243Sobrien    p2dig((int) (l % 100));
10459243Sobrien}
10559243Sobrien
10659243Sobrienstatic void
10759243Sobrienp2dig(i)
10859243Sobrien    register int i;
10959243Sobrien{
11059243Sobrien
11159243Sobrien    xprintf("%d%d", i / 10, i % 10);
11259243Sobrien}
11359243Sobrien
11459243Sobrienchar    linbuf[2048];		/* was 128 */
11559243Sobrienchar   *linp = linbuf;
11659243Sobrienbool    output_raw = 0;		/* PWP */
11759243Sobrienbool    xlate_cr   = 0;		/* HE */
11859243Sobrien
11959243Sobrienvoid
12059243Sobrienxputchar(c)
12159243Sobrien    register int c;
12259243Sobrien{
12359243Sobrien    int     atr = 0;
12459243Sobrien
12559243Sobrien    atr |= c & ATTRIBUTES & TRIM;
12659243Sobrien    c &= CHAR | QUOTE;
12759243Sobrien    if (!output_raw && (c & QUOTE) == 0) {
12859243Sobrien	if (Iscntrl(c)) {
12959243Sobrien#ifdef COLORCAT
13059243Sobrien	    if (c != '\t' && c != '\n' && !(adrof(STRcolorcat) && c=='\033') && (xlate_cr || c != '\r')) {
13159243Sobrien#else
13259243Sobrien	    if (c != '\t' && c != '\n' && (xlate_cr || c != '\r')) {
13359243Sobrien#endif
13459243Sobrien		xputchar('^' | atr);
13569408Sache#ifdef IS_ASCII
13659243Sobrien		if (c == ASCII)
13759243Sobrien		    c = '?';
13859243Sobrien		else
13959243Sobrien		    c |= 0100;
14069408Sache#else
14159243Sobrien		if (c == CTL_ESC('\177'))
14259243Sobrien		    c = '?';
14359243Sobrien		else
14459243Sobrien		    c =_toebcdic[_toascii[c]|0100];
14569408Sache#endif
14659243Sobrien
14759243Sobrien	    }
14859243Sobrien	}
14959243Sobrien	else if (!Isprint(c)) {
15059243Sobrien	    xputchar('\\' | atr);
15159243Sobrien	    xputchar((((c >> 6) & 7) + '0') | atr);
15259243Sobrien	    xputchar((((c >> 3) & 7) + '0') | atr);
15359243Sobrien	    c = (c & 7) + '0';
15459243Sobrien	}
15559243Sobrien	(void) putraw(c | atr);
15659243Sobrien    }
15759243Sobrien    else {
15859243Sobrien	c &= TRIM;
15959243Sobrien	if (haderr ? (didfds ? is2atty : isdiagatty) :
16059243Sobrien	    (didfds ? is1atty : isoutatty))
16159243Sobrien	    SetAttributes(c | atr);
16259243Sobrien	(void) putpure(c);
16359243Sobrien    }
16459243Sobrien    if (lbuffed && (c & CHAR) == '\n')
16559243Sobrien	flush();
16659243Sobrien}
16759243Sobrien
16859243Sobrienint
16959243Sobrienputraw(c)
17059243Sobrien    register int c;
17159243Sobrien{
17259243Sobrien    if (haderr ? (didfds ? is2atty : isdiagatty) :
17359243Sobrien	(didfds ? is1atty : isoutatty)) {
17459243Sobrien	if (Tty_eight_bit == -1)
17559243Sobrien	    ed_set_tty_eight_bit();
17659243Sobrien	if (!Tty_eight_bit && (c & META)) {
17759243Sobrien	    c = (c & ~META) | STANDOUT;
17859243Sobrien	}
17959243Sobrien	SetAttributes(c);
18059243Sobrien    }
18159243Sobrien    return putpure(c);
18259243Sobrien}
18359243Sobrien
18459243Sobrienint
18559243Sobrienputpure(c)
18659243Sobrien    register int c;
18759243Sobrien{
18859243Sobrien    c &= CHAR;
18959243Sobrien
19059243Sobrien    *linp++ = (char) c;
19159243Sobrien    if (linp >= &linbuf[sizeof linbuf - 10])
19259243Sobrien	flush();
19359243Sobrien    return (1);
19459243Sobrien}
19559243Sobrien
19659243Sobrienvoid
19759243Sobriendrainoline()
19859243Sobrien{
19959243Sobrien    linp = linbuf;
20059243Sobrien}
20159243Sobrien
20259243Sobrienvoid
20359243Sobrienflush()
20459243Sobrien{
20559243Sobrien    int unit;
20659243Sobrien    static int interrupted = 0;
20759243Sobrien    size_t sz;
20859243Sobrien
20959243Sobrien    /* int lmode; */
21059243Sobrien
21159243Sobrien    if (linp == linbuf)
21259243Sobrien	return;
21359243Sobrien    if (GettingInput && !Tty_raw_mode && linp < &linbuf[sizeof linbuf - 10])
21459243Sobrien	return;
21559243Sobrien    if (interrupted) {
21659243Sobrien	interrupted = 0;
21759243Sobrien	linp = linbuf;		/* avoid resursion as stderror calls flush */
21859243Sobrien	stderror(ERR_SILENT);
21959243Sobrien    }
22059243Sobrien    interrupted = 1;
22159243Sobrien    if (haderr)
22259243Sobrien	unit = didfds ? 2 : SHDIAG;
22359243Sobrien    else
22459243Sobrien	unit = didfds ? 1 : SHOUT;
22559243Sobrien#ifdef COMMENT
22659243Sobrien#ifdef TIOCLGET
22759243Sobrien    if (didfds == 0 && ioctl(unit, TIOCLGET, (ioctl_t) & lmode) == 0 &&
22859243Sobrien	lmode & LFLUSHO) {
22959243Sobrien	lmode = LFLUSHO;
23059243Sobrien	(void) ioctl(unit, TIOCLBIC, (ioclt_t) & lmode);
23159243Sobrien	(void) write(unit, "\n", 1);
23259243Sobrien    }
23359243Sobrien#endif
23459243Sobrien#endif
23559243Sobrien    sz = (size_t) (linp - linbuf);
23659243Sobrien    if (write(unit, linbuf, sz) == -1)
23759243Sobrien	switch (errno) {
23859243Sobrien#ifdef EIO
23959243Sobrien	/* We lost our tty */
24059243Sobrien	case EIO:
24159243Sobrien#endif
24259243Sobrien#ifdef ENXIO
24359243Sobrien	/*
24459243Sobrien	 * Deal with Digital Unix 4.0D bogocity, returning ENXIO when
24559243Sobrien	 * we lose our tty.
24659243Sobrien	 */
24759243Sobrien	case ENXIO:
24859243Sobrien#endif
24959243Sobrien	/*
25059243Sobrien	 * IRIX 6.4 bogocity?
25159243Sobrien	 */
25259243Sobrien#ifdef ENOTTY
25359243Sobrien	case ENOTTY:
25459243Sobrien#endif
25559243Sobrien#ifdef EBADF
25659243Sobrien	case EBADF:
25759243Sobrien#endif
25859415Sobrien#ifdef ESTALE
25959243Sobrien	/*
26059415Sobrien	 * Lost our file descriptor, exit (IRIS4D)
26159415Sobrien	 */
26259415Sobrien	case ESTALE:
26359415Sobrien#endif
26459415Sobrien	/*
26559243Sobrien	 * Over our quota, writing the history file
26659243Sobrien	 */
26759243Sobrien#ifdef EDQUOT
26859243Sobrien	case EDQUOT:
26959243Sobrien#endif
27059243Sobrien	/* Nothing to do, but die */
27159243Sobrien	    xexit(1);
27259243Sobrien	    break;
27359243Sobrien	default:
27459243Sobrien	    stderror(ERR_SILENT);
27559243Sobrien	    break;
27659243Sobrien	}
27759243Sobrien
27859243Sobrien    linp = linbuf;
27959243Sobrien    interrupted = 0;
28059243Sobrien}
281