Kaynağa Gözat

[script] Allow "exit" to exit a script

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 yıl önce
ebeveyn
işleme
84aa702ff8
4 değiştirilmiş dosya ile 92 ekleme ve 45 silme
  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 Dosyayı Görüntüle

@@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
29 29
 #include <assert.h>
30 30
 #include <ipxe/tables.h>
31 31
 #include <ipxe/command.h>
32
+#include <ipxe/parseopt.h>
32 33
 #include <ipxe/settings.h>
33 34
 
34 35
 /** @file
@@ -37,9 +38,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
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 45
  * Execute command
@@ -270,6 +270,9 @@ int system ( const char *command ) {
270 270
 	int count;
271 271
 	int rc = 0;
272 272
 
273
+	/* Reset exit flag */
274
+	shell_exit = 0;
275
+
273 276
 	/* Perform variable expansion */
274 277
 	expcmd = expand_command ( command );
275 278
 	if ( ! expcmd )
@@ -294,6 +297,10 @@ int system ( const char *command ) {
294 297
 			argv[argc] = NULL;
295 298
 			rc = execv ( argv[0], argv );
296 299
 
300
+			/* Check exit flag */
301
+			if ( shell_exit )
302
+				break;
303
+
297 304
 			/* Handle terminator */
298 305
 			if ( terminator ( rc ) )
299 306
 				break;
@@ -307,7 +314,7 @@ int system ( const char *command ) {
307 314
 }
308 315
 
309 316
 /**
310
- * The "echo" command
317
+ * "echo" command
311 318
  *
312 319
  * @v argc		Argument count
313 320
  * @v argv		Argument list
@@ -328,3 +335,49 @@ struct command echo_command __command = {
328 335
 	.name = "echo",
329 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 Dosyayı Görüntüle

@@ -21,8 +21,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
21 21
 #include <stdint.h>
22 22
 #include <stdlib.h>
23 23
 #include <stdio.h>
24
+#include <getopt.h>
24 25
 #include <readline/readline.h>
25 26
 #include <ipxe/command.h>
27
+#include <ipxe/parseopt.h>
26 28
 #include <ipxe/shell.h>
27 29
 
28 30
 /** @file
@@ -34,29 +36,13 @@ FILE_LICENCE ( GPL2_OR_LATER );
34 36
 /** The shell prompt string */
35 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 46
 static int help_exec ( int argc __unused, char **argv __unused ) {
61 47
 	struct command *command;
62 48
 	unsigned int hpos = 0;
@@ -78,7 +64,7 @@ static int help_exec ( int argc __unused, char **argv __unused ) {
78 64
 	return 0;
79 65
 }
80 66
 
81
-/** "help" command definition */
67
+/** "help" command */
82 68
 struct command help_command __command = {
83 69
 	.name = "help",
84 70
 	.exec = help_exec,
@@ -91,12 +77,11 @@ struct command help_command __command = {
91 77
 void shell ( void ) {
92 78
 	char *line;
93 79
 
94
-	exit_flag = 0;
95
-	while ( ! exit_flag ) {
80
+	do {
96 81
 		line = readline ( shell_prompt );
97 82
 		if ( line ) {
98 83
 			system ( line );
99 84
 			free ( line );
100 85
 		}
101
-	}
86
+	} while ( shell_exit == 0 );
102 87
 }

+ 21
- 14
src/image/script.c Dosyayı Görüntüle

@@ -99,23 +99,20 @@ static int process_script ( int ( * process_line ) ( const char *line ),
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 104
  * @v rc		Line processing status
105 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,7 +161,7 @@ static int script_exec ( struct image *image ) {
164 161
 	script = image;
165 162
 
166 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 166
 	/* Restore saved state, re-register image, and return */
170 167
 	script_offset = saved_offset;
@@ -252,6 +249,16 @@ static int goto_find_label ( const char *line ) {
252 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 263
  * "goto" command
257 264
  *
@@ -280,7 +287,7 @@ static int goto_exec ( int argc, char **argv ) {
280 287
 	/* Find label */
281 288
 	saved_offset = script_offset;
282 289
 	if ( ( rc = process_script ( goto_find_label,
283
-				     terminate_on_success ) ) != 0 ) {
290
+				     terminate_on_label_found ) ) != 0 ) {
284 291
 		script_offset = saved_offset;
285 292
 		return rc;
286 293
 	}

+ 2
- 0
src/include/ipxe/command.h Dosyayı Görüntüle

@@ -23,4 +23,6 @@ struct command {
23 23
 
24 24
 #define __command __table_entry ( COMMANDS, 01 )
25 25
 
26
+extern int shell_exit;
27
+
26 28
 #endif /* _IPXE_COMMAND_H */

Loading…
İptal
Kaydet