diff options
author | Michael Brown <mcb30@ipxe.org> | 2012-10-24 23:21:49 -0700 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2012-10-24 23:24:43 -0700 |
commit | 2c011d77ae0147b8cc68bc4f3c577ebf55b83f16 (patch) | |
tree | 4eaa0afca5fcaa5963799408d29eb60b456fc512 | |
parent | 88e19fcda95fa1ea59d262898001207c4406eb6d (diff) | |
download | ipxe-2c011d77ae0147b8cc68bc4f3c577ebf55b83f16.zip ipxe-2c011d77ae0147b8cc68bc4f3c577ebf55b83f16.tar.gz ipxe-2c011d77ae0147b8cc68bc4f3c577ebf55b83f16.tar.bz2 |
[readline] Allow readline_history() to return a meaningful status
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/hci/commands/nvo_cmd.c | 14 | ||||
-rw-r--r-- | src/hci/readline.c | 30 | ||||
-rw-r--r-- | src/hci/shell.c | 2 | ||||
-rw-r--r-- | src/include/ipxe/errfile.h | 1 | ||||
-rw-r--r-- | src/include/readline/readline.h | 5 |
5 files changed, 32 insertions, 20 deletions
diff --git a/src/hci/commands/nvo_cmd.c b/src/hci/commands/nvo_cmd.c index b3775d0..f255bbf 100644 --- a/src/hci/commands/nvo_cmd.c +++ b/src/hci/commands/nvo_cmd.c @@ -213,15 +213,19 @@ static int read_value ( const char *name, char **args __unused, char **value ) { /* Read existing value */ if ( ( rc = fetchf_named_setting_copy ( name, &existing ) ) < 0 ) - return rc; + goto err_existing; /* Read new value */ - *value = readline_history ( NULL, existing, NULL ); + if ( ( rc = readline_history ( NULL, existing, NULL, value ) ) != 0 ) + goto err_new; - /* Free existing value */ - free ( existing ); + /* Success */ + rc = 0; - return 0; + err_new: + free ( existing ); + err_existing: + return rc; } /** diff --git a/src/hci/readline.c b/src/hci/readline.c index a199fb0..d67980b 100644 --- a/src/hci/readline.c +++ b/src/hci/readline.c @@ -22,6 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <errno.h> #include <ipxe/console.h> #include <ipxe/keys.h> #include <ipxe/editstring.h> @@ -244,18 +245,22 @@ void history_free ( struct readline_history *history ) { * @v prefill Prefill string, or NULL for no prefill * @v history History buffer, or NULL for no history * @ret line Line read from console (excluding terminating newline) + * @ret rc Return status code * * The returned line is allocated with malloc(); the caller must * eventually call free() to release the storage. */ -char * readline_history ( const char *prompt, const char *prefill, - struct readline_history *history ) { +int readline_history ( const char *prompt, const char *prefill, + struct readline_history *history, char **line ) { char buf[READLINE_MAX]; struct edit_string string; int key; int move_by; const char *new_string; - char *line; + int rc; + + /* Avoid returning uninitialised data on error */ + *line = NULL; /* Display prompt, if applicable */ if ( prompt ) @@ -280,12 +285,11 @@ char * readline_history ( const char *prompt, const char *prefill, switch ( key ) { case CR: case LF: - line = strdup ( buf ); - if ( ! line ) - printf ( "\nOut of memory" ); + *line = strdup ( buf ); + rc = ( ( *line ) ? 0 : -ENOMEM ); goto done; case CTRL_C: - line = NULL; + rc = -ECANCELED; goto done; case KEY_UP: move_by = 1; @@ -311,11 +315,12 @@ char * readline_history ( const char *prompt, const char *prefill, done: putchar ( '\n' ); if ( history ) { - if ( line && line[0] ) - history_append ( history, line ); + if ( *line && (*line)[0] ) + history_append ( history, *line ); history_cleanup ( history ); } - return line; + assert ( ( rc == 0 ) ^ ( *line == NULL ) ); + return rc; } /** @@ -328,5 +333,8 @@ char * readline_history ( const char *prompt, const char *prefill, * eventually call free() to release the storage. */ char * readline ( const char *prompt ) { - return readline_history ( prompt, NULL, NULL ); + char *line; + + readline_history ( prompt, NULL, NULL, &line ); + return line; } diff --git a/src/hci/shell.c b/src/hci/shell.c index f4cf9bc..b620867 100644 --- a/src/hci/shell.c +++ b/src/hci/shell.c @@ -86,7 +86,7 @@ int shell ( void ) { /* Read and execute commands */ do { - line = readline_history ( shell_prompt, NULL, &history ); + readline_history ( shell_prompt, NULL, &history, &line ); if ( line ) { rc = system ( line ); free ( line ); diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h index dd63225..514e1f8 100644 --- a/src/include/ipxe/errfile.h +++ b/src/include/ipxe/errfile.h @@ -264,6 +264,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define ERRFILE_ocsp ( ERRFILE_OTHER | 0x002f0000 ) #define ERRFILE_nslookup ( ERRFILE_OTHER | 0x00300000 ) #define ERRFILE_efi_snp_hii ( ERRFILE_OTHER | 0x00310000 ) +#define ERRFILE_readline ( ERRFILE_OTHER | 0x00320000 ) /** @} */ diff --git a/src/include/readline/readline.h b/src/include/readline/readline.h index 8b15997..0449a3f 100644 --- a/src/include/readline/readline.h +++ b/src/include/readline/readline.h @@ -50,9 +50,8 @@ struct readline_history { }; extern void history_free ( struct readline_history *history ); -extern char * __malloc readline_history ( const char *prompt, - const char *prefill, - struct readline_history *history ); +extern int readline_history ( const char *prompt, const char *prefill, + struct readline_history *history, char **line ); extern char * __malloc readline ( const char *prompt ); #endif /* _READLINE_H */ |