Michael Brown wrote:

"Exit just the currently executing script" feels cleanest to me.

Maybe "loopif" rather than "loop", to make it more intuitively obvious that
the argument is required?

In the bazaar spirit, 69 bytes seems worth it to me.


Thanks for your feedback, Michael. Attached are both features as one patch. Of course, 'loopif' now brings the cost to 71 bytes, versus the 69 for 'loop'. ;) I agree that 'loopif' makes more sense to the user.

I'll tear down the 'loop' staging branch shortly and put a 'loopif' version there, instead.

I value further feedback from anyone interested.
- Shao Miller
-----

diff --git a/src/hci/shell.c b/src/hci/shell.c
index 5bedbdc..825dac3 100644
--- a/src/hci/shell.c
+++ b/src/hci/shell.c
@@ -35,13 +35,13 @@ FILE_LICENCE ( GPL2_OR_LATER );
static const char shell_prompt[] = "gPXE> ";

/** Flag set in order to exit shell */
-static int exit_flag = 0;
+int shell_exit_flag = 0;

/** "exit" command body */
static int exit_exec ( int argc, char **argv __unused ) {

    if ( argc == 1 ) {
-        exit_flag = 1;
+        shell_exit_flag = 1;
    } else {
        printf ( "Usage: exit\n"
             "Exits the command shell\n" );
@@ -91,8 +91,8 @@ struct command help_command __command = {
void shell ( void ) {
    char *line;

-    exit_flag = 0;
-    while ( ! exit_flag ) {
+    shell_exit_flag = 0;
+    while ( ! shell_exit_flag ) {
        line = readline ( shell_prompt );
        if ( line ) {
            system ( line );
diff --git a/src/image/script.c b/src/image/script.c
index 0835ecb..0597228 100644
--- a/src/image/script.c
+++ b/src/image/script.c
@@ -29,7 +29,9 @@ 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>

struct image_type script_image_type __image_type ( PROBE_NORMAL );

@@ -40,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;
@@ -50,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' */
@@ -73,12 +77,24 @@ static int script_exec ( struct image *image ) {
            }
        }
+ if ( shell_exit_flag )
+            /* "exit" command should exit this script */
+            goto done;
        /* Move to next line */
        offset += ( len + 1 );
    }

    rc = 0;
 done:
+    /* 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;
@@ -124,3 +140,20 @@ struct image_type script_image_type __image_type ( PROBE_NORMAL ) = {
    .load = script_load,
    .exec = script_exec,
};
+
+/** "loopif" command body */
+static int loopif_exec ( int argc, char **argv ) {
+    /* We use ENOTSUP, since we don't use it
+     * for anything else in this file
+     */
+    if ( argc > 1 && strtoul ( argv[1], NULL, 0 ) )
+        return -ENOTSUP;
+    return 0;
+}
+
+/** "loopif" command definition */
+struct command loop_command __command = {
+    .name = "loopif",
+    .exec = loopif_exec,
+};
+
diff --git a/src/include/gpxe/shell.h b/src/include/gpxe/shell.h
index a65a344..148ea83 100644
--- a/src/include/gpxe/shell.h
+++ b/src/include/gpxe/shell.h
@@ -9,6 +9,7 @@

FILE_LICENCE ( GPL2_OR_LATER );

+extern int shell_exit_flag;
extern void shell ( void );

#endif /* _GPXE_SHELL_H */

diff --git a/src/hci/shell.c b/src/hci/shell.c
index 5bedbdc..825dac3 100644
--- a/src/hci/shell.c
+++ b/src/hci/shell.c
@@ -35,13 +35,13 @@ FILE_LICENCE ( GPL2_OR_LATER );
 static const char shell_prompt[] = "gPXE> ";
 
 /** Flag set in order to exit shell */
-static int exit_flag = 0;
+int shell_exit_flag = 0;
 
 /** "exit" command body */
 static int exit_exec ( int argc, char **argv __unused ) {
 
        if ( argc == 1 ) {
-               exit_flag = 1;
+               shell_exit_flag = 1;
        } else {
                printf ( "Usage: exit\n"
                         "Exits the command shell\n" );
@@ -91,8 +91,8 @@ struct command help_command __command = {
 void shell ( void ) {
        char *line;
 
-       exit_flag = 0;
-       while ( ! exit_flag ) {
+       shell_exit_flag = 0;
+       while ( ! shell_exit_flag ) {
                line = readline ( shell_prompt );
                if ( line ) {
                        system ( line );
diff --git a/src/image/script.c b/src/image/script.c
index 0835ecb..0597228 100644
--- a/src/image/script.c
+++ b/src/image/script.c
@@ -29,7 +29,9 @@ 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>
 
 struct image_type script_image_type __image_type ( PROBE_NORMAL );
 
@@ -40,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;
@@ -50,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' */
@@ -73,12 +77,24 @@ static int script_exec ( struct image *image ) {
                        }
                }
                
+               if ( shell_exit_flag )
+                       /* "exit" command should exit this script */
+                       goto done;
                /* Move to next line */
                offset += ( len + 1 );
        }
 
        rc = 0;
  done:
+       /* 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;
@@ -124,3 +140,20 @@ struct image_type script_image_type __image_type ( 
PROBE_NORMAL ) = {
        .load = script_load,
        .exec = script_exec,
 };
+
+/** "loopif" command body */
+static int loopif_exec ( int argc, char **argv ) {
+       /* We use ENOTSUP, since we don't use it
+        * for anything else in this file
+        */
+       if ( argc > 1 && strtoul ( argv[1], NULL, 0 ) )
+               return -ENOTSUP;
+       return 0;
+}
+
+/** "loopif" command definition */
+struct command loop_command __command = {
+       .name = "loopif",
+       .exec = loopif_exec,
+};
+
diff --git a/src/include/gpxe/shell.h b/src/include/gpxe/shell.h
index a65a344..148ea83 100644
--- a/src/include/gpxe/shell.h
+++ b/src/include/gpxe/shell.h
@@ -9,6 +9,7 @@
 
 FILE_LICENCE ( GPL2_OR_LATER );
 
+extern int shell_exit_flag;
 extern void shell ( void );
 
 #endif /* _GPXE_SHELL_H */
_______________________________________________
gPXE-devel mailing list
[email protected]
http://etherboot.org/mailman/listinfo/gpxe-devel

Reply via email to