[PATCH] [script] Allow looping in a script

Shao Miller shao.miller at yrdsb.edu.on.ca
Fri Mar 5 01:43:40 EST 2010


This commit adds the 'loop' command for scripts.  When this
command is executed with no arguments or a non-zero unsigned
integer argument, the script parser will loop back to the
beginning of the script.  With the argument "0", it will not
loop back to the beginning, but will carry on with the next
line of the script.  A bogus argument is the same as "0".

For example,

 #!gpxe
 # start.gpxe
 set again 1
 dhcp net0
 imgload loop.gpxe
 boot

 #!gpxe
 # loop.gpxe
 chain http://10.0.2.2/control.cgi?ip=${ip}
 sleep 10
 loop ${again}

 $ make EMBEDDED_IMAGE=start.gpxe,loop.gpxe bin/gpxe.pdsk
 $ qemu -fda bin/gpxe.pdsk -boot a

The webserver can return a gPXE script as the response to
the control.cgi query.  If this response were

 #!gpxe
 set again 0

then the gPXE client would break the loop and exit the script.

Code size cost: 50 bytes uncompressed
---
 src/image/script.c |   30 +++++++++++++++++++++++++++++-
 1 files changed, 29 insertions(+), 1 deletions(-)

diff --git a/src/image/script.c b/src/image/script.c
index 4073eb0..2935c48 100644
--- a/src/image/script.c
+++ b/src/image/script.c
@@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <stdlib.h>
 #include <ctype.h>
 #include <errno.h>
+#include <gpxe/command.h>
 #include <gpxe/image.h>
 #include <gpxe/shell.h>
 
@@ -41,7 +42,7 @@ struct image_type script_image_type __image_type ( PROBE_NORMAL );
  * @ret rc		Return status code
  */
 static int script_exec ( struct image *image ) {
-	size_t offset = 0;
+	size_t offset;
 	off_t eol;
 	size_t len;
 	int rc;
@@ -51,6 +52,8 @@ static int script_exec ( struct image *image ) {
 	 */
 	unregister_image ( image );
 
+ start_script:
+	offset = 0;
 	while ( offset < image->len ) {
 	
 		/* Find length of next line, excluding any terminating '\n' */
@@ -86,6 +89,12 @@ static int script_exec ( struct image *image ) {
 	/* Reset exit flag */
 	shell_exit_flag = 0;
 
+	/* Check if we should loop.  We might as well use ENOTSUP,
+	 * since we don't use it for anything else in this file
+	 */
+	if ( rc == -ENOTSUP )
+		goto start_script;
+
 	/* Re-register image and return */
 	register_image ( image );
 	return rc;
@@ -131,3 +140,22 @@ struct image_type script_image_type __image_type ( PROBE_NORMAL ) = {
 	.load = script_load,
 	.exec = script_exec,
 };
+
+/** "loop" command body */
+static int loop_exec ( int argc, char **argv ) {
+	/* We use ENOTSUP, since we don't use it
+	 * for anything else in this file
+	 */
+	if ( argc == 1 )
+		return -ENOTSUP;
+	if ( strtoul ( argv[1], NULL, 0 ) )
+		return -ENOTSUP;
+	return 0;
+}
+
+/** "loop" command definition */
+struct command loop_command __command = {
+	.name = "loop",
+	.exec = loop_exec,
+};
+
-- 
1.5.6.3


--------------030603070009060609000406--


More information about the gPXE-devel mailing list