1 /* $OpenBSD: ttoutput.c,v 1.8 2005/04/11 19:59:07 deraadt Exp $ */
2 /* $NetBSD: ttoutput.c,v 1.3 1995/09/28 10:34:51 tls Exp $ */
3
4 /*
5 * Copyright (c) 1983, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Edward Wang at The University of California, Berkeley.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)ttoutput.c 8.1 (Berkeley) 6/6/93";
39 #else
40 static char rcsid[] = "$OpenBSD: ttoutput.c,v 1.8 2005/04/11 19:59:07 deraadt Exp $";
41 #endif
42 #endif /* not lint */
43
44 #include "ww.h"
45 #include "tt.h"
46 #include <errno.h>
47 #include <sys/types.h>
48 #include <string.h>
49 #include <unistd.h>
50
51 /*
52 * Buffered output package.
53 * We need this because stdio fails on non-blocking writes.
54 */
55
ttflush()56 ttflush()
57 {
58 char *p;
59 int n = tt_obp - tt_ob;
60
61 if (n == 0)
62 return;
63 if (tt.tt_checksum)
64 (*tt.tt_checksum)(tt_ob, n);
65 if (tt.tt_flush) {
66 (*tt.tt_flush)();
67 return;
68 }
69 wwnflush++;
70 for (p = tt_ob; p < tt_obp;) {
71 wwnwr++;
72 n = write(STDOUT_FILENO, p, tt_obp - p);
73 if (n < 0) {
74 wwnwre++;
75 if (errno != EWOULDBLOCK) {
76 /* can't deal with this */
77 p = tt_obp;
78 }
79 } else if (n == 0) {
80 /* what to do? */
81 wwnwrz++;
82 } else {
83 wwnwrc += n;
84 p += n;
85 }
86 }
87 tt_obp = tt_ob;
88 }
89
ttputs(s)90 ttputs(s)
91 char *s;
92 {
93 while (*s)
94 ttputc(*s++);
95 }
96
ttwrite(s,n)97 ttwrite(s, n)
98 char *s;
99 int n;
100 {
101 switch (n) {
102 case 0:
103 break;
104 case 1:
105 ttputc(*s);
106 break;
107 case 2:
108 if (tt_obe - tt_obp < 2)
109 ttflush();
110 *tt_obp++ = *s++;
111 *tt_obp++ = *s;
112 break;
113 case 3:
114 if (tt_obe - tt_obp < 3)
115 ttflush();
116 *tt_obp++ = *s++;
117 *tt_obp++ = *s++;
118 *tt_obp++ = *s;
119 break;
120 case 4:
121 if (tt_obe - tt_obp < 4)
122 ttflush();
123 *tt_obp++ = *s++;
124 *tt_obp++ = *s++;
125 *tt_obp++ = *s++;
126 *tt_obp++ = *s;
127 break;
128 case 5:
129 if (tt_obe - tt_obp < 5)
130 ttflush();
131 *tt_obp++ = *s++;
132 *tt_obp++ = *s++;
133 *tt_obp++ = *s++;
134 *tt_obp++ = *s++;
135 *tt_obp++ = *s;
136 break;
137 default:
138 while (n > 0) {
139 int m;
140
141 while ((m = tt_obe - tt_obp) == 0)
142 ttflush();
143 if ((m = tt_obe - tt_obp) > n)
144 m = n;
145 memmove(tt_obp, s, m);
146 tt_obp += m;
147 s += m;
148 n -= m;
149 }
150 }
151 }
152