Browse Source

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

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 11 years ago
parent
commit
2c011d77ae
5 changed files with 32 additions and 20 deletions
  1. 9
    5
      src/hci/commands/nvo_cmd.c
  2. 19
    11
      src/hci/readline.c
  3. 1
    1
      src/hci/shell.c
  4. 1
    0
      src/include/ipxe/errfile.h
  5. 2
    3
      src/include/readline/readline.h

+ 9
- 5
src/hci/commands/nvo_cmd.c View File

@@ -213,15 +213,19 @@ static int read_value ( const char *name, char **args __unused, char **value ) {
213 213
 
214 214
 	/* Read existing value */
215 215
 	if ( ( rc = fetchf_named_setting_copy ( name, &existing ) ) < 0 )
216
-		return rc;
216
+		goto err_existing;
217 217
 
218 218
 	/* Read new value */
219
-	*value = readline_history ( NULL, existing, NULL );
219
+	if ( ( rc = readline_history ( NULL, existing, NULL, value ) ) != 0 )
220
+		goto err_new;
220 221
 
221
-	/* Free existing value */
222
-	free ( existing );
222
+	/* Success */
223
+	rc = 0;
223 224
 
224
-	return 0;
225
+ err_new:
226
+	free ( existing );
227
+ err_existing:
228
+	return rc;
225 229
 }
226 230
 
227 231
 /**

+ 19
- 11
src/hci/readline.c View File

@@ -22,6 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
22 22
 #include <stdio.h>
23 23
 #include <string.h>
24 24
 #include <stdlib.h>
25
+#include <errno.h>
25 26
 #include <ipxe/console.h>
26 27
 #include <ipxe/keys.h>
27 28
 #include <ipxe/editstring.h>
@@ -244,18 +245,22 @@ void history_free ( struct readline_history *history ) {
244 245
  * @v prefill		Prefill string, or NULL for no prefill
245 246
  * @v history		History buffer, or NULL for no history
246 247
  * @ret line		Line read from console (excluding terminating newline)
248
+ * @ret rc		Return status code
247 249
  *
248 250
  * The returned line is allocated with malloc(); the caller must
249 251
  * eventually call free() to release the storage.
250 252
  */
251
-char * readline_history ( const char *prompt, const char *prefill,
252
-			  struct readline_history *history ) {
253
+int readline_history ( const char *prompt, const char *prefill,
254
+		       struct readline_history *history, char **line ) {
253 255
 	char buf[READLINE_MAX];
254 256
 	struct edit_string string;
255 257
 	int key;
256 258
 	int move_by;
257 259
 	const char *new_string;
258
-	char *line;
260
+	int rc;
261
+
262
+	/* Avoid returning uninitialised data on error */
263
+	*line = NULL;
259 264
 
260 265
 	/* Display prompt, if applicable */
261 266
 	if ( prompt )
@@ -280,12 +285,11 @@ char * readline_history ( const char *prompt, const char *prefill,
280 285
 		switch ( key ) {
281 286
 		case CR:
282 287
 		case LF:
283
-			line = strdup ( buf );
284
-			if ( ! line )
285
-				printf ( "\nOut of memory" );
288
+			*line = strdup ( buf );
289
+			rc = ( ( *line ) ? 0 : -ENOMEM );
286 290
 			goto done;
287 291
 		case CTRL_C:
288
-			line = NULL;
292
+			rc = -ECANCELED;
289 293
 			goto done;
290 294
 		case KEY_UP:
291 295
 			move_by = 1;
@@ -311,11 +315,12 @@ char * readline_history ( const char *prompt, const char *prefill,
311 315
  done:
312 316
 	putchar ( '\n' );
313 317
 	if ( history ) {
314
-		if ( line && line[0] )
315
-			history_append ( history, line );
318
+		if ( *line && (*line)[0] )
319
+			history_append ( history, *line );
316 320
 		history_cleanup ( history );
317 321
 	}
318
-	return line;
322
+	assert ( ( rc == 0 ) ^ ( *line == NULL ) );
323
+	return rc;
319 324
 }
320 325
 
321 326
 /**
@@ -328,5 +333,8 @@ char * readline_history ( const char *prompt, const char *prefill,
328 333
  * eventually call free() to release the storage.
329 334
  */
330 335
 char * readline ( const char *prompt ) {
331
-	return readline_history ( prompt, NULL, NULL );
336
+	char *line;
337
+
338
+	readline_history ( prompt, NULL, NULL, &line );
339
+	return line;
332 340
 }

+ 1
- 1
src/hci/shell.c View File

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

+ 1
- 0
src/include/ipxe/errfile.h View File

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

+ 2
- 3
src/include/readline/readline.h View File

@@ -50,9 +50,8 @@ struct readline_history {
50 50
 };
51 51
 
52 52
 extern void history_free ( struct readline_history *history );
53
-extern char * __malloc readline_history ( const char *prompt,
54
-					  const char *prefill,
55
-					  struct readline_history *history );
53
+extern int readline_history ( const char *prompt, const char *prefill,
54
+			      struct readline_history *history, char **line );
56 55
 extern char * __malloc readline ( const char *prompt );
57 56
 
58 57
 #endif /* _READLINE_H */

Loading…
Cancel
Save