Browse Source

[script] Allow "exit" to exit a script

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
84aa702ff8
4 changed files with 92 additions and 45 deletions
  1. 57
    4
      src/core/exec.c
  2. 12
    27
      src/hci/shell.c
  3. 21
    14
      src/image/script.c
  4. 2
    0
      src/include/ipxe/command.h

+ 57
- 4
src/core/exec.c View File

29
 #include <assert.h>
29
 #include <assert.h>
30
 #include <ipxe/tables.h>
30
 #include <ipxe/tables.h>
31
 #include <ipxe/command.h>
31
 #include <ipxe/command.h>
32
+#include <ipxe/parseopt.h>
32
 #include <ipxe/settings.h>
33
 #include <ipxe/settings.h>
33
 
34
 
34
 /** @file
35
 /** @file
37
  *
38
  *
38
  */
39
  */
39
 
40
 
40
-/* Avoid dragging in getopt.o unless a command really uses it */
41
-int optind;
42
-int nextchar;
41
+/** Shell exit flag */
42
+int shell_exit;
43
 
43
 
44
 /**
44
 /**
45
  * Execute command
45
  * Execute command
270
 	int count;
270
 	int count;
271
 	int rc = 0;
271
 	int rc = 0;
272
 
272
 
273
+	/* Reset exit flag */
274
+	shell_exit = 0;
275
+
273
 	/* Perform variable expansion */
276
 	/* Perform variable expansion */
274
 	expcmd = expand_command ( command );
277
 	expcmd = expand_command ( command );
275
 	if ( ! expcmd )
278
 	if ( ! expcmd )
294
 			argv[argc] = NULL;
297
 			argv[argc] = NULL;
295
 			rc = execv ( argv[0], argv );
298
 			rc = execv ( argv[0], argv );
296
 
299
 
300
+			/* Check exit flag */
301
+			if ( shell_exit )
302
+				break;
303
+
297
 			/* Handle terminator */
304
 			/* Handle terminator */
298
 			if ( terminator ( rc ) )
305
 			if ( terminator ( rc ) )
299
 				break;
306
 				break;
307
 }
314
 }
308
 
315
 
309
 /**
316
 /**
310
- * The "echo" command
317
+ * "echo" command
311
  *
318
  *
312
  * @v argc		Argument count
319
  * @v argc		Argument count
313
  * @v argv		Argument list
320
  * @v argv		Argument list
328
 	.name = "echo",
335
 	.name = "echo",
329
 	.exec = echo_exec,
336
 	.exec = echo_exec,
330
 };
337
 };
338
+
339
+/** "exit" options */
340
+struct exit_options {};
341
+
342
+/** "exit" option list */
343
+static struct option_descriptor exit_opts[] = {};
344
+
345
+/** "exit" command descriptor */
346
+static struct command_descriptor exit_cmd =
347
+	COMMAND_DESC ( struct exit_options, exit_opts, 0, 1,
348
+		       "[<status>]", "" );
349
+
350
+/**
351
+ * "exit" command
352
+ *
353
+ * @v argc		Argument count
354
+ * @v argv		Argument list
355
+ * @ret rc		Return status code
356
+ */
357
+static int exit_exec ( int argc, char **argv ) {
358
+	struct exit_options opts;
359
+	unsigned int exit_code = 0;
360
+	int rc;
361
+
362
+	/* Parse options */
363
+	if ( ( rc = parse_options ( argc, argv, &exit_cmd, &opts ) ) != 0 )
364
+		return rc;
365
+
366
+	/* Parse exit status, if present */
367
+	if ( optind != argc ) {
368
+		if ( ( rc = parse_integer ( argv[optind], &exit_code ) ) != 0 )
369
+			return rc;
370
+	}
371
+
372
+	/* Set exit flag */
373
+	shell_exit = 1;
374
+
375
+	return exit_code;
376
+}
377
+
378
+/** "exit" command */
379
+struct command exit_command __command = {
380
+	.name = "exit",
381
+	.exec = exit_exec,
382
+};
383
+

+ 12
- 27
src/hci/shell.c View File

21
 #include <stdint.h>
21
 #include <stdint.h>
22
 #include <stdlib.h>
22
 #include <stdlib.h>
23
 #include <stdio.h>
23
 #include <stdio.h>
24
+#include <getopt.h>
24
 #include <readline/readline.h>
25
 #include <readline/readline.h>
25
 #include <ipxe/command.h>
26
 #include <ipxe/command.h>
27
+#include <ipxe/parseopt.h>
26
 #include <ipxe/shell.h>
28
 #include <ipxe/shell.h>
27
 
29
 
28
 /** @file
30
 /** @file
34
 /** The shell prompt string */
36
 /** The shell prompt string */
35
 static const char shell_prompt[] = "iPXE> ";
37
 static const char shell_prompt[] = "iPXE> ";
36
 
38
 
37
-/** Flag set in order to exit shell */
38
-static int exit_flag = 0;
39
-
40
-/** "exit" command body */
41
-static int exit_exec ( int argc, char **argv __unused ) {
42
-
43
-	if ( argc == 1 ) {
44
-		exit_flag = 1;
45
-	} else {
46
-		printf ( "Usage: exit\n"
47
-			 "Exits the command shell\n" );
48
-	}
49
-
50
-	return 0;
51
-}
52
-
53
-/** "exit" command definition */
54
-struct command exit_command __command = {
55
-	.name = "exit",
56
-	.exec = exit_exec,
57
-};
58
-
59
-/** "help" command body */
39
+/**
40
+ * "help" command
41
+ *
42
+ * @v argc		Argument count
43
+ * @v argv		Argument list
44
+ * @ret rc		Return status code
45
+ */
60
 static int help_exec ( int argc __unused, char **argv __unused ) {
46
 static int help_exec ( int argc __unused, char **argv __unused ) {
61
 	struct command *command;
47
 	struct command *command;
62
 	unsigned int hpos = 0;
48
 	unsigned int hpos = 0;
78
 	return 0;
64
 	return 0;
79
 }
65
 }
80
 
66
 
81
-/** "help" command definition */
67
+/** "help" command */
82
 struct command help_command __command = {
68
 struct command help_command __command = {
83
 	.name = "help",
69
 	.name = "help",
84
 	.exec = help_exec,
70
 	.exec = help_exec,
91
 void shell ( void ) {
77
 void shell ( void ) {
92
 	char *line;
78
 	char *line;
93
 
79
 
94
-	exit_flag = 0;
95
-	while ( ! exit_flag ) {
80
+	do {
96
 		line = readline ( shell_prompt );
81
 		line = readline ( shell_prompt );
97
 		if ( line ) {
82
 		if ( line ) {
98
 			system ( line );
83
 			system ( line );
99
 			free ( line );
84
 			free ( line );
100
 		}
85
 		}
101
-	}
86
+	} while ( shell_exit == 0 );
102
 }
87
 }

+ 21
- 14
src/image/script.c View File

99
 }
99
 }
100
 
100
 
101
 /**
101
 /**
102
- * Terminate script processing if line processing failed
102
+ * Terminate script processing on shell exit or command failure
103
  *
103
  *
104
  * @v rc		Line processing status
104
  * @v rc		Line processing status
105
  * @ret terminate	Terminate script processing
105
  * @ret terminate	Terminate script processing
106
  */
106
  */
107
-static int terminate_on_failure ( int rc ) {
108
-	return ( rc != 0 );
109
-}
107
+static int terminate_on_exit_or_failure ( int rc ) {
110
 
108
 
111
-/**
112
- * Terminate script processing if line processing succeeded
113
- *
114
- * @v rc		Line processing status
115
- * @ret terminate	Terminate script processing
116
- */
117
-static int terminate_on_success ( int rc ) {
118
-	return ( rc == 0 );
109
+	/* Check and consume exit flag */
110
+	if ( shell_exit ) {
111
+		shell_exit = 0;
112
+		return 1;
113
+	}
114
+
115
+	return ( rc != 0 );
119
 }
116
 }
120
 
117
 
121
 /**
118
 /**
164
 	script = image;
161
 	script = image;
165
 
162
 
166
 	/* Process script */
163
 	/* Process script */
167
-	rc = process_script ( script_exec_line, terminate_on_failure );
164
+	rc = process_script ( script_exec_line, terminate_on_exit_or_failure );
168
 
165
 
169
 	/* Restore saved state, re-register image, and return */
166
 	/* Restore saved state, re-register image, and return */
170
 	script_offset = saved_offset;
167
 	script_offset = saved_offset;
252
 	return 0;
249
 	return 0;
253
 }
250
 }
254
 
251
 
252
+/**
253
+ * Terminate script processing when label is found
254
+ *
255
+ * @v rc		Line processing status
256
+ * @ret terminate	Terminate script processing
257
+ */
258
+static int terminate_on_label_found ( int rc ) {
259
+	return ( rc == 0 );
260
+}
261
+
255
 /**
262
 /**
256
  * "goto" command
263
  * "goto" command
257
  *
264
  *
280
 	/* Find label */
287
 	/* Find label */
281
 	saved_offset = script_offset;
288
 	saved_offset = script_offset;
282
 	if ( ( rc = process_script ( goto_find_label,
289
 	if ( ( rc = process_script ( goto_find_label,
283
-				     terminate_on_success ) ) != 0 ) {
290
+				     terminate_on_label_found ) ) != 0 ) {
284
 		script_offset = saved_offset;
291
 		script_offset = saved_offset;
285
 		return rc;
292
 		return rc;
286
 	}
293
 	}

+ 2
- 0
src/include/ipxe/command.h View File

23
 
23
 
24
 #define __command __table_entry ( COMMANDS, 01 )
24
 #define __command __table_entry ( COMMANDS, 01 )
25
 
25
 
26
+extern int shell_exit;
27
+
26
 #endif /* _IPXE_COMMAND_H */
28
 #endif /* _IPXE_COMMAND_H */

Loading…
Cancel
Save