diff --git a/builtin.c b/builtin.c index 7353c7a68..ece574a46 100644 --- a/builtin.c +++ b/builtin.c @@ -1507,7 +1507,7 @@ static int builtin_read( wchar_t **argv ) wchar_t *nxt; wchar_t *prompt = DEFAULT_READ_PROMPT; wchar_t *commandline = L""; - int exit_res=0; + int exit_res=STATUS_BUILTIN_OK; wchar_t *mode_name = READ_MODE_NAME; woptind=0; @@ -1684,11 +1684,21 @@ static int builtin_read( wchar_t **argv ) */ if( isatty(0) && builtin_stdin == 0 ) { + wchar_t *line; + reader_push( mode_name ); reader_set_prompt( prompt ); reader_set_buffer( commandline, wcslen( commandline ) ); - buff = wcsdup(reader_readline( )); + line = reader_readline( ); + if( line ) + { + buff = wcsdup( line ); + } + else + { + exit_res = STATUS_BUILTIN_ERROR; + } reader_pop(); } else @@ -1756,7 +1766,7 @@ static int builtin_read( wchar_t **argv ) sb_destroy( &sb ); } - if( i != argc ) + if( i != argc && !exit_res ) { wchar_t *state; diff --git a/reader.c b/reader.c index 1732d643a..9a1129d88 100644 --- a/reader.c +++ b/reader.c @@ -135,8 +135,8 @@ commence. /** A struct describing the state of the interactive reader. These - states can be stacked, in case reader_readline is called from - input_read(). + states can be stacked, in case reader_readline() calls are + nested. This happens when the 'read' builtin is used. */ typedef struct reader_data { @@ -1950,16 +1950,24 @@ static int read_i() } else { - for( j = first_job; j; j=j->next ) + if( !isatty(0) ) { - if( ! job_is_completed( j ) ) + /* + We already know that stdin is a tty since we're + in interactive mode. If isatty returns false, it + means stdin must have been closed. + */ + for( j = first_job; j; j=j->next ) { - job_signal( j, SIGHUP ); + if( ! job_is_completed( j ) ) + { + job_signal( j, SIGHUP ); + } } } } } - else + else if( tmp ) { tmp = wcsdup( tmp ); @@ -2644,7 +2652,7 @@ wchar_t *reader_readline() set_color( FISH_COLOR_RESET, FISH_COLOR_RESET ); } - return data->buff; + return finished ? data->buff : 0; } /**