<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body text="#000000" bgcolor="#ffffff">
<tt>Michael Brown wrote:</tt>
<blockquote type="cite" cite="mid:201003051630.24203.mbrown@fensystems.co.uk">
<title>Re: [gPXE-devel] Minor Scripting Improvements</title>
<!-- Converted from text/plain format -->
<p><tt><font size="2">Looking at the patch itself...<br>
<br>
Could this be rearranged to avoid goto? We generally use goto only for<br>
structured error clean-up.<br>
<br>
Also, using -ENOTSUP as a magic value meaning "loop" seems kind of
icky. <br>
There's a similarity between "exit" and "loopif" here; both commands
need to<br>
set temporary state that affects the "move to next line of script"
logic. <br>
Maybe have "loopif" set a flag as well; still fairly icky but at least
it's<br>
icky in the same way that "exit" currently is.</font></tt></p>
</blockquote>
<tt><br>
Or perhaps this patch, which costs 82 bytes uncompressed, and uses a
separate looping variable.<br>
<br>
- Shao Miller<br>
-----<br>
<br>
diff --git a/src/hci/shell.c b/src/hci/shell.c<br>
index 5bedbdc..825dac3 100644<br>
--- a/src/hci/shell.c<br>
+++ b/src/hci/shell.c<br>
@@ -35,13 +35,13 @@ FILE_LICENCE ( GPL2_OR_LATER );<br>
static const char shell_prompt[] = "gPXE> ";<br>
<br>
/** Flag set in order to exit shell */<br>
-static int exit_flag = 0;<br>
+int shell_exit_flag = 0;<br>
<br>
/** "exit" command body */<br>
static int exit_exec ( int argc, char **argv __unused ) {<br>
<br>
if ( argc == 1 ) {<br>
- exit_flag = 1;<br>
+ shell_exit_flag = 1;<br>
} else {<br>
printf ( "Usage: exit\n"<br>
"Exits the command shell\n" );<br>
@@ -91,8 +91,8 @@ struct command help_command __command = {<br>
void shell ( void ) {<br>
char *line;<br>
<br>
- exit_flag = 0;<br>
- while ( ! exit_flag ) {<br>
+ shell_exit_flag = 0;<br>
+ while ( ! shell_exit_flag ) {<br>
line = readline ( shell_prompt );<br>
if ( line ) {<br>
system ( line );<br>
diff --git a/src/image/script.c b/src/image/script.c<br>
old mode 100644<br>
new mode 100755<br>
index 0835ecb..fd1d4a2<br>
--- a/src/image/script.c<br>
+++ b/src/image/script.c<br>
@@ -29,10 +29,15 @@ FILE_LICENCE ( GPL2_OR_LATER );<br>
#include <stdlib.h><br>
#include <ctype.h><br>
#include <errno.h><br>
+#include <gpxe/command.h><br>
#include <gpxe/image.h><br>
+#include <gpxe/shell.h><br>
<br>
struct image_type script_image_type __image_type ( PROBE_NORMAL );<br>
<br>
+/** Flag cleared in order to loop the current script */<br>
+static int keep_offset = 1;<br>
+<br>
/**<br>
* Execute script<br>
*<br>
@@ -51,7 +56,10 @@ static int script_exec ( struct image *image ) {<br>
unregister_image ( image );<br>
<br>
while ( offset < image->len ) {<br>
- <br>
+ /* Reset the exit and loop flags */<br>
+ shell_exit_flag = 0;<br>
+ keep_offset = 1;<br>
+<br>
/* Find length of next line, excluding any terminating '\n' */<br>
eol = memchr_user ( image->data, offset, '\n',<br>
( image->len - offset ) );<br>
@@ -66,15 +74,19 @@ static int script_exec ( struct image *image ) {<br>
copy_from_user ( cmdbuf, image->data, offset, len );<br>
cmdbuf[len] = '\0';<br>
DBG ( "$ %s\n", cmdbuf );<br>
- if ( ( rc = system ( cmdbuf ) ) != 0 ) {<br>
- DBG ( "Command \"%s\" failed: %s\n",<br>
+ rc = system ( cmdbuf );<br>
+ rc |= shell_exit_flag;<br>
+ if ( rc ) {<br>
+ DBG ( "Command \"%s\" failed or exited: %s\n",<br>
cmdbuf, strerror ( rc ) );<br>
goto done;<br>
}<br>
}<br>
- <br>
+<br>
/* Move to next line */<br>
offset += ( len + 1 );<br>
+ /* "loopif" command might want us to reset the offset */<br>
+ offset *= keep_offset;<br>
}<br>
<br>
rc = 0;<br>
@@ -124,3 +136,16 @@ struct image_type script_image_type __image_type (
PROBE_NORMAL ) = {<br>
.load = script_load,<br>
.exec = script_exec,<br>
};<br>
+<br>
+/** "loopif" command body */<br>
+static int loopif_exec ( int argc, char **argv ) {<br>
+ if ( argc > 1 && strtoul ( argv[1], NULL, 0 ) )<br>
+ keep_offset = 0;<br>
+ return 0;<br>
+}<br>
+<br>
+/** "loopif" command definition */<br>
+struct command loopif_command __command = {<br>
+ .name = "loopif",<br>
+ .exec = loopif_exec,<br>
+};<br>
diff --git a/src/include/gpxe/shell.h b/src/include/gpxe/shell.h<br>
index a65a344..148ea83 100644<br>
--- a/src/include/gpxe/shell.h<br>
+++ b/src/include/gpxe/shell.h<br>
@@ -9,6 +9,7 @@<br>
<br>
FILE_LICENCE ( GPL2_OR_LATER );<br>
<br>
+extern int shell_exit_flag;<br>
extern void shell ( void );<br>
<br>
#endif /* _GPXE_SHELL_H */<br>
<br>
</tt>
</body>
</html>