1 | This file is read.def, from which is created read.c.
|
---|
2 | It implements the builtin "read" in Bash.
|
---|
3 |
|
---|
4 | Copyright (C) 1987-2005 Free Software Foundation, Inc.
|
---|
5 |
|
---|
6 | This file is part of GNU Bash, the Bourne Again SHell.
|
---|
7 |
|
---|
8 | Bash is free software; you can redistribute it and/or modify it under
|
---|
9 | the terms of the GNU General Public License as published by the Free
|
---|
10 | Software Foundation; either version 2, or (at your option) any later
|
---|
11 | version.
|
---|
12 |
|
---|
13 | Bash is distributed in the hope that it will be useful, but WITHOUT ANY
|
---|
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
---|
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
---|
16 | for more details.
|
---|
17 |
|
---|
18 | You should have received a copy of the GNU General Public License along
|
---|
19 | with Bash; see the file COPYING. If not, write to the Free Software
|
---|
20 | Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
---|
21 |
|
---|
22 | $PRODUCES read.c
|
---|
23 |
|
---|
24 | $BUILTIN read
|
---|
25 | $FUNCTION read_builtin
|
---|
26 | $SHORT_DOC read [-ers] [-u fd] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...]
|
---|
27 | One line is read from the standard input, or from file descriptor FD if the
|
---|
28 | -u option is supplied, and the first word is assigned to the first NAME,
|
---|
29 | the second word to the second NAME, and so on, with leftover words assigned
|
---|
30 | to the last NAME. Only the characters found in $IFS are recognized as word
|
---|
31 | delimiters. If no NAMEs are supplied, the line read is stored in the REPLY
|
---|
32 | variable. If the -r option is given, this signifies `raw' input, and
|
---|
33 | backslash escaping is disabled. The -d option causes read to continue
|
---|
34 | until the first character of DELIM is read, rather than newline. If the -p
|
---|
35 | option is supplied, the string PROMPT is output without a trailing newline
|
---|
36 | before attempting to read. If -a is supplied, the words read are assigned
|
---|
37 | to sequential indices of ARRAY, starting at zero. If -e is supplied and
|
---|
38 | the shell is interactive, readline is used to obtain the line. If -n is
|
---|
39 | supplied with a non-zero NCHARS argument, read returns after NCHARS
|
---|
40 | characters have been read. The -s option causes input coming from a
|
---|
41 | terminal to not be echoed.
|
---|
42 |
|
---|
43 | The -t option causes read to time out and return failure if a complete line
|
---|
44 | of input is not read within TIMEOUT seconds. If the TMOUT variable is set,
|
---|
45 | its value is the default timeout. The return code is zero, unless end-of-file
|
---|
46 | is encountered, read times out, or an invalid file descriptor is supplied as
|
---|
47 | the argument to -u.
|
---|
48 | $END
|
---|
49 |
|
---|
50 | #include <config.h>
|
---|
51 |
|
---|
52 | #include "bashtypes.h"
|
---|
53 | #include "posixstat.h"
|
---|
54 |
|
---|
55 | #include <stdio.h>
|
---|
56 |
|
---|
57 | #if defined (HAVE_UNISTD_H)
|
---|
58 | # include <unistd.h>
|
---|
59 | #endif
|
---|
60 |
|
---|
61 | #include <signal.h>
|
---|
62 | #include <errno.h>
|
---|
63 |
|
---|
64 | #if defined (__CYGWIN__) || defined (__OS2__)
|
---|
65 | # include <fcntl.h>
|
---|
66 | # include <io.h>
|
---|
67 | #endif
|
---|
68 |
|
---|
69 | #include "../bashintl.h"
|
---|
70 |
|
---|
71 | #include "../shell.h"
|
---|
72 | #include "common.h"
|
---|
73 | #include "bashgetopt.h"
|
---|
74 |
|
---|
75 | #include <shtty.h>
|
---|
76 |
|
---|
77 | #if defined (READLINE)
|
---|
78 | #include "../bashline.h"
|
---|
79 | #include <readline/readline.h>
|
---|
80 | #endif
|
---|
81 |
|
---|
82 | #if defined (BUFFERED_INPUT)
|
---|
83 | # include "input.h"
|
---|
84 | #endif
|
---|
85 |
|
---|
86 | #if !defined(errno)
|
---|
87 | extern int errno;
|
---|
88 | #endif
|
---|
89 |
|
---|
90 | extern int interrupt_immediately;
|
---|
91 |
|
---|
92 | #if defined (READLINE)
|
---|
93 | static char *edit_line __P((char *));
|
---|
94 | static void set_eol_delim __P((int));
|
---|
95 | static void reset_eol_delim __P((char *));
|
---|
96 | #endif
|
---|
97 | static SHELL_VAR *bind_read_variable __P((char *, char *));
|
---|
98 |
|
---|
99 | static sighandler sigalrm __P((int));
|
---|
100 | static void reset_alarm __P((void));
|
---|
101 |
|
---|
102 | static procenv_t alrmbuf;
|
---|
103 | static SigHandler *old_alrm;
|
---|
104 | static unsigned char delim;
|
---|
105 |
|
---|
106 | static sighandler
|
---|
107 | sigalrm (s)
|
---|
108 | int s;
|
---|
109 | {
|
---|
110 | longjmp (alrmbuf, 1);
|
---|
111 | }
|
---|
112 |
|
---|
113 | static void
|
---|
114 | reset_alarm ()
|
---|
115 | {
|
---|
116 | set_signal_handler (SIGALRM, old_alrm);
|
---|
117 | alarm (0);
|
---|
118 | }
|
---|
119 |
|
---|
120 | /* Read the value of the shell variables whose names follow.
|
---|
121 | The reading is done from the current input stream, whatever
|
---|
122 | that may be. Successive words of the input line are assigned
|
---|
123 | to the variables mentioned in LIST. The last variable in LIST
|
---|
124 | gets the remainder of the words on the line. If no variables
|
---|
125 | are mentioned in LIST, then the default variable is $REPLY. */
|
---|
126 | int
|
---|
127 | read_builtin (list)
|
---|
128 | WORD_LIST *list;
|
---|
129 | {
|
---|
130 | register char *varname;
|
---|
131 | int size, i, nr, pass_next, saw_escape, eof, opt, retval, code;
|
---|
132 | int input_is_tty, input_is_pipe, unbuffered_read;
|
---|
133 | int raw, edit, nchars, silent, have_timeout, fd;
|
---|
134 | unsigned int tmout;
|
---|
135 | intmax_t intval;
|
---|
136 | char c;
|
---|
137 | char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
|
---|
138 | char *e, *t, *t1;
|
---|
139 | struct stat tsb;
|
---|
140 | SHELL_VAR *var;
|
---|
141 | #if defined (ARRAY_VARS)
|
---|
142 | WORD_LIST *alist;
|
---|
143 | #endif
|
---|
144 | #if defined (READLINE)
|
---|
145 | char *rlbuf;
|
---|
146 | int rlind;
|
---|
147 | #endif
|
---|
148 |
|
---|
149 | USE_VAR(size);
|
---|
150 | USE_VAR(i);
|
---|
151 | USE_VAR(pass_next);
|
---|
152 | USE_VAR(saw_escape);
|
---|
153 | USE_VAR(input_is_pipe);
|
---|
154 | /* USE_VAR(raw); */
|
---|
155 | USE_VAR(edit);
|
---|
156 | USE_VAR(tmout);
|
---|
157 | USE_VAR(nchars);
|
---|
158 | USE_VAR(silent);
|
---|
159 | USE_VAR(ifs_chars);
|
---|
160 | USE_VAR(prompt);
|
---|
161 | USE_VAR(arrayname);
|
---|
162 | #if defined (READLINE)
|
---|
163 | USE_VAR(rlbuf);
|
---|
164 | USE_VAR(rlind);
|
---|
165 | #endif
|
---|
166 | USE_VAR(list);
|
---|
167 |
|
---|
168 | i = 0; /* Index into the string that we are reading. */
|
---|
169 | raw = edit = 0; /* Not reading raw input by default. */
|
---|
170 | silent = 0;
|
---|
171 | arrayname = prompt = (char *)NULL;
|
---|
172 | fd = 0; /* file descriptor to read from */
|
---|
173 |
|
---|
174 | #if defined (READLINE)
|
---|
175 | rlbuf = (char *)0;
|
---|
176 | rlind = 0;
|
---|
177 | #endif
|
---|
178 |
|
---|
179 | tmout = 0; /* no timeout */
|
---|
180 | nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0;
|
---|
181 | delim = '\n'; /* read until newline */
|
---|
182 |
|
---|
183 | reset_internal_getopt ();
|
---|
184 | while ((opt = internal_getopt (list, "ersa:d:n:p:t:u:")) != -1)
|
---|
185 | {
|
---|
186 | switch (opt)
|
---|
187 | {
|
---|
188 | case 'r':
|
---|
189 | raw = 1;
|
---|
190 | break;
|
---|
191 | case 'p':
|
---|
192 | prompt = list_optarg;
|
---|
193 | break;
|
---|
194 | case 's':
|
---|
195 | silent = 1;
|
---|
196 | break;
|
---|
197 | case 'e':
|
---|
198 | #if defined (READLINE)
|
---|
199 | edit = 1;
|
---|
200 | #endif
|
---|
201 | break;
|
---|
202 | #if defined (ARRAY_VARS)
|
---|
203 | case 'a':
|
---|
204 | arrayname = list_optarg;
|
---|
205 | break;
|
---|
206 | #endif
|
---|
207 | case 't':
|
---|
208 | code = legal_number (list_optarg, &intval);
|
---|
209 | if (code == 0 || intval < 0 || intval != (unsigned int)intval)
|
---|
210 | {
|
---|
211 | builtin_error (_("%s: invalid timeout specification"), list_optarg);
|
---|
212 | return (EXECUTION_FAILURE);
|
---|
213 | }
|
---|
214 | else
|
---|
215 | {
|
---|
216 | have_timeout = 1;
|
---|
217 | tmout = intval;
|
---|
218 | }
|
---|
219 | break;
|
---|
220 | case 'n':
|
---|
221 | code = legal_number (list_optarg, &intval);
|
---|
222 | if (code == 0 || intval < 0 || intval != (int)intval)
|
---|
223 | {
|
---|
224 | sh_invalidnum (list_optarg);
|
---|
225 | return (EXECUTION_FAILURE);
|
---|
226 | }
|
---|
227 | else
|
---|
228 | nchars = intval;
|
---|
229 | break;
|
---|
230 | case 'u':
|
---|
231 | code = legal_number (list_optarg, &intval);
|
---|
232 | if (code == 0 || intval < 0 || intval != (int)intval)
|
---|
233 | {
|
---|
234 | builtin_error (_("%s: invalid file descriptor specification"), list_optarg);
|
---|
235 | return (EXECUTION_FAILURE);
|
---|
236 | }
|
---|
237 | else
|
---|
238 | fd = intval;
|
---|
239 | if (sh_validfd (fd) == 0)
|
---|
240 | {
|
---|
241 | builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno));
|
---|
242 | return (EXECUTION_FAILURE);
|
---|
243 | }
|
---|
244 | break;
|
---|
245 | case 'd':
|
---|
246 | delim = *list_optarg;
|
---|
247 | break;
|
---|
248 | default:
|
---|
249 | builtin_usage ();
|
---|
250 | return (EX_USAGE);
|
---|
251 | }
|
---|
252 | }
|
---|
253 | list = loptend;
|
---|
254 |
|
---|
255 | /* `read -t 0 var' returns failure immediately. XXX - should it test
|
---|
256 | whether input is available with select/FIONREAD, and fail if those
|
---|
257 | are unavailable? */
|
---|
258 | if (have_timeout && tmout == 0)
|
---|
259 | return (EXECUTION_FAILURE);
|
---|
260 |
|
---|
261 | /* IF IFS is unset, we use the default of " \t\n". */
|
---|
262 | ifs_chars = getifs ();
|
---|
263 | if (ifs_chars == 0) /* XXX - shouldn't happen */
|
---|
264 | ifs_chars = "";
|
---|
265 |
|
---|
266 | input_string = (char *)xmalloc (size = 112); /* XXX was 128 */
|
---|
267 |
|
---|
268 | /* $TMOUT, if set, is the default timeout for read. */
|
---|
269 | if (have_timeout == 0 && (e = get_string_value ("TMOUT")))
|
---|
270 | {
|
---|
271 | code = legal_number (e, &intval);
|
---|
272 | if (code == 0 || intval < 0 || intval != (unsigned int)intval)
|
---|
273 | tmout = 0;
|
---|
274 | else
|
---|
275 | tmout = intval;
|
---|
276 | }
|
---|
277 |
|
---|
278 | begin_unwind_frame ("read_builtin");
|
---|
279 |
|
---|
280 | #if defined (BUFFERED_INPUT)
|
---|
281 | if (interactive == 0 && default_buffered_input >= 0 && fd_is_bash_input (fd))
|
---|
282 | sync_buffered_stream (default_buffered_input);
|
---|
283 | #endif
|
---|
284 |
|
---|
285 | input_is_tty = isatty (fd);
|
---|
286 | if (input_is_tty == 0)
|
---|
287 | #ifndef __CYGWIN__
|
---|
288 | input_is_pipe = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
|
---|
289 | #else
|
---|
290 | input_is_pipe = 1;
|
---|
291 | #endif
|
---|
292 |
|
---|
293 | /* If the -p, -e or -s flags were given, but input is not coming from the
|
---|
294 | terminal, turn them off. */
|
---|
295 | if ((prompt || edit || silent) && input_is_tty == 0)
|
---|
296 | {
|
---|
297 | prompt = (char *)NULL;
|
---|
298 | edit = silent = 0;
|
---|
299 | }
|
---|
300 |
|
---|
301 | #if defined (READLINE)
|
---|
302 | if (edit)
|
---|
303 | add_unwind_protect (xfree, rlbuf);
|
---|
304 | #endif
|
---|
305 |
|
---|
306 | if (prompt && edit == 0)
|
---|
307 | {
|
---|
308 | fprintf (stderr, "%s", prompt);
|
---|
309 | fflush (stderr);
|
---|
310 | }
|
---|
311 |
|
---|
312 | pass_next = 0; /* Non-zero signifies last char was backslash. */
|
---|
313 | saw_escape = 0; /* Non-zero signifies that we saw an escape char */
|
---|
314 |
|
---|
315 | if (tmout > 0)
|
---|
316 | {
|
---|
317 | /* Turn off the timeout if stdin is a regular file (e.g. from
|
---|
318 | input redirection). */
|
---|
319 | if ((fstat (fd, &tsb) < 0) || S_ISREG (tsb.st_mode))
|
---|
320 | tmout = 0;
|
---|
321 | }
|
---|
322 |
|
---|
323 | if (tmout > 0)
|
---|
324 | {
|
---|
325 | code = setjmp (alrmbuf);
|
---|
326 | if (code)
|
---|
327 | {
|
---|
328 | run_unwind_frame ("read_builtin");
|
---|
329 | return (EXECUTION_FAILURE);
|
---|
330 | }
|
---|
331 | old_alrm = set_signal_handler (SIGALRM, sigalrm);
|
---|
332 | add_unwind_protect (reset_alarm, (char *)NULL);
|
---|
333 | alarm (tmout);
|
---|
334 | }
|
---|
335 |
|
---|
336 | /* If we've been asked to read only NCHARS chars, or we're using some
|
---|
337 | character other than newline to terminate the line, do the right
|
---|
338 | thing to readline or the tty. */
|
---|
339 | if (nchars > 0 || delim != '\n')
|
---|
340 | {
|
---|
341 | #if defined (READLINE)
|
---|
342 | if (edit)
|
---|
343 | {
|
---|
344 | if (nchars > 0)
|
---|
345 | {
|
---|
346 | unwind_protect_int (rl_num_chars_to_read);
|
---|
347 | rl_num_chars_to_read = nchars;
|
---|
348 | }
|
---|
349 | if (delim != '\n')
|
---|
350 | {
|
---|
351 | set_eol_delim (delim);
|
---|
352 | add_unwind_protect (reset_eol_delim, (char *)NULL);
|
---|
353 | }
|
---|
354 | }
|
---|
355 | else
|
---|
356 | #endif
|
---|
357 | if (input_is_tty)
|
---|
358 | {
|
---|
359 | ttsave ();
|
---|
360 | if (silent)
|
---|
361 | ttcbreak ();
|
---|
362 | else
|
---|
363 | ttonechar ();
|
---|
364 | add_unwind_protect ((Function *)ttrestore, (char *)NULL);
|
---|
365 | }
|
---|
366 | }
|
---|
367 | else if (silent) /* turn off echo but leave term in canonical mode */
|
---|
368 | {
|
---|
369 | ttsave ();
|
---|
370 | ttnoecho ();
|
---|
371 | add_unwind_protect ((Function *)ttrestore, (char *)NULL);
|
---|
372 | }
|
---|
373 |
|
---|
374 | /* This *must* be the top unwind-protect on the stack, so the manipulation
|
---|
375 | of the unwind-protect stack after the realloc() works right. */
|
---|
376 | add_unwind_protect (xfree, input_string);
|
---|
377 | interrupt_immediately++;
|
---|
378 |
|
---|
379 | unbuffered_read = (nchars > 0) || (delim != '\n') || input_is_pipe;
|
---|
380 |
|
---|
381 | #if (defined (__CYGWIN__) || defined (__OS2__)) && defined (O_TEXT)
|
---|
382 | setmode (0, O_TEXT);
|
---|
383 | #endif
|
---|
384 |
|
---|
385 | for (eof = retval = 0;;)
|
---|
386 | {
|
---|
387 | #if defined (READLINE)
|
---|
388 | if (edit)
|
---|
389 | {
|
---|
390 | if (rlbuf && rlbuf[rlind] == '\0')
|
---|
391 | {
|
---|
392 | xfree (rlbuf);
|
---|
393 | rlbuf = (char *)0;
|
---|
394 | }
|
---|
395 | if (rlbuf == 0)
|
---|
396 | {
|
---|
397 | rlbuf = edit_line (prompt ? prompt : "");
|
---|
398 | rlind = 0;
|
---|
399 | }
|
---|
400 | if (rlbuf == 0)
|
---|
401 | {
|
---|
402 | eof = 1;
|
---|
403 | break;
|
---|
404 | }
|
---|
405 | c = rlbuf[rlind++];
|
---|
406 | }
|
---|
407 | else
|
---|
408 | {
|
---|
409 | #endif
|
---|
410 |
|
---|
411 | if (unbuffered_read)
|
---|
412 | retval = zread (fd, &c, 1);
|
---|
413 | else
|
---|
414 | retval = zreadc (fd, &c);
|
---|
415 |
|
---|
416 | if (retval <= 0)
|
---|
417 | {
|
---|
418 | eof = 1;
|
---|
419 | break;
|
---|
420 | }
|
---|
421 |
|
---|
422 | #if defined (READLINE)
|
---|
423 | }
|
---|
424 | #endif
|
---|
425 |
|
---|
426 | if (i + 2 >= size)
|
---|
427 | {
|
---|
428 | input_string = (char *)xrealloc (input_string, size += 128);
|
---|
429 | remove_unwind_protect ();
|
---|
430 | add_unwind_protect (xfree, input_string);
|
---|
431 | }
|
---|
432 |
|
---|
433 | /* If the next character is to be accepted verbatim, a backslash
|
---|
434 | newline pair still disappears from the input. */
|
---|
435 | if (pass_next)
|
---|
436 | {
|
---|
437 | pass_next = 0;
|
---|
438 | if (c == '\n')
|
---|
439 | i--; /* back up over the CTLESC */
|
---|
440 | else
|
---|
441 | goto add_char;
|
---|
442 | continue;
|
---|
443 | }
|
---|
444 |
|
---|
445 | if (c == '\\' && raw == 0)
|
---|
446 | {
|
---|
447 | pass_next++;
|
---|
448 | saw_escape++;
|
---|
449 | input_string[i++] = CTLESC;
|
---|
450 | continue;
|
---|
451 | }
|
---|
452 |
|
---|
453 | if ((unsigned char)c == delim)
|
---|
454 | break;
|
---|
455 |
|
---|
456 | if (c == CTLESC || c == CTLNUL)
|
---|
457 | {
|
---|
458 | saw_escape++;
|
---|
459 | input_string[i++] = CTLESC;
|
---|
460 | }
|
---|
461 |
|
---|
462 | add_char:
|
---|
463 | input_string[i++] = c;
|
---|
464 | nr++;
|
---|
465 |
|
---|
466 | if (nchars > 0 && nr >= nchars)
|
---|
467 | break;
|
---|
468 | }
|
---|
469 | input_string[i] = '\0';
|
---|
470 |
|
---|
471 | #if 1
|
---|
472 | if (retval < 0)
|
---|
473 | {
|
---|
474 | builtin_error (_("read error: %d: %s"), fd, strerror (errno));
|
---|
475 | return (EXECUTION_FAILURE);
|
---|
476 | }
|
---|
477 | #endif
|
---|
478 |
|
---|
479 | if (tmout > 0)
|
---|
480 | reset_alarm ();
|
---|
481 |
|
---|
482 | if (nchars > 0 || delim != '\n')
|
---|
483 | {
|
---|
484 | #if defined (READLINE)
|
---|
485 | if (edit)
|
---|
486 | {
|
---|
487 | if (nchars > 0)
|
---|
488 | rl_num_chars_to_read = 0;
|
---|
489 | if (delim != '\n')
|
---|
490 | reset_eol_delim ((char *)NULL);
|
---|
491 | }
|
---|
492 | else
|
---|
493 | #endif
|
---|
494 | if (input_is_tty)
|
---|
495 | ttrestore ();
|
---|
496 | }
|
---|
497 | else if (silent)
|
---|
498 | ttrestore ();
|
---|
499 |
|
---|
500 | if (unbuffered_read == 0)
|
---|
501 | zsyncfd (fd);
|
---|
502 |
|
---|
503 | interrupt_immediately--;
|
---|
504 | discard_unwind_frame ("read_builtin");
|
---|
505 |
|
---|
506 | retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
|
---|
507 |
|
---|
508 | #if defined (ARRAY_VARS)
|
---|
509 | /* If -a was given, take the string read, break it into a list of words,
|
---|
510 | an assign them to `arrayname' in turn. */
|
---|
511 | if (arrayname)
|
---|
512 | {
|
---|
513 | if (legal_identifier (arrayname) == 0)
|
---|
514 | {
|
---|
515 | sh_invalidid (arrayname);
|
---|
516 | xfree (input_string);
|
---|
517 | return (EXECUTION_FAILURE);
|
---|
518 | }
|
---|
519 |
|
---|
520 | var = find_or_make_array_variable (arrayname, 1);
|
---|
521 | if (var == 0)
|
---|
522 | return EXECUTION_FAILURE; /* readonly or noassign */
|
---|
523 | array_flush (array_cell (var));
|
---|
524 |
|
---|
525 | alist = list_string (input_string, ifs_chars, 0);
|
---|
526 | if (alist)
|
---|
527 | {
|
---|
528 | word_list_remove_quoted_nulls (alist);
|
---|
529 | assign_array_var_from_word_list (var, alist, 0);
|
---|
530 | dispose_words (alist);
|
---|
531 | }
|
---|
532 | xfree (input_string);
|
---|
533 | return (retval);
|
---|
534 | }
|
---|
535 | #endif /* ARRAY_VARS */
|
---|
536 |
|
---|
537 | /* If there are no variables, save the text of the line read to the
|
---|
538 | variable $REPLY. ksh93 strips leading and trailing IFS whitespace,
|
---|
539 | so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the
|
---|
540 | same way, but I believe that the difference in behaviors is useful
|
---|
541 | enough to not do it. Without the bash behavior, there is no way
|
---|
542 | to read a line completely without interpretation or modification
|
---|
543 | unless you mess with $IFS (e.g., setting it to the empty string).
|
---|
544 | If you disagree, change the occurrences of `#if 0' to `#if 1' below. */
|
---|
545 | if (list == 0)
|
---|
546 | {
|
---|
547 | #if 0
|
---|
548 | orig_input_string = input_string;
|
---|
549 | for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++)
|
---|
550 | ;
|
---|
551 | input_string = t;
|
---|
552 | input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
|
---|
553 | #endif
|
---|
554 |
|
---|
555 | if (saw_escape)
|
---|
556 | {
|
---|
557 | t = dequote_string (input_string);
|
---|
558 | var = bind_variable ("REPLY", t, 0);
|
---|
559 | free (t);
|
---|
560 | }
|
---|
561 | else
|
---|
562 | var = bind_variable ("REPLY", input_string, 0);
|
---|
563 | VUNSETATTR (var, att_invisible);
|
---|
564 |
|
---|
565 | free (input_string);
|
---|
566 | return (retval);
|
---|
567 | }
|
---|
568 |
|
---|
569 | /* This code implements the Posix.2 spec for splitting the words
|
---|
570 | read and assigning them to variables. */
|
---|
571 | orig_input_string = input_string;
|
---|
572 |
|
---|
573 | /* Remove IFS white space at the beginning of the input string. If
|
---|
574 | $IFS is null, no field splitting is performed. */
|
---|
575 | for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++)
|
---|
576 | ;
|
---|
577 | input_string = t;
|
---|
578 |
|
---|
579 | for (; list->next; list = list->next)
|
---|
580 | {
|
---|
581 | varname = list->word->word;
|
---|
582 | #if defined (ARRAY_VARS)
|
---|
583 | if (legal_identifier (varname) == 0 && valid_array_reference (varname) == 0)
|
---|
584 | #else
|
---|
585 | if (legal_identifier (varname) == 0)
|
---|
586 | #endif
|
---|
587 | {
|
---|
588 | sh_invalidid (varname);
|
---|
589 | xfree (orig_input_string);
|
---|
590 | return (EXECUTION_FAILURE);
|
---|
591 | }
|
---|
592 |
|
---|
593 | /* If there are more variables than words read from the input,
|
---|
594 | the remaining variables are set to the empty string. */
|
---|
595 | if (*input_string)
|
---|
596 | {
|
---|
597 | /* This call updates INPUT_STRING. */
|
---|
598 | t = get_word_from_string (&input_string, ifs_chars, &e);
|
---|
599 | if (t)
|
---|
600 | *e = '\0';
|
---|
601 | /* Don't bother to remove the CTLESC unless we added one
|
---|
602 | somewhere while reading the string. */
|
---|
603 | if (t && saw_escape)
|
---|
604 | {
|
---|
605 | t1 = dequote_string (t);
|
---|
606 | var = bind_read_variable (varname, t1);
|
---|
607 | xfree (t1);
|
---|
608 | }
|
---|
609 | else
|
---|
610 | var = bind_read_variable (varname, t);
|
---|
611 | }
|
---|
612 | else
|
---|
613 | {
|
---|
614 | t = (char *)0;
|
---|
615 | var = bind_read_variable (varname, "");
|
---|
616 | }
|
---|
617 |
|
---|
618 | FREE (t);
|
---|
619 | if (var == 0)
|
---|
620 | {
|
---|
621 | xfree (orig_input_string);
|
---|
622 | return (EXECUTION_FAILURE);
|
---|
623 | }
|
---|
624 |
|
---|
625 | stupidly_hack_special_variables (varname);
|
---|
626 | VUNSETATTR (var, att_invisible);
|
---|
627 | }
|
---|
628 |
|
---|
629 | /* Now assign the rest of the line to the last variable argument. */
|
---|
630 | #if defined (ARRAY_VARS)
|
---|
631 | if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word) == 0)
|
---|
632 | #else
|
---|
633 | if (legal_identifier (list->word->word) == 0)
|
---|
634 | #endif
|
---|
635 | {
|
---|
636 | sh_invalidid (list->word->word);
|
---|
637 | xfree (orig_input_string);
|
---|
638 | return (EXECUTION_FAILURE);
|
---|
639 | }
|
---|
640 |
|
---|
641 | #if 0
|
---|
642 | /* This has to be done this way rather than using string_list
|
---|
643 | and list_string because Posix.2 says that the last variable gets the
|
---|
644 | remaining words and their intervening separators. */
|
---|
645 | input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
|
---|
646 | #else
|
---|
647 | /* Check whether or not the number of fields is exactly the same as the
|
---|
648 | number of variables. */
|
---|
649 | if (*input_string)
|
---|
650 | {
|
---|
651 | t1 = input_string;
|
---|
652 | t = get_word_from_string (&input_string, ifs_chars, &e);
|
---|
653 | if (*input_string == 0)
|
---|
654 | input_string = t;
|
---|
655 | else
|
---|
656 | input_string = strip_trailing_ifs_whitespace (t1, ifs_chars, saw_escape);
|
---|
657 | }
|
---|
658 | #endif
|
---|
659 |
|
---|
660 | if (saw_escape)
|
---|
661 | {
|
---|
662 | t = dequote_string (input_string);
|
---|
663 | var = bind_read_variable (list->word->word, t);
|
---|
664 | xfree (t);
|
---|
665 | }
|
---|
666 | else
|
---|
667 | var = bind_read_variable (list->word->word, input_string);
|
---|
668 | stupidly_hack_special_variables (list->word->word);
|
---|
669 | if (var)
|
---|
670 | VUNSETATTR (var, att_invisible);
|
---|
671 | xfree (orig_input_string);
|
---|
672 |
|
---|
673 | return (retval);
|
---|
674 | }
|
---|
675 |
|
---|
676 | static SHELL_VAR *
|
---|
677 | bind_read_variable (name, value)
|
---|
678 | char *name, *value;
|
---|
679 | {
|
---|
680 | #if defined (ARRAY_VARS)
|
---|
681 | if (valid_array_reference (name) == 0)
|
---|
682 | return (bind_variable (name, value, 0));
|
---|
683 | else
|
---|
684 | return (assign_array_element (name, value, 0));
|
---|
685 | #else /* !ARRAY_VARS */
|
---|
686 | return bind_variable (name, value, 0);
|
---|
687 | #endif /* !ARRAY_VARS */
|
---|
688 | }
|
---|
689 |
|
---|
690 | #if defined (READLINE)
|
---|
691 | static rl_completion_func_t *old_attempted_completion_function;
|
---|
692 |
|
---|
693 | static char *
|
---|
694 | edit_line (p)
|
---|
695 | char *p;
|
---|
696 | {
|
---|
697 | char *ret;
|
---|
698 | int len;
|
---|
699 |
|
---|
700 | if (bash_readline_initialized == 0)
|
---|
701 | initialize_readline ();
|
---|
702 | old_attempted_completion_function = rl_attempted_completion_function;
|
---|
703 | rl_attempted_completion_function = (rl_completion_func_t *)NULL;
|
---|
704 | ret = readline (p);
|
---|
705 | rl_attempted_completion_function = old_attempted_completion_function;
|
---|
706 | if (ret == 0)
|
---|
707 | return ret;
|
---|
708 | len = strlen (ret);
|
---|
709 | ret = (char *)xrealloc (ret, len + 2);
|
---|
710 | ret[len++] = delim;
|
---|
711 | ret[len] = '\0';
|
---|
712 | return ret;
|
---|
713 | }
|
---|
714 |
|
---|
715 | static int old_delim_ctype;
|
---|
716 | static rl_command_func_t *old_delim_func;
|
---|
717 | static int old_newline_ctype;
|
---|
718 | static rl_command_func_t *old_newline_func;
|
---|
719 |
|
---|
720 | static unsigned char delim_char;
|
---|
721 |
|
---|
722 | static void
|
---|
723 | set_eol_delim (c)
|
---|
724 | int c;
|
---|
725 | {
|
---|
726 | Keymap cmap;
|
---|
727 |
|
---|
728 | if (bash_readline_initialized == 0)
|
---|
729 | initialize_readline ();
|
---|
730 | cmap = rl_get_keymap ();
|
---|
731 |
|
---|
732 | /* Change newline to self-insert */
|
---|
733 | old_newline_ctype = cmap[RETURN].type;
|
---|
734 | old_newline_func = cmap[RETURN].function;
|
---|
735 | cmap[RETURN].type = ISFUNC;
|
---|
736 | cmap[RETURN].function = rl_insert;
|
---|
737 |
|
---|
738 | /* Bind the delimiter character to accept-line. */
|
---|
739 | old_delim_ctype = cmap[c].type;
|
---|
740 | old_delim_func = cmap[c].function;
|
---|
741 | cmap[c].type = ISFUNC;
|
---|
742 | cmap[c].function = rl_newline;
|
---|
743 |
|
---|
744 | delim_char = c;
|
---|
745 | }
|
---|
746 |
|
---|
747 | static void
|
---|
748 | reset_eol_delim (cp)
|
---|
749 | char *cp;
|
---|
750 | {
|
---|
751 | Keymap cmap;
|
---|
752 |
|
---|
753 | cmap = rl_get_keymap ();
|
---|
754 |
|
---|
755 | cmap[RETURN].type = old_newline_ctype;
|
---|
756 | cmap[RETURN].function = old_newline_func;
|
---|
757 |
|
---|
758 | cmap[delim_char].type = old_delim_ctype;
|
---|
759 | cmap[delim_char].function = old_delim_func;
|
---|
760 | }
|
---|
761 | #endif
|
---|