]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/read.def
Imported from ../bash-1.14.7.tar.gz.
[thirdparty/bash.git] / builtins / read.def
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, 1989, 1991 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 $PRODUCES read.c
23
24 $BUILTIN read
25 $FUNCTION read_builtin
26 $SHORT_DOC read [-r] [name ...]
27 One line is read from the standard input, and the first word is
28 assigned to the first NAME, the second word to the second NAME, etc.
29 with leftover words assigned to the last NAME. Only the characters
30 found in $IFS are recognized as word delimiters. The return code is
31 zero, unless end-of-file is encountered. If the -r option is given,
32 this signifies `raw' input, and backslash processing is disabled.
33 $END
34
35 #include <stdio.h>
36 #include "../shell.h"
37 #include "common.h"
38
39 #define issep(c) (strchr (ifs_chars, (c)) != (char *)0)
40
41 static int stream_close ();
42
43 extern int interrupt_immediately;
44
45 /* Read the value of the shell variables whose names follow.
46 The reading is done from the current input stream, whatever
47 that may be. Successive words of the input line are assigned
48 to the variables mentioned in LIST. The last variable in LIST
49 gets the remainder of the words on the line. If no variables
50 are mentioned in LIST, then the default variable is $REPLY.
51
52 S. R. Bourne's shell complains if you don't name a variable
53 to receive the stuff that is read. GNU's shell doesn't. This
54 allows you to let the user type random things. */
55 read_builtin (list)
56 WORD_LIST *list;
57 {
58 register char *varname;
59 int size, c, i, fildes, raw_mode, pass_next, saw_escape, retval;
60 char *input_string, *orig_input_string, *ifs_chars, *t;
61 FILE *input_stream;
62 SHELL_VAR *var;
63
64 i = 0; /* Index into the string that we are reading. */
65 raw_mode = 0; /* Not reading raw input be default. */
66
67 while (list)
68 {
69 if (ISOPTION (list->word->word, 'r'))
70 {
71 raw_mode = 1;
72 list = list->next;
73 }
74 else if (ISOPTION (list->word->word, '-'))
75 {
76 list = list->next;
77 break;
78 }
79 else if (*list->word->word == '-')
80 {
81 bad_option (list->word->word);
82 builtin_error ("usage: read [-r] [name ...]");
83 return (EX_USAGE);
84 }
85 else
86 break;
87 }
88
89 /* We need unbuffered input from stdin. So we make a new stream with
90 the same file descriptor as stdin, then unbuffer it. */
91 fildes = dup (fileno (stdin));
92
93 if (fildes == -1)
94 return (EXECUTION_FAILURE);
95
96 input_stream = fdopen (fildes, "r");
97
98 if (!input_stream)
99 {
100 close (fildes);
101 return (EXECUTION_FAILURE);
102 }
103
104 var = find_variable ("IFS");
105 ifs_chars = var ? value_cell (var) : " \t\n";
106
107 input_string = xmalloc (size = 128);
108
109 setbuf (input_stream, (char *)NULL);
110
111 begin_unwind_frame ("read_builtin");
112 add_unwind_protect (xfree, input_string);
113 add_unwind_protect (stream_close, input_stream);
114 interrupt_immediately++;
115
116 pass_next = 0; /* Non-zero signifies last char was backslash. */
117 saw_escape = 0; /* Non-zero signifies that we saw an escape char */
118
119 while ((c = getc (input_stream)) != EOF)
120 {
121 if (i + 2 >= size)
122 input_string = xrealloc (input_string, size += 128);
123
124 /* If the next character is to be accepted verbatim, a backslash
125 newline pair still disappears from the input. */
126 if (pass_next)
127 {
128 if (c == '\n')
129 i--; /* back up over the CTLESC */
130 else
131 input_string[i++] = c;
132 pass_next = 0;
133 continue;
134 }
135
136 if (c == '\\' && !raw_mode)
137 {
138 pass_next++;
139 saw_escape++;
140 input_string[i++] = CTLESC;
141 continue;
142 }
143
144 if (c == '\n')
145 break;
146
147 if (c == CTLESC || c == CTLNUL)
148 {
149 saw_escape++;
150 input_string[i++] = CTLESC;
151 }
152
153 input_string[i++] = c;
154 }
155 input_string[i] = '\0';
156
157 interrupt_immediately--;
158 discard_unwind_frame ("read_builtin");
159
160 fclose (input_stream);
161
162 if (c == EOF)
163 {
164 retval = EXECUTION_FAILURE;
165 /* input_string[0] = '\0'; */
166 }
167 else
168 retval = EXECUTION_SUCCESS;
169
170 if (!list)
171 {
172 if (saw_escape)
173 {
174 t = dequote_string (input_string);
175 var = bind_variable ("REPLY", t);
176 free (t);
177 }
178 else
179 var = bind_variable ("REPLY", input_string);
180 var->attributes &= ~att_invisible;
181 free (input_string);
182 }
183 else
184 {
185 /* This code implements the Posix.2 spec for splitting the words
186 read and assigning them to variables. If $IFS is unset, we
187 use the default value of " \t\n". */
188 orig_input_string = input_string;
189
190 /* Remove IFS white space at the beginning of the input string. If
191 $IFS is null, no field splitting is performed. */
192 for (t = input_string; *ifs_chars && spctabnl (*t) && issep (*t); t++)
193 ;
194 input_string = t;
195
196 for (; list->next; list = list->next)
197 {
198 char *e, *t1;
199
200 varname = list->word->word;
201 if (legal_identifier (varname) == 0)
202 {
203 builtin_error ("%s: not a legal variable name", varname);
204 free (orig_input_string);
205 return (EXECUTION_FAILURE);
206 }
207
208 /* If there are more variables than words read from the input,
209 the remaining variables are set to the empty string. */
210 if (*input_string)
211 {
212 /* This call updates INPUT_STRING. */
213 t = get_word_from_string (&input_string, ifs_chars, &e);
214 if (t)
215 *e = '\0';
216 /* Don't bother to remove the CTLESC unless we added one
217 somewhere while reading the string. */
218 if (t && saw_escape)
219 {
220 t1 = dequote_string (t);
221 var = bind_variable (varname, t1);
222 free (t1);
223 }
224 else
225 var = bind_variable (varname, t);
226 }
227 else
228 {
229 t = (char *)0;
230 var = bind_variable (varname, "");
231 }
232
233 stupidly_hack_special_variables (varname);
234 var->attributes &= ~att_invisible;
235
236 if (t)
237 free (t);
238 }
239
240 if (legal_identifier (list->word->word) == 0)
241 {
242 builtin_error ("%s: not a legal variable name", list->word->word);
243 free (orig_input_string);
244 return (EXECUTION_FAILURE);
245 }
246
247 /* This has to be done this way rather than using string_list
248 and list_string because Posix.2 says that the last variable gets the
249 remaining words and their intervening separators. */
250 input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars,
251 saw_escape);
252
253 if (saw_escape)
254 {
255 t = dequote_string (input_string);
256 var = bind_variable (list->word->word, t);
257 free (t);
258 }
259 else
260 var = bind_variable (list->word->word, input_string);
261 stupidly_hack_special_variables (list->word->word);
262 var->attributes &= ~att_invisible;
263 free (orig_input_string);
264 }
265
266 return (retval);
267 }
268
269 /* This way I don't have to know whether fclose () is a
270 function or a macro. */
271 static int
272 stream_close (file)
273 FILE *file;
274 {
275 return (fclose (file));
276 }