diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-02-14 15:42:18 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-02-14 15:42:18 +0100 |
commit | b9348440b0491b479457b304754bca4840286f74 (patch) | |
tree | 636a1f233abbe51216a231d1d3eb37f7faabd1bd /coreutils | |
parent | 713e6d78e1cb567848805e8dd0c9c0cadbfa787a (diff) | |
download | busybox-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.c | 112 |
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 | } |