aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-01-12 22:12:10 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-01-12 22:12:10 +0100
commit045f4ad92c07434625e168bc8c37aa0e89f6e58e (patch)
tree83e8c3eeca479d0ad4cc78a83c6da55678f91f0f
parent7306727d1b2ed05afc91548ba374f7400a2389e3 (diff)
downloadbusybox-w32-045f4ad92c07434625e168bc8c37aa0e89f6e58e.tar.gz
busybox-w32-045f4ad92c07434625e168bc8c37aa0e89f6e58e.tar.bz2
busybox-w32-045f4ad92c07434625e168bc8c37aa0e89f6e58e.zip
shell/read: fix "'read' without parameters" bash compat thingy
previous change: function old new delta builtin_read 82 1074 +992 popstring 134 140 +6 readcmd 1034 148 -886 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 998/-886) Total: 112 bytes this change: builtin_read 1074 1096 +22 static.arg_REPLY 8 - -8 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/0 up/down: 22/-8) Total: 14 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/builtin_read.c70
1 files changed, 39 insertions, 31 deletions
diff --git a/shell/builtin_read.c b/shell/builtin_read.c
index 7f667e9c1..24cfe08fb 100644
--- a/shell/builtin_read.c
+++ b/shell/builtin_read.c
@@ -31,8 +31,6 @@ builtin_read(void (*setvar)(const char *name, const char *val, int flags),
31 const char *opt_u 31 const char *opt_u
32) 32)
33{ 33{
34 static const char *const arg_REPLY[] = { "REPLY", NULL };
35
36 unsigned end_ms; /* -t TIMEOUT */ 34 unsigned end_ms; /* -t TIMEOUT */
37 int fd; /* -u FD */ 35 int fd; /* -u FD */
38 int nchars; /* -n NUM */ 36 int nchars; /* -n NUM */
@@ -94,8 +92,6 @@ builtin_read(void (*setvar)(const char *name, const char *val, int flags),
94 fflush_all(); 92 fflush_all();
95 } 93 }
96 94
97 if (argv[0] == NULL)
98 argv = (char**)arg_REPLY;
99 if (ifs == NULL) 95 if (ifs == NULL)
100 ifs = defifs; 96 ifs = defifs;
101 97
@@ -125,7 +121,6 @@ builtin_read(void (*setvar)(const char *name, const char *val, int flags),
125 bufpos = 0; 121 bufpos = 0;
126 do { 122 do {
127 char c; 123 char c;
128 const char *is_ifs;
129 124
130 if (end_ms) { 125 if (end_ms) {
131 int timeout; 126 int timeout;
@@ -163,40 +158,53 @@ builtin_read(void (*setvar)(const char *name, const char *val, int flags),
163 } 158 }
164 if (c == '\n') 159 if (c == '\n')
165 break; 160 break;
166 /* $IFS splitting */ 161
162 /* $IFS splitting. NOT done if we run "read"
163 * without variable names (bash compat).
164 * Thus, "read" and "read REPLY" are not the same.
165 */
166 if (argv[0]) {
167/* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05 */ 167/* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05 */
168 is_ifs = strchr(ifs, c); 168 const char *is_ifs = strchr(ifs, c);
169 if (startword && is_ifs) { 169 if (startword && is_ifs) {
170 if (isspace(c)) 170 if (isspace(c))
171 continue;
172 /* it is a non-space ifs char */
173 startword--;
174 if (startword == 1) /* first one? */
175 continue; /* yes, it is not next word yet */
176 }
177 startword = 0;
178 if (argv[1] != NULL && is_ifs) {
179 buffer[bufpos] = '\0';
180 bufpos = 0;
181 setvar(*argv, buffer, 0);
182 argv++;
183 /* can we skip one non-space ifs char? (2: yes) */
184 startword = isspace(c) ? 2 : 1;
171 continue; 185 continue;
172 /* it is a non-space ifs char */ 186 }
173 startword--;
174 if (startword == 1) /* first one? */
175 continue; /* yes, it is not next word yet */
176 }
177 startword = 0;
178 if (argv[1] != NULL && is_ifs) {
179 buffer[bufpos] = '\0';
180 bufpos = 0;
181 setvar(*argv, buffer, 0);
182 argv++;
183 /* can we skip one non-space ifs char? (2: yes) */
184 startword = isspace(c) ? 2 : 1;
185 continue;
186 } 187 }
187 put: 188 put:
188 bufpos++; 189 bufpos++;
189 } while (--nchars); 190 } while (--nchars);
190 191
191 /* Remove trailing space ifs chars */ 192 if (argv[0]) {
192 while (--bufpos >= 0 && isspace(buffer[bufpos]) && strchr(ifs, buffer[bufpos]) != NULL) 193 /* Remove trailing space $IFS chars */
193 continue; 194 while (--bufpos >= 0 && isspace(buffer[bufpos]) && strchr(ifs, buffer[bufpos]) != NULL)
194 buffer[bufpos + 1] = '\0'; 195 continue;
195 196 buffer[bufpos + 1] = '\0';
196 setvar(*argv, buffer, 0); 197 /* Use the remainder as a value for the next variable */
198 setvar(*argv, buffer, 0);
199 /* Set the rest to "" */
200 while (*++argv)
201 setvar(*argv, "", 0);
202 } else {
203 /* Note: no $IFS removal */
204 buffer[bufpos] = '\0';
205 setvar("REPLY", buffer, 0);
206 }
197 207
198 while (*++argv != NULL)
199 setvar(*argv, "", 0);
200 ret: 208 ret:
201 free(buffer); 209 free(buffer);
202 if (read_flags & BUILTIN_READ_SILENT) 210 if (read_flags & BUILTIN_READ_SILENT)