From 83fcc293055a8eb9b94171cc0c665a9691d08f01 Mon Sep 17 00:00:00 2001 From: axel Date: Wed, 19 Oct 2005 22:07:44 +1000 Subject: [PATCH] Do not break stdin when reading a script darcs-hash:20051019120744-ac50b-67cc9a5c4f6509eb8a012aff32fcd9606933d0ab.gz --- builtin.c | 51 ++++++++++++++------------------------------------- main.c | 14 +++++--------- reader.c | 45 ++++++++++++++++++++++++--------------------- reader.h | 4 ++-- 4 files changed, 45 insertions(+), 69 deletions(-) diff --git a/builtin.c b/builtin.c index 8197b6006..b0a05e28b 100644 --- a/builtin.c +++ b/builtin.c @@ -1956,7 +1956,7 @@ static int builtin_complete( wchar_t **argv ) */ static int builtin_source( wchar_t ** argv ) { - int stdin_org; + int fd; int res; /* @@ -1976,19 +1976,7 @@ static int builtin_source( wchar_t ** argv ) return 1; } - if( (stdin_org=dup( 0 )) == -1) - { - builtin_wperror(L"dup"); - return 1; - } - - if( close( 0 ) ) - { - builtin_wperror(L"close"); - return 1; - } - - if( wopen( argv[1], O_RDONLY ) == -1 ) + if( ( fd = wopen( argv[1], O_RDONLY ) ) == -1 ) { builtin_wperror( L"open" ); res = 1; @@ -1996,8 +1984,14 @@ static int builtin_source( wchar_t ** argv ) else { reader_push_current_filename( argv[1] ); + + /* + Push a new non-shadowwing variable scope to the stack. That + way one can use explicitly local variables in sourced files + that will die on return to the calling file. + */ env_push(0); - res = reader_read(); + res = reader_read( fd ); env_pop(); if( res ) { @@ -2006,33 +2000,16 @@ static int builtin_source( wchar_t ** argv ) argv[0], argv[1] ); - } - if( close( 0 ) ) - { - builtin_wperror(L"close"); - res = errno; - } + /* + Do not close fd after calling reader_read. reader_read + automatically closes it before calling eval. + */ + reader_pop_current_filename(); } - if( dup( stdin_org ) == -1) - { - builtin_wperror(L"dup"); - res = errno; - fwprintf( stderr, L"Could not restore stdout\n" ); - sanity_lose(); - } - - if( close( stdin_org ) ) - { - builtin_wperror(L"close"); - res = errno; - fwprintf( stderr, L"Could not restore stdout\n" ); - sanity_lose(); - } - return res; } diff --git a/main.c b/main.c index dbcff92ed..a5f657154 100644 --- a/main.c +++ b/main.c @@ -235,7 +235,7 @@ int main( int argc, char **argv ) if( my_optind == argc ) { reader_push_current_filename( L"(stdin)" ); - res = reader_read(); + res = reader_read( 0 ); reader_pop_current_filename(); } else @@ -244,13 +244,9 @@ int main( int argc, char **argv ) char *file = *(argv+1); int i; string_buffer_t sb; - - if( close( 0 ) ) - { - wperror(L"close"); - return 1; - } - if( open(file, O_RDONLY) == -1 ) + int fd; + + if( ( fd = open(file, O_RDONLY) ) == -1 ) { wperror( L"open" ); return 1; @@ -274,7 +270,7 @@ int main( int argc, char **argv ) } reader_push_current_filename( str2wcs( file ) ); - res = reader_read(); + res = reader_read( fd ); if( res ) { diff --git a/reader.c b/reader.c index b585ea481..6a687d825 100644 --- a/reader.c +++ b/reader.c @@ -2876,15 +2876,15 @@ wchar_t *reader_readline() the prompt, using syntax highlighting. This is used for reading scripts and init files. */ -static int read_ni() +static int read_ni( int fd ) { FILE *in_stream; wchar_t *buff=0; buffer_t acc; - int des = dup( 0 ); + int des = fd == 0 ? dup(0) : fd; int res=0; - + if (des == -1) { wperror( L"dup" ); @@ -2897,7 +2897,8 @@ static int read_ni() if( in_stream != 0 ) { wchar_t *str; - + int acc_used; + while(!feof( in_stream )) { char buff[4096]; @@ -2905,9 +2906,18 @@ static int read_ni() b_append( &acc, buff, c ); } b_append( &acc, "\0", 1 ); + acc_used = acc.used; str = str2wcs( acc.buff ); b_destroy( &acc ); + if( fclose( in_stream )) + { + debug( 1, + L"Error while closing input" ); + wperror( L"fclose" ); + res = 1; + } + // fwprintf( stderr, L"Woot is %d chars\n", wcslen( acc.buff ) ); if( str ) @@ -2928,11 +2938,11 @@ static int read_ni() } else { - if( acc.used > 1 ) + if( acc_used > 1 ) { debug( 1, L"Could not convert input. Read %d bytes.", - acc.used-1 ); + acc_used-1 ); } else { @@ -2942,14 +2952,6 @@ static int read_ni() res=1; } - if( fclose( in_stream )) - { - debug( 1, - L"Error while closing input" ); - wperror( L"fclose" ); - res = 1; - } - } else { @@ -2963,7 +2965,7 @@ static int read_ni() return res; } -int reader_read() +int reader_read( int fd ) { int res; /* @@ -2972,17 +2974,18 @@ int reader_read() original state. We also update the signal handlers. */ int shell_was_interactive = is_interactive; - is_interactive = isatty(STDIN_FILENO); + + is_interactive = (fd == 0) && isatty(STDIN_FILENO); signal_set_handlers(); - res= is_interactive?read_i():read_ni(); - + res= is_interactive?read_i():read_ni( fd ); + /* - If the exit command was called in a script, only exit the - script, not the program + If the exit command was called in a script, only exit the + script, not the program */ end_loop = 0; - + is_interactive = shell_was_interactive; signal_set_handlers(); return res; diff --git a/reader.h b/reader.h index c152bd9a3..de0d6b5ef 100644 --- a/reader.h +++ b/reader.h @@ -14,9 +14,9 @@ #include "util.h" /** - Read commands from fd 0 until encountering EOF + Read commands from \c fd until encountering EOF */ -int reader_read(); +int reader_read( int fd); /** Tell the shell that it should exit after the currently running command finishes.