aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-02-14 15:42:18 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2011-02-14 15:42:18 +0100
commitb9348440b0491b479457b304754bca4840286f74 (patch)
tree636a1f233abbe51216a231d1d3eb37f7faabd1bd /coreutils
parent713e6d78e1cb567848805e8dd0c9c0cadbfa787a (diff)
downloadbusybox-w32-b9348440b0491b479457b304754bca4840286f74.tar.gz
busybox-w32-b9348440b0491b479457b304754bca4840286f74.tar.bz2
busybox-w32-b9348440b0491b479457b304754bca4840286f74.zip
echo: fix ENOSPC detection and some iffy code in \NNN handling
function old new delta echo_main 330 302 -28 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/echo.c112
1 files changed, 56 insertions, 56 deletions
diff --git a/coreutils/echo.c b/coreutils/echo.c
index 5fa3d10c5..42c3f9ed8 100644
--- a/coreutils/echo.c
+++ b/coreutils/echo.c
@@ -50,7 +50,6 @@ int echo_main(int argc UNUSED_PARAM, char **argv)
50 char *out; 50 char *out;
51 char *buffer; 51 char *buffer;
52 unsigned buflen; 52 unsigned buflen;
53 int r;
54#if !ENABLE_FEATURE_FANCY_ECHO 53#if !ENABLE_FEATURE_FANCY_ECHO
55 enum { 54 enum {
56 eflag = '\\', 55 eflag = '\\',
@@ -59,40 +58,40 @@ int echo_main(int argc UNUSED_PARAM, char **argv)
59 58
60 argv++; 59 argv++;
61#else 60#else
62 const char *p;
63 char nflag = 1; 61 char nflag = 1;
64 char eflag = 0; 62 char eflag = 0;
65 63
66 while ((arg = *++argv) != NULL) { 64 while ((arg = *++argv) != NULL) {
67 if (!arg || arg[0] != '-') 65 char n, e;
68 break; 66
67 if (arg[0] != '-')
68 break; /* not an option arg, echo it */
69 69
70 /* If it appears that we are handling options, then make sure 70 /* If it appears that we are handling options, then make sure
71 * that all of the options specified are actually valid. 71 * that all of the options specified are actually valid.
72 * Otherwise, the string should just be echoed. 72 * Otherwise, the string should just be echoed.
73 */ 73 */
74 p = arg + 1; 74 arg++;
75 if (!*p) /* A single '-', so echo it. */ 75 n = nflag;
76 break; 76 e = eflag;
77
78 do { 77 do {
79 if (!strrchr("neE", *p)) 78 if (*arg == 'n')
79 n = 0;
80 else if (*arg == 'e')
81 e = '\\';
82 else if (*arg != 'E') {
83 /* "-ccc" arg with one of c's invalid, echo it */
84 /* arg consisting from just "-" also handled here */
80 goto just_echo; 85 goto just_echo;
81 } while (*++p); 86 }
82 87 } while (*++arg);
83 /* All of the options in this arg are valid, so handle them. */ 88 nflag = n;
84 p = arg + 1; 89 eflag = e;
85 do {
86 if (*p == 'n')
87 nflag = 0;
88 if (*p == 'e')
89 eflag = '\\';
90 } while (*++p);
91 } 90 }
92 just_echo: 91 just_echo:
93#endif 92#endif
94 93
95 buflen = 1; 94 buflen = 0;
96 pp = argv; 95 pp = argv;
97 while ((arg = *pp) != NULL) { 96 while ((arg = *pp) != NULL) {
98 buflen += strlen(arg) + 1; 97 buflen += strlen(arg) + 1;
@@ -106,29 +105,32 @@ int echo_main(int argc UNUSED_PARAM, char **argv)
106 if (!eflag) { 105 if (!eflag) {
107 /* optimization for very common case */ 106 /* optimization for very common case */
108 out = stpcpy(out, arg); 107 out = stpcpy(out, arg);
109 } else while ((c = *arg++)) { 108 } else
110 if (c == eflag) { /* Check for escape seq. */ 109 while ((c = *arg++) != '\0') {
110 if (c == eflag) {
111 /* This is an "\x" sequence */
112
111 if (*arg == 'c') { 113 if (*arg == 'c') {
112 /* '\c' means cancel newline and 114 /* "\c" means cancel newline and
113 * ignore all subsequent chars. */ 115 * ignore all subsequent chars. */
114 goto do_write; 116 goto do_write;
115 } 117 }
116#if !ENABLE_FEATURE_FANCY_ECHO 118 /* Since SUSv3 mandates a first digit of 0, 4-digit octals
117 /* SUSv3 specifies that octal escapes must begin with '0'. */ 119 * of the form \0### are accepted. */
118 if ( ((int)(unsigned char)(*arg) - '0') >= 8) /* '8' or bigger */ 120 if (*arg == '0') {
119#endif 121 if ((unsigned char)(arg[1] - '0') < 8) {
120 { 122 /* 2nd char is 0..7: skip leading '0' */
121 /* Since SUSv3 mandates a first digit of 0, 4-digit octals 123 arg++;
122 * of the form \0### are accepted. */
123 if (*arg == '0') {
124 /* NB: don't turn "...\0" into "...\" */
125 if (arg[1] && ((unsigned char)(arg[1]) - '0') < 8) {
126 arg++;
127 }
128 } 124 }
129 /* bb_process_escape_sequence handles NUL correctly 125 }
130 * ("...\" case). */ 126 /* bb_process_escape_sequence handles NUL correctly
131 c = bb_process_escape_sequence(&arg); 127 * ("...\" case). */
128 {
129 /* optimization: don't force arg to be on-stack,
130 * use another variable for that. ~30 bytes win */
131 const char *z = arg;
132 c = bb_process_escape_sequence(&z);
133 arg = z;
132 } 134 }
133 } 135 }
134 *out++ = c; 136 *out++ = c;
@@ -144,16 +146,18 @@ int echo_main(int argc UNUSED_PARAM, char **argv)
144 } 146 }
145 147
146 do_write: 148 do_write:
147 r = full_write(STDOUT_FILENO, buffer, out - buffer); 149 /* Careful to error out on partial writes too (think ENOSPC!) */
150 errno = 0;
151 /*r =*/ full_write(STDOUT_FILENO, buffer, out - buffer);
148 free(buffer); 152 free(buffer);
149 if (r < 0) { 153 if (/*WRONG:r < 0*/ errno) {
150 bb_perror_msg(bb_msg_write_error); 154 bb_perror_msg(bb_msg_write_error);
151 return 1; 155 return 1;
152 } 156 }
153 return 0; 157 return 0;
154} 158}
155 159
156/*- 160/*
157 * Copyright (c) 1991, 1993 161 * Copyright (c) 1991, 1993
158 * The Regents of the University of California. All rights reserved. 162 * The Regents of the University of California. All rights reserved.
159 * 163 *
@@ -239,7 +243,7 @@ int echo_main(int argc, char **argv)
239 goto just_echo; 243 goto just_echo;
240 244
241 do { 245 do {
242 if (!strrchr("neE", *p)) 246 if (!strchr("neE", *p))
243 goto just_echo; 247 goto just_echo;
244 } while (*++p); 248 } while (*++p);
245 249
@@ -265,27 +269,23 @@ int echo_main(int argc, char **argv)
265 /* optimization for very common case */ 269 /* optimization for very common case */
266 p += strlen(arg); 270 p += strlen(arg);
267 } else while ((c = *arg++)) { 271 } else while ((c = *arg++)) {
268 if (c == eflag) { /* Check for escape seq. */ 272 if (c == eflag) {
273 /* This is an "\x" sequence */
274
269 if (*arg == 'c') { 275 if (*arg == 'c') {
270 /* '\c' means cancel newline and 276 /* "\c" means cancel newline and
271 * ignore all subsequent chars. */ 277 * ignore all subsequent chars. */
272 cur_io->iov_len = p - (char*)cur_io->iov_base; 278 cur_io->iov_len = p - (char*)cur_io->iov_base;
273 cur_io++; 279 cur_io++;
274 goto ret; 280 goto ret;
275 } 281 }
276#if !ENABLE_FEATURE_FANCY_ECHO 282 /* Since SUSv3 mandates a first digit of 0, 4-digit octals
277 /* SUSv3 specifies that octal escapes must begin with '0'. */ 283 * of the form \0### are accepted. */
278 if ( (((unsigned char)*arg) - '1') >= 7) 284 if (*arg == '0' && (unsigned char)(arg[1] - '0') < 8) {
279#endif 285 arg++;
280 {
281 /* Since SUSv3 mandates a first digit of 0, 4-digit octals
282 * of the form \0### are accepted. */
283 if (*arg == '0' && ((unsigned char)(arg[1]) - '0') < 8) {
284 arg++;
285 }
286 /* bb_process_escape_sequence can handle nul correctly */
287 c = bb_process_escape_sequence( (void*) &arg);
288 } 286 }
287 /* bb_process_escape_sequence can handle nul correctly */
288 c = bb_process_escape_sequence( (void*) &arg);
289 } 289 }
290 *p++ = c; 290 *p++ = c;
291 } 291 }