aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2012-10-24 23:21:49 -0700
committerMichael Brown <mcb30@ipxe.org>2012-10-24 23:24:43 -0700
commit2c011d77ae0147b8cc68bc4f3c577ebf55b83f16 (patch)
tree4eaa0afca5fcaa5963799408d29eb60b456fc512
parent88e19fcda95fa1ea59d262898001207c4406eb6d (diff)
downloadipxe-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.c14
-rw-r--r--src/hci/readline.c30
-rw-r--r--src/hci/shell.c2
-rw-r--r--src/include/ipxe/errfile.h1
-rw-r--r--src/include/readline/readline.h5
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 */