Implement non-clobbering file io. Use the >? operator for this for now.

darcs-hash:20071026184232-75c98-11edcbc7548c8ad3a2d4b648cb7ae18067569f02.gz
This commit is contained in:
liljencrantz 2007-10-27 04:42:32 +10:00
parent a97faaf664
commit 2160777d2f
5 changed files with 53 additions and 9 deletions

18
exec.c
View file

@ -52,10 +52,17 @@
file descriptor redirection error message
*/
#define FD_ERROR _( L"An error occurred while redirecting file descriptor %d" )
/**
file redirection error message
*/
#define FILE_ERROR _( L"An error occurred while redirecting file '%ls'" )
/**
file redirection clobbering error message
*/
#define NOCLOB_ERROR _( L"The file '%ls' already exists" )
/**
fork error message
*/
@ -289,12 +296,23 @@ static int handle_child_io( io_data_t *io )
{
if( (tmp=wopen( io->param1.filename,
io->param2.flags, OPEN_MASK ) )==-1 )
{
if( ( io->param2.flags & O_EXCL ) &&
( errno ==EEXIST ) )
{
debug( 1,
NOCLOB_ERROR,
io->param1.filename );
}
else
{
debug( 1,
FILE_ERROR,
io->param1.filename );
wperror( L"open" );
}
return -1;
}
else if( tmp != io->fd)

View file

@ -757,6 +757,7 @@ void highlight_shell( wchar_t * buff,
break;
}
case TOK_REDIRECT_NOCLOB:
case TOK_REDIRECT_OUT:
case TOK_REDIRECT_IN:
case TOK_REDIRECT_APPEND:
@ -834,6 +835,15 @@ void highlight_shell( wchar_t * buff,
al_push( error, wcsdupcat( L"File \'", target, L"\' does not exist" ) );
}
}
if( last_type == TOK_REDIRECT_NOCLOB )
{
if( wstat( target, &buff ) != -1 )
{
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_ERROR;
if( error )
al_push( error, wcsdupcat( L"File \'", target, L"\' exists" ) );
}
}
}
break;
}

View file

@ -1462,6 +1462,7 @@ static void parse_job_argument_list( process_t *p,
case TOK_REDIRECT_IN:
case TOK_REDIRECT_APPEND:
case TOK_REDIRECT_FD:
case TOK_REDIRECT_NOCLOB:
{
int type = tok_last_type( tok );
io_data_t *new_io;
@ -1557,6 +1558,12 @@ static void parse_job_argument_list( process_t *p,
new_io->param1.filename = target;
break;
case TOK_REDIRECT_NOCLOB:
new_io->io_mode = IO_FILE;
new_io->param2.flags = O_CREAT | O_EXCL | O_WRONLY;
new_io->param1.filename = target;
break;
case TOK_REDIRECT_IN:
new_io->io_mode = IO_FILE;
new_io->param2.flags = O_RDONLY;
@ -2121,6 +2128,7 @@ static int parse_job( process_t *p,
break;
case TOK_REDIRECT_OUT:
case TOK_REDIRECT_NOCLOB:
case TOK_REDIRECT_APPEND:
case TOK_REDIRECT_IN:
case TOK_REDIRECT_FD:
@ -3324,6 +3332,7 @@ int parser_test( const wchar_t * buff,
case TOK_REDIRECT_IN:
case TOK_REDIRECT_APPEND:
case TOK_REDIRECT_FD:
case TOK_REDIRECT_NOCLOB:
{
if( !had_cmd )
{

View file

@ -69,6 +69,7 @@ static const wchar_t *tok_desc[] =
N_( L"Append output to file" ),
N_( L"Redirect input to file" ),
N_( L"Redirect to file descriptor" ),
N_( L"Redirect output to file if file does not exist" ),
N_( L"Run job in background" ),
N_( L"Comment" )
}
@ -473,6 +474,11 @@ static void read_redirect( tokenizer *tok, int fd )
tok->buff++;
tok->last_type = TOK_REDIRECT_FD;
}
else if( *tok->buff == L'?' )
{
tok->buff++;
tok->last_type = TOK_REDIRECT_NOCLOB;
}
else
{
tok->last_type = TOK_REDIRECT_OUT + mode;

View file

@ -26,6 +26,7 @@ enum token_type
TOK_REDIRECT_APPEND,/**< redirection append token */
TOK_REDIRECT_IN,/**< input redirection token */
TOK_REDIRECT_FD,/**< redirection to new fd token */
TOK_REDIRECT_NOCLOB, /**<? redirection token */
TOK_BACKGROUND,/**< send job to bg token */
TOK_COMMENT/**< comment token */
}