Change bwillwrite() to smooth out performance under heavy loads. Blocking
[dragonfly.git] / bin / ls / util.c
blob76762547f86f58ff342ed158e415557783b89574
1 /*
2 * Copyright (c) 1989, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Michael Fischbein.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 4. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
32 * @(#)util.c 8.3 (Berkeley) 4/2/94
33 * $FreeBSD: src/bin/ls/util.c,v 1.35 2004/05/03 11:48:55 tjr Exp $
34 * $DragonFly: src/bin/ls/util.c,v 1.8 2008/02/14 09:33:24 matthias Exp $
37 #include <sys/types.h>
38 #include <sys/stat.h>
40 #include <ctype.h>
41 #include <err.h>
42 #include <fts.h>
43 #include <limits.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <wchar.h>
48 #include <wctype.h>
50 #include "ls.h"
51 #include "extern.h"
53 int
54 prn_normal(const char *s)
56 mbstate_t mbs;
57 wchar_t wc;
58 int i, n;
59 size_t clen;
61 memset(&mbs, 0, sizeof(mbs));
62 n = 0;
63 while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
64 if (clen == (size_t)-2) {
65 n += printf("%s", s);
66 break;
68 if (clen == (size_t)-1) {
69 memset(&mbs, 0, sizeof(mbs));
70 putchar((unsigned char)*s);
71 s++;
72 n++;
73 continue;
75 for (i = 0; i < (int)clen; i++)
76 putchar((unsigned char)s[i]);
77 s += clen;
78 if (iswprint(wc))
79 n += wcwidth(wc);
81 return (n);
84 int
85 prn_printable(const char *s)
87 mbstate_t mbs;
88 wchar_t wc;
89 int i, n;
90 size_t clen;
92 memset(&mbs, 0, sizeof(mbs));
93 n = 0;
94 while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
95 if (clen == (size_t)-1) {
96 putchar('?');
97 s++;
98 n++;
99 memset(&mbs, 0, sizeof(mbs));
100 continue;
102 if (clen == (size_t)-2) {
103 putchar('?');
104 n++;
105 break;
107 if (!iswprint(wc)) {
108 putchar('?');
109 s += clen;
110 n++;
111 continue;
113 for (i = 0; i < (int)clen; i++)
114 putchar((unsigned char)s[i]);
115 s += clen;
116 n += wcwidth(wc);
118 return (n);
122 * The fts system makes it difficult to replace fts_name with a different-
123 * sized string, so we just calculate the real length here and do the
124 * conversion in prn_octal()
126 * XXX when using f_octal_escape (-b) rather than f_octal (-B), the
127 * length computed by len_octal may be too big. I just can't be buggered
128 * to fix this as an efficient fix would involve a lookup table. Same goes
129 * for the rather inelegant code in prn_octal.
131 * DES 1998/04/23
134 size_t
135 len_octal(const char *s, int len)
137 mbstate_t mbs;
138 wchar_t wc;
139 size_t clen, r;
141 memset(&mbs, 0, sizeof(mbs));
142 r = 0;
143 while (len != 0 && (clen = mbrtowc(&wc, s, len, &mbs)) != 0) {
144 if (clen == (size_t)-1) {
145 r += 4;
146 s++;
147 len--;
148 memset(&mbs, 0, sizeof(mbs));
149 continue;
151 if (clen == (size_t)-2) {
152 r += 4 * len;
153 break;
155 if (iswprint(wc))
156 r++;
157 else
158 r += 4 * clen;
159 s += clen;
161 return (r);
165 prn_octal(const char *s)
167 static const char esc[] = "\\\\\"\"\aa\bb\ff\nn\rr\tt\vv";
168 const char *p;
169 mbstate_t mbs;
170 wchar_t wc;
171 size_t clen;
172 unsigned char ch;
173 int goodchar, i, len, prtlen;
175 memset(&mbs, 0, sizeof(mbs));
176 len = 0;
177 while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
178 goodchar = clen != (size_t)-1 && clen != (size_t)-2;
179 if (goodchar && iswprint(wc) && wc != L'\"' && wc != L'\\') {
180 for (i = 0; i < (int)clen; i++)
181 putchar((unsigned char)s[i]);
182 len += wcwidth(wc);
183 } else if (goodchar && f_octal_escape && wc >= 0 &&
184 wc <= (wchar_t)UCHAR_MAX &&
185 (p = strchr(esc, (char)wc)) != NULL) {
186 putchar('\\');
187 putchar(p[1]);
188 len += 2;
189 } else {
190 if (goodchar)
191 prtlen = clen;
192 else if (clen == (size_t)-1)
193 prtlen = 1;
194 else
195 prtlen = strlen(s);
196 for (i = 0; i < prtlen; i++) {
197 ch = (unsigned char)s[i];
198 putchar('\\');
199 putchar('0' + (ch >> 6));
200 putchar('0' + ((ch >> 3) & 7));
201 putchar('0' + (ch & 7));
202 len += 4;
205 if (clen == (size_t)-2)
206 break;
207 if (clen == (size_t)-1) {
208 memset(&mbs, 0, sizeof(mbs));
209 s++;
210 } else
211 s += clen;
213 return (len);
216 void
217 usage(void)
219 fprintf(stderr,
220 #ifdef COLORLS
221 "usage: ls [-ABCFGHLPRSTWabcdfghiklmnoqrstuwxy1]"
222 #else
223 "usage: ls [-ABCFHLPRSTWabcdfghiklmnoqrstuwxy1]"
224 #endif
225 " [file ...]\n");
226 exit(1);