[readline] Allow readline_history() to return a meaningful status

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/598/head
Michael Brown 2012-10-24 23:21:49 -07:00
parent 88e19fcda9
commit 2c011d77ae
5 changed files with 32 additions and 20 deletions

View File

@ -213,15 +213,19 @@ static int read_value ( const char *name, char **args __unused, char **value ) {
/* Read existing value */ /* Read existing value */
if ( ( rc = fetchf_named_setting_copy ( name, &existing ) ) < 0 ) if ( ( rc = fetchf_named_setting_copy ( name, &existing ) ) < 0 )
return rc; goto err_existing;
/* Read new value */ /* Read new value */
*value = readline_history ( NULL, existing, NULL ); if ( ( rc = readline_history ( NULL, existing, NULL, value ) ) != 0 )
goto err_new;
/* Free existing value */ /* Success */
rc = 0;
err_new:
free ( existing ); free ( existing );
err_existing:
return 0; return rc;
} }
/** /**

View File

@ -22,6 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h>
#include <ipxe/console.h> #include <ipxe/console.h>
#include <ipxe/keys.h> #include <ipxe/keys.h>
#include <ipxe/editstring.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 prefill Prefill string, or NULL for no prefill
* @v history History buffer, or NULL for no history * @v history History buffer, or NULL for no history
* @ret line Line read from console (excluding terminating newline) * @ret line Line read from console (excluding terminating newline)
* @ret rc Return status code
* *
* The returned line is allocated with malloc(); the caller must * The returned line is allocated with malloc(); the caller must
* eventually call free() to release the storage. * eventually call free() to release the storage.
*/ */
char * readline_history ( const char *prompt, const char *prefill, int readline_history ( const char *prompt, const char *prefill,
struct readline_history *history ) { struct readline_history *history, char **line ) {
char buf[READLINE_MAX]; char buf[READLINE_MAX];
struct edit_string string; struct edit_string string;
int key; int key;
int move_by; int move_by;
const char *new_string; const char *new_string;
char *line; int rc;
/* Avoid returning uninitialised data on error */
*line = NULL;
/* Display prompt, if applicable */ /* Display prompt, if applicable */
if ( prompt ) if ( prompt )
@ -280,12 +285,11 @@ char * readline_history ( const char *prompt, const char *prefill,
switch ( key ) { switch ( key ) {
case CR: case CR:
case LF: case LF:
line = strdup ( buf ); *line = strdup ( buf );
if ( ! line ) rc = ( ( *line ) ? 0 : -ENOMEM );
printf ( "\nOut of memory" );
goto done; goto done;
case CTRL_C: case CTRL_C:
line = NULL; rc = -ECANCELED;
goto done; goto done;
case KEY_UP: case KEY_UP:
move_by = 1; move_by = 1;
@ -311,11 +315,12 @@ char * readline_history ( const char *prompt, const char *prefill,
done: done:
putchar ( '\n' ); putchar ( '\n' );
if ( history ) { if ( history ) {
if ( line && line[0] ) if ( *line && (*line)[0] )
history_append ( history, line ); history_append ( history, *line );
history_cleanup ( history ); 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. * eventually call free() to release the storage.
*/ */
char * readline ( const char *prompt ) { char * readline ( const char *prompt ) {
return readline_history ( prompt, NULL, NULL ); char *line;
readline_history ( prompt, NULL, NULL, &line );
return line;
} }

View File

@ -86,7 +86,7 @@ int shell ( void ) {
/* Read and execute commands */ /* Read and execute commands */
do { do {
line = readline_history ( shell_prompt, NULL, &history ); readline_history ( shell_prompt, NULL, &history, &line );
if ( line ) { if ( line ) {
rc = system ( line ); rc = system ( line );
free ( line ); free ( line );

View File

@ -264,6 +264,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_ocsp ( ERRFILE_OTHER | 0x002f0000 ) #define ERRFILE_ocsp ( ERRFILE_OTHER | 0x002f0000 )
#define ERRFILE_nslookup ( ERRFILE_OTHER | 0x00300000 ) #define ERRFILE_nslookup ( ERRFILE_OTHER | 0x00300000 )
#define ERRFILE_efi_snp_hii ( ERRFILE_OTHER | 0x00310000 ) #define ERRFILE_efi_snp_hii ( ERRFILE_OTHER | 0x00310000 )
#define ERRFILE_readline ( ERRFILE_OTHER | 0x00320000 )
/** @} */ /** @} */

View File

@ -50,9 +50,8 @@ struct readline_history {
}; };
extern void history_free ( struct readline_history *history ); extern void history_free ( struct readline_history *history );
extern char * __malloc readline_history ( const char *prompt, extern int readline_history ( const char *prompt, const char *prefill,
const char *prefill, struct readline_history *history, char **line );
struct readline_history *history );
extern char * __malloc readline ( const char *prompt ); extern char * __malloc readline ( const char *prompt );
#endif /* _READLINE_H */ #endif /* _READLINE_H */