Skip to content

Commit b5f5f73

Browse files
committedMar 28, 2011
[cmdline] Expand settings within each command-line token individually
Perform settings expansion after tokenisation, and only at the point of executing each command. This allows statements such as dhcp && echo ${net0/ip} to work correctly. Signed-off-by: Michael Brown <mcb30@ipxe.org>
1 parent 1f4c5f9 commit b5f5f73

File tree

1 file changed

+79
-35
lines changed

1 file changed

+79
-35
lines changed
 

‎src/core/exec.c

+79-35
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,45 @@ int shell_stopped ( int stop ) {
216216
return stopped;
217217
}
218218

219+
/**
220+
* Expand settings within a token list
221+
*
222+
* @v argc Argument count
223+
* @v tokens Token list
224+
* @v argv Argument list to fill in
225+
* @ret rc Return status code
226+
*/
227+
static int expand_tokens ( int argc, char **tokens, char **argv ) {
228+
int i;
229+
230+
/* Expand each token in turn */
231+
for ( i = 0 ; i < argc ; i++ ) {
232+
argv[i] = expand_settings ( tokens[i] );
233+
if ( ! argv[i] )
234+
goto err_expand_settings;
235+
}
236+
237+
return 0;
238+
239+
err_expand_settings:
240+
assert ( argv[i] == NULL );
241+
for ( ; i >= 0 ; i-- )
242+
free ( argv[i] );
243+
return -ENOMEM;
244+
}
245+
246+
/**
247+
* Free an expanded token list
248+
*
249+
* @v argv Argument list
250+
*/
251+
static void free_tokens ( char **argv ) {
252+
253+
/* Free each expanded argument */
254+
while ( *argv )
255+
free ( *(argv++) );
256+
}
257+
219258
/**
220259
* Execute command line
221260
*
@@ -225,58 +264,63 @@ int shell_stopped ( int stop ) {
225264
* Execute the named command and arguments.
226265
*/
227266
int system ( const char *command ) {
267+
int count = split_command ( ( char * ) command, NULL );
268+
char *all_tokens[ count + 1 ];
228269
int ( * process_next ) ( int rc );
229-
char *expcmd;
230-
char **argv;
270+
char *command_copy;
271+
char **tokens;
231272
int argc;
232-
int count;
233273
int process;
234274
int rc = 0;
235275

236-
/* Perform variable expansion */
237-
expcmd = expand_settings ( command );
238-
if ( ! expcmd )
276+
/* Create modifiable copy of command */
277+
command_copy = strdup ( command );
278+
if ( ! command_copy )
239279
return -ENOMEM;
240280

241-
/* Count tokens */
242-
count = split_command ( expcmd, NULL );
243-
244-
/* Create token array */
245-
if ( count ) {
246-
char * tokens[count + 1];
247-
248-
split_command ( expcmd, tokens );
249-
tokens[count] = NULL;
250-
process = 1;
281+
/* Split command into tokens */
282+
split_command ( command_copy, all_tokens );
283+
all_tokens[count] = NULL;
251284

252-
for ( argv = tokens ; ; argv += ( argc + 1 ) ) {
285+
/* Process individual commands */
286+
process = 1;
287+
for ( tokens = all_tokens ; ; tokens += ( argc + 1 ) ) {
253288

254-
/* Find command terminator */
255-
argc = command_terminator ( argv, &process_next );
289+
/* Find command terminator */
290+
argc = command_terminator ( tokens, &process_next );
256291

257-
/* Execute command */
258-
if ( process ) {
259-
argv[argc] = NULL;
260-
rc = execv ( argv[0], argv );
261-
}
292+
/* Expand tokens and execute command */
293+
if ( process ) {
294+
char *argv[ argc + 1 ];
262295

263-
/* Stop processing, if applicable */
264-
if ( shell_stopped ( SHELL_STOP_COMMAND ) )
296+
/* Expand tokens */
297+
if ( ( rc = expand_tokens ( argc, tokens, argv ) ) != 0)
265298
break;
299+
argv[argc] = NULL;
266300

267-
/* Stop processing if we have reached the end
268-
* of the command.
269-
*/
270-
if ( ! process_next )
271-
break;
301+
/* Execute command */
302+
rc = execv ( argv[0], argv );
272303

273-
/* Determine whether or not to process next command */
274-
process = process_next ( rc );
304+
/* Free tokens */
305+
free_tokens ( argv );
275306
}
307+
308+
/* Stop processing, if applicable */
309+
if ( shell_stopped ( SHELL_STOP_COMMAND ) )
310+
break;
311+
312+
/* Stop processing if we have reached the end of the
313+
* command.
314+
*/
315+
if ( ! process_next )
316+
break;
317+
318+
/* Determine whether or not to process next command */
319+
process = process_next ( rc );
276320
}
277321

278-
/* Free expanded command */
279-
free ( expcmd );
322+
/* Free modified copy of command */
323+
free ( command_copy );
280324

281325
return rc;
282326
}

0 commit comments

Comments
 (0)
Please sign in to comment.