mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 21:44:16 +00:00
Rearrange wopen and stat to avoid a race and hopefully improve performance a little bit.
This commit is contained in:
parent
17a75a5aa5
commit
2da8df6202
2 changed files with 95 additions and 95 deletions
19
builtin.cpp
19
builtin.cpp
|
@ -2746,27 +2746,28 @@ static int builtin_source( parser_t &parser, wchar_t ** argv )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
if( wstat(argv[1], &buf) == -1 )
|
if( ( fd = wopen_cloexec( argv[1], O_RDONLY ) ) == -1 )
|
||||||
{
|
{
|
||||||
append_format(stderr_buffer, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1] );
|
append_format(stderr_buffer, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1] );
|
||||||
builtin_wperror( L"." );
|
builtin_wperror( L"." );
|
||||||
|
return STATUS_BUILTIN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fstat(fd, &buf) == -1 )
|
||||||
|
{
|
||||||
|
close(fd);
|
||||||
|
append_format(stderr_buffer, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1] );
|
||||||
|
builtin_wperror( L"." );
|
||||||
return STATUS_BUILTIN_ERROR;
|
return STATUS_BUILTIN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !S_ISREG(buf.st_mode) )
|
if( !S_ISREG(buf.st_mode) )
|
||||||
{
|
{
|
||||||
|
close(fd);
|
||||||
append_format(stderr_buffer, _( L"%ls: '%ls' is not a file\n" ), argv[0], argv[1] );
|
append_format(stderr_buffer, _( L"%ls: '%ls' is not a file\n" ), argv[0], argv[1] );
|
||||||
return STATUS_BUILTIN_ERROR;
|
return STATUS_BUILTIN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( fd = wopen_cloexec( argv[1], O_RDONLY ) ) == -1 )
|
|
||||||
{
|
|
||||||
append_format(stderr_buffer, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1] );
|
|
||||||
builtin_wperror( L"." );
|
|
||||||
return STATUS_BUILTIN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn = wrealpath( argv[1], 0 );
|
fn = wrealpath( argv[1], 0 );
|
||||||
|
|
||||||
if( !fn )
|
if( !fn )
|
||||||
|
|
171
parser.cpp
171
parser.cpp
|
@ -1967,91 +1967,91 @@ int parser_t::parse_job( process_t *p,
|
||||||
*/
|
*/
|
||||||
if( p->actual_cmd == NULL )
|
if( p->actual_cmd == NULL )
|
||||||
{
|
{
|
||||||
|
|
||||||
int tmp;
|
int tmp;
|
||||||
const wchar_t *cmd = args.at( 0 ).completion.c_str();
|
const wchar_t *cmd = args.at( 0 ).completion.c_str();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We couldn't find the specified command.
|
We couldn't find the specified command.
|
||||||
|
|
||||||
What we want to happen now is that the
|
What we want to happen now is that the
|
||||||
specified job won't get executed, and an
|
specified job won't get executed, and an
|
||||||
error message is printed on-screen, but
|
error message is printed on-screen, but
|
||||||
otherwise, the parsing/execution of the
|
otherwise, the parsing/execution of the
|
||||||
file continues. Because of this, we don't
|
file continues. Because of this, we don't
|
||||||
want to call error(), since that would stop
|
want to call error(), since that would stop
|
||||||
execution of the file. Instead we let
|
execution of the file. Instead we let
|
||||||
p->actual_command be 0 (null), which will
|
p->actual_command be 0 (null), which will
|
||||||
cause the job to silently not execute. We
|
cause the job to silently not execute. We
|
||||||
also print an error message and set the
|
also print an error message and set the
|
||||||
status to 127 (This is the standard number
|
status to 127 (This is the standard number
|
||||||
for this, used by other shells like bash
|
for this, used by other shells like bash
|
||||||
and zsh).
|
and zsh).
|
||||||
*/
|
*/
|
||||||
if( wcschr( cmd, L'=' ) )
|
if( wcschr( cmd, L'=' ) )
|
||||||
{
|
{
|
||||||
wchar_t *cpy = wcsdup( cmd );
|
wchar_t *cpy = wcsdup( cmd );
|
||||||
wchar_t *valpart = wcschr( cpy, L'=' );
|
wchar_t *valpart = wcschr( cpy, L'=' );
|
||||||
*valpart++=0;
|
*valpart++=0;
|
||||||
|
|
||||||
debug( 0,
|
debug( 0,
|
||||||
COMMAND_ASSIGN_ERR_MSG,
|
COMMAND_ASSIGN_ERR_MSG,
|
||||||
cmd,
|
cmd,
|
||||||
cpy,
|
cpy,
|
||||||
valpart);
|
valpart);
|
||||||
free(cpy);
|
free(cpy);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(cmd[0]==L'$')
|
else if(cmd[0]==L'$')
|
||||||
{
|
{
|
||||||
|
|
||||||
const env_var_t val_wstr = env_get_string( cmd+1 );
|
const env_var_t val_wstr = env_get_string( cmd+1 );
|
||||||
const wchar_t *val = val_wstr.missing() ? NULL : val_wstr.c_str();
|
const wchar_t *val = val_wstr.missing() ? NULL : val_wstr.c_str();
|
||||||
if( val )
|
if( val )
|
||||||
{
|
{
|
||||||
debug( 0,
|
debug( 0,
|
||||||
_(L"Variables may not be used as commands. Instead, define a function like 'function %ls; %ls $argv; end'. See the help section for the function command by typing 'help function'." ),
|
_(L"Variables may not be used as commands. Instead, define a function like 'function %ls; %ls $argv; end'. See the help section for the function command by typing 'help function'." ),
|
||||||
cmd+1,
|
cmd+1,
|
||||||
val,
|
val,
|
||||||
cmd );
|
cmd );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debug( 0,
|
debug( 0,
|
||||||
_(L"Variables may not be used as commands. Instead, define a function. See the help section for the function command by typing 'help function'." ),
|
_(L"Variables may not be used as commands. Instead, define a function. See the help section for the function command by typing 'help function'." ),
|
||||||
cmd );
|
cmd );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(wcschr( cmd, L'$' ))
|
else if(wcschr( cmd, L'$' ))
|
||||||
{
|
{
|
||||||
debug( 0,
|
debug( 0,
|
||||||
_(L"Commands may not contain variables. Use the eval builtin instead, like 'eval %ls'. See the help section for the eval command by typing 'help eval'." ),
|
_(L"Commands may not contain variables. Use the eval builtin instead, like 'eval %ls'. See the help section for the eval command by typing 'help eval'." ),
|
||||||
cmd,
|
cmd,
|
||||||
cmd );
|
cmd );
|
||||||
}
|
}
|
||||||
else if( err!=ENOENT )
|
else if( err!=ENOENT )
|
||||||
{
|
{
|
||||||
debug( 0,
|
debug( 0,
|
||||||
_(L"The file '%ls' is not executable by this user"),
|
_(L"The file '%ls' is not executable by this user"),
|
||||||
cmd?cmd:L"UNKNOWN" );
|
cmd?cmd:L"UNKNOWN" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debug( 0,
|
debug( 0,
|
||||||
_(L"Unknown command '%ls'"),
|
_(L"Unknown command '%ls'"),
|
||||||
cmd?cmd:L"UNKNOWN" );
|
cmd?cmd:L"UNKNOWN" );
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = current_tokenizer_pos;
|
tmp = current_tokenizer_pos;
|
||||||
current_tokenizer_pos = tok_get_pos(tok);
|
current_tokenizer_pos = tok_get_pos(tok);
|
||||||
|
|
||||||
fwprintf( stderr, L"%ls", parser_t::current_line() );
|
fwprintf( stderr, L"%ls", parser_t::current_line() );
|
||||||
|
|
||||||
current_tokenizer_pos=tmp;
|
current_tokenizer_pos=tmp;
|
||||||
|
|
||||||
job_set_flag( j, JOB_SKIP, 1 );
|
job_set_flag( j, JOB_SKIP, 1 );
|
||||||
event_fire_generic(L"fish_command_not_found", (wchar_t *)( args.at( 0 ).completion.c_str() ) );
|
event_fire_generic(L"fish_command_not_found", (wchar_t *)( args.at( 0 ).completion.c_str() ) );
|
||||||
proc_set_last_status( err==ENOENT?STATUS_UNKNOWN_COMMAND:STATUS_NOT_EXECUTABLE );
|
proc_set_last_status( err==ENOENT?STATUS_UNKNOWN_COMMAND:STATUS_NOT_EXECUTABLE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2307,8 +2307,7 @@ void parser_t::eval_job( tokenizer *tok )
|
||||||
if( job_start_pos < tok_get_pos( tok ) )
|
if( job_start_pos < tok_get_pos( tok ) )
|
||||||
{
|
{
|
||||||
int stop_pos = tok_get_pos( tok );
|
int stop_pos = tok_get_pos( tok );
|
||||||
const wchar_t *newline = wcschr( tok_string(tok)+start_pos,
|
const wchar_t *newline = wcschr(tok_string(tok)+start_pos, L'\n');
|
||||||
L'\n' );
|
|
||||||
if( newline )
|
if( newline )
|
||||||
stop_pos = mini( stop_pos, newline - tok_string(tok) );
|
stop_pos = mini( stop_pos, newline - tok_string(tok) );
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue