Do not break stdin when reading a script

darcs-hash:20051019120744-ac50b-67cc9a5c4f6509eb8a012aff32fcd9606933d0ab.gz
This commit is contained in:
axel 2005-10-19 22:07:44 +10:00
parent 4fb2dc3f55
commit 83fcc29305
4 changed files with 45 additions and 69 deletions

View file

@ -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;
}

14
main.c
View file

@ -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 )
{

View file

@ -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;

View file

@ -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.