Skip to content

Commit

Permalink
Implement non-clobbering file io. Use the >? operator for this for now.
Browse files Browse the repository at this point in the history
darcs-hash:20071026184232-75c98-11edcbc7548c8ad3a2d4b648cb7ae18067569f02.gz
  • Loading branch information
liljencrantz committed Oct 26, 2007
1 parent a97faaf commit 2160777
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 9 deletions.
34 changes: 26 additions & 8 deletions exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -113,10 +120,10 @@ void exec_close( int fd )
if( n == fd )
{
al_set_long( open_fds,
i,
al_get_long( open_fds, al_get_count( open_fds ) -1 ) );
i,
al_get_long( open_fds, al_get_count( open_fds ) -1 ) );
al_truncate( open_fds,
al_get_count( open_fds ) -1 );
al_get_count( open_fds ) -1 );
break;
}
}
Expand Down Expand Up @@ -288,13 +295,24 @@ static int handle_child_io( io_data_t *io )
case IO_FILE:
{
if( (tmp=wopen( io->param1.filename,
io->param2.flags, OPEN_MASK ) )==-1 )
io->param2.flags, OPEN_MASK ) )==-1 )
{
debug( 1,
FILE_ERROR,
io->param1.filename );
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" );
}

wperror( L"open" );
return -1;
}
else if( tmp != io->fd)
Expand Down
12 changes: 11 additions & 1 deletion highlight.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -825,7 +826,7 @@ void highlight_shell( wchar_t * buff,
if it exists.
*/
if( last_type == TOK_REDIRECT_IN ||
last_type == TOK_REDIRECT_APPEND )
last_type == TOK_REDIRECT_APPEND )
{
if( wstat( target, &buff ) == -1 )
{
Expand All @@ -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;
}
Expand Down
9 changes: 9 additions & 0 deletions parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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 )
{
Expand Down
6 changes: 6 additions & 0 deletions tokenizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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" )
}
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions tokenizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
}
Expand Down

0 comments on commit 2160777

Please sign in to comment.