A bunch of work to move towards a sane memory model in job_t
This commit is contained in:
parent
966cd6a8ca
commit
3b8a4e56b0
20
builtin.cpp
20
builtin.cpp
@ -3014,7 +3014,7 @@ static int builtin_fg( parser_t &parser, wchar_t **argv )
|
||||
_( L"%ls: Can't put job %d, '%ls' to foreground because it is not under job control\n" ),
|
||||
argv[0],
|
||||
pid,
|
||||
j->command );
|
||||
j->command_cstr() );
|
||||
builtin_print_help( parser, argv[0], sb_err );
|
||||
j=0;
|
||||
}
|
||||
@ -3028,7 +3028,7 @@ static int builtin_fg( parser_t &parser, wchar_t **argv )
|
||||
sb_printf( sb_err,
|
||||
FG_MSG,
|
||||
j->job_id,
|
||||
j->command );
|
||||
j->command_cstr() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3040,10 +3040,10 @@ static int builtin_fg( parser_t &parser, wchar_t **argv )
|
||||
fwprintf( stderr,
|
||||
FG_MSG,
|
||||
j->job_id,
|
||||
j->command );
|
||||
j->command_cstr() );
|
||||
}
|
||||
|
||||
wchar_t *ft = tok_first( j->command );
|
||||
wchar_t *ft = tok_first( j->command_cstr() );
|
||||
if( ft != 0 )
|
||||
env_set( L"_", ft, ENV_EXPORT );
|
||||
free(ft);
|
||||
@ -3077,7 +3077,7 @@ static int send_to_bg( parser_t &parser, job_t *j, const wchar_t *name )
|
||||
_( L"%ls: Can't put job %d, '%ls' to background because it is not under job control\n" ),
|
||||
L"bg",
|
||||
j->job_id,
|
||||
j->command );
|
||||
j->command_cstr() );
|
||||
builtin_print_help( parser, L"bg", sb_err );
|
||||
return STATUS_BUILTIN_ERROR;
|
||||
}
|
||||
@ -3086,7 +3086,7 @@ static int send_to_bg( parser_t &parser, job_t *j, const wchar_t *name )
|
||||
sb_printf( sb_err,
|
||||
_(L"Send job %d '%ls' to background\n"),
|
||||
j->job_id,
|
||||
j->command );
|
||||
j->command_cstr() );
|
||||
}
|
||||
make_first( j );
|
||||
job_set_flag( j, JOB_FOREGROUND, 0 );
|
||||
@ -3821,7 +3821,7 @@ int builtin_exists( wchar_t *cmd )
|
||||
Return true if the specified builtin should handle it's own help,
|
||||
false otherwise.
|
||||
*/
|
||||
static int internal_help( wchar_t *cmd )
|
||||
static int internal_help( const wchar_t *cmd )
|
||||
{
|
||||
CHECK( cmd, 0 );
|
||||
return contains( cmd, L"for", L"while", L"function",
|
||||
@ -3829,15 +3829,15 @@ static int internal_help( wchar_t *cmd )
|
||||
}
|
||||
|
||||
|
||||
int builtin_run( parser_t &parser, wchar_t **argv, io_data_t *io )
|
||||
int builtin_run( parser_t &parser, const wchar_t * const *argv, io_data_t *io )
|
||||
{
|
||||
int (*cmd)(parser_t &parser, wchar_t **argv)=0;
|
||||
int (*cmd)(parser_t &parser, const wchar_t * const *argv)=0;
|
||||
real_io = io;
|
||||
|
||||
CHECK( argv, STATUS_BUILTIN_ERROR );
|
||||
CHECK( argv[0], STATUS_BUILTIN_ERROR );
|
||||
|
||||
cmd = (int (*)(parser_t &parser, wchar_t **))hash_get( &builtin, argv[0] );
|
||||
cmd = (int (*)(parser_t &parser, const wchar_t * const*))hash_get( &builtin, argv[0] );
|
||||
|
||||
if( argv[1] != 0 && !internal_help(argv[0]) )
|
||||
{
|
||||
|
@ -137,7 +137,7 @@ int builtin_exists( wchar_t *cmd );
|
||||
|
||||
\return the exit status of the builtin command
|
||||
*/
|
||||
int builtin_run( parser_t &parser, wchar_t **argv, io_data_t *io );
|
||||
int builtin_run( parser_t &parser, const wchar_t * const *argv, io_data_t *io );
|
||||
|
||||
/**
|
||||
Insert all builtin names into l. These are not copies of the strings and should not be freed after use.
|
||||
|
@ -542,7 +542,6 @@ static int builtin_complete( parser_t &parser, wchar_t **argv )
|
||||
if( do_complete )
|
||||
{
|
||||
std::vector<completion_t> comp;
|
||||
int i;
|
||||
|
||||
const wchar_t *prev_temporary_buffer = temporary_buffer;
|
||||
|
||||
@ -560,7 +559,7 @@ static int builtin_complete( parser_t &parser, wchar_t **argv )
|
||||
|
||||
complete2( do_complete, comp );
|
||||
|
||||
for( i=0; i< comp.size() ; i++ )
|
||||
for( size_t i=0; i< comp.size() ; i++ )
|
||||
{
|
||||
const completion_t &next = comp.at( i );
|
||||
|
||||
|
@ -99,7 +99,7 @@ static void builtin_jobs_print( job_t *j, int mode, int header )
|
||||
sb_append( sb_out,
|
||||
job_is_stopped(j)?_(L"stopped"):_(L"running"),
|
||||
L"\t",
|
||||
j->command,
|
||||
j->command_cstr(),
|
||||
L"\n",
|
||||
NULL );
|
||||
break;
|
||||
@ -147,7 +147,7 @@ static void builtin_jobs_print( job_t *j, int mode, int header )
|
||||
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
sb_printf( sb_out, L"%ls\n", p->argv[0] );
|
||||
sb_printf( sb_out, L"%ls\n", p->argv0() );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -159,14 +159,14 @@ wchar_t **list_to_char_arr( array_list_t *l )
|
||||
wchar_t **completions_to_char_arr( std::vector<completion_t> &l )
|
||||
{
|
||||
wchar_t ** res = (wchar_t **)malloc( sizeof(wchar_t *)*( l.size() + 1) );
|
||||
int i;
|
||||
size_t i;
|
||||
if( res == 0 )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
for( i=0; i< l.size(); i++ )
|
||||
{
|
||||
res[i] = const_cast<wchar_t*>(l.at(i).completion.c_str());
|
||||
res[i] = wcsdup(l.at(i).completion.c_str());
|
||||
}
|
||||
res[i]='\0';
|
||||
return res;
|
||||
@ -414,7 +414,7 @@ char *wcs2str_internal( const wchar_t *in, char *out )
|
||||
return out;
|
||||
}
|
||||
|
||||
char **wcsv2strv( const wchar_t **in )
|
||||
char **wcsv2strv( const wchar_t * const *in )
|
||||
{
|
||||
int count =0;
|
||||
int i;
|
||||
|
2
common.h
2
common.h
@ -356,7 +356,7 @@ wcstring format_string(const wchar_t *format, ...);
|
||||
Returns a newly allocated wide character string array equivalent of
|
||||
the specified multibyte character string array
|
||||
*/
|
||||
char **wcsv2strv( const wchar_t **in );
|
||||
char **wcsv2strv( const wchar_t * const *in );
|
||||
|
||||
/**
|
||||
Returns a newly allocated multibyte character string array equivalent of the specified wide character string array
|
||||
|
@ -907,7 +907,6 @@ static void complete_strings( std::vector<completion_t> &comp_out,
|
||||
std::vector<completion_t> &possible_comp,
|
||||
int flags )
|
||||
{
|
||||
int i;
|
||||
wchar_t *wc, *tmp;
|
||||
|
||||
tmp = expand_one( 0,
|
||||
@ -918,7 +917,7 @@ static void complete_strings( std::vector<completion_t> &comp_out,
|
||||
wc = parse_util_unescape_wildcards( tmp );
|
||||
free(tmp);
|
||||
|
||||
for( i=0; i< possible_comp.size(); i++ )
|
||||
for( size_t i=0; i< possible_comp.size(); i++ )
|
||||
{
|
||||
wcstring temp = possible_comp.at( i ).completion;
|
||||
const wchar_t *next_str = temp.empty()?NULL:temp.c_str();
|
||||
|
@ -236,7 +236,7 @@ const wchar_t *event_get_desc( event_t *e )
|
||||
{
|
||||
job_t *j = job_get_from_pid( -e->param1.pid );
|
||||
if( j )
|
||||
sb_printf( get_desc_buff, _(L"exit handler for job %d, '%ls'"), j->job_id, j->command );
|
||||
sb_printf( get_desc_buff, _(L"exit handler for job %d, '%ls'"), j->job_id, j->command_cstr() );
|
||||
else
|
||||
sb_printf( get_desc_buff, _(L"exit handler for job with process group %d"), -e->param1.pid );
|
||||
}
|
||||
@ -247,7 +247,7 @@ const wchar_t *event_get_desc( event_t *e )
|
||||
{
|
||||
job_t *j = job_get( e->param1.job_id );
|
||||
if( j )
|
||||
sb_printf( get_desc_buff, _(L"exit handler for job %d, '%ls'"), j->job_id, j->command );
|
||||
sb_printf( get_desc_buff, _(L"exit handler for job %d, '%ls'"), j->job_id, j->command_cstr() );
|
||||
else
|
||||
sb_printf( get_desc_buff, _(L"exit handler for job with job id %d"), j->job_id );
|
||||
|
||||
|
56
exec.cpp
56
exec.cpp
@ -467,7 +467,7 @@ static int setup_child_process( job_t *j, process_t *p )
|
||||
call. Only use it in the execve error handler which calls exit
|
||||
right afterwards, anyway.
|
||||
*/
|
||||
static wchar_t *get_interpreter( wchar_t *file )
|
||||
static wchar_t *get_interpreter( const wchar_t *file )
|
||||
{
|
||||
string_buffer_t sb;
|
||||
FILE *fp = wfopen( file, "r" );
|
||||
@ -509,7 +509,7 @@ static void launch_process( process_t *p )
|
||||
|
||||
// debug( 1, L"exec '%ls'", p->argv[0] );
|
||||
|
||||
char **argv = wcsv2strv( (const wchar_t **) p->argv);
|
||||
char **argv = wcsv2strv(p->get_argv());
|
||||
char **envv = env_export_arr( 0 );
|
||||
|
||||
execve ( wcs2str(p->actual_cmd),
|
||||
@ -539,21 +539,21 @@ static void launch_process( process_t *p )
|
||||
wchar_t **res;
|
||||
char **res_real;
|
||||
|
||||
while( p->argv[count] != 0 )
|
||||
while( p->argv(count) != 0 )
|
||||
count++;
|
||||
|
||||
res = (wchar_t **)malloc( sizeof(wchar_t*)*(count+2));
|
||||
wchar_t sh_command[] = L"/bin/sh";
|
||||
res = (wchar_t **)malloc( sizeof(wchar_t*)*(count+3));
|
||||
const wchar_t *sh_command = L"/bin/sh";
|
||||
|
||||
res[0] = sh_command;
|
||||
res[1] = p->actual_cmd;
|
||||
res[0] = wcsdup(sh_command);
|
||||
res[1] = wcsdup(p->actual_cmd);
|
||||
|
||||
for( i=1; p->argv[i]; i++ ){
|
||||
res[i+1] = p->argv[i];
|
||||
for( i=1; p->argv(i) != NULL; i++ ){
|
||||
res[i+1] = wcsdup(p->argv(i));
|
||||
}
|
||||
|
||||
res[i+1] = 0;
|
||||
p->argv = res;
|
||||
p->set_argv(res);
|
||||
p->actual_cmd = sh_command;
|
||||
|
||||
res_real = wcsv2strv( (const wchar_t **) res);
|
||||
@ -841,9 +841,9 @@ static int set_child_group( job_t *j, process_t *p, int print_errors )
|
||||
debug( 1,
|
||||
_( L"Could not send process %d, '%ls' in job %d, '%ls' from group %d to group %d" ),
|
||||
p->pid,
|
||||
p->argv[0],
|
||||
p->argv0(),
|
||||
j->job_id,
|
||||
j->command,
|
||||
j->command_cstr(),
|
||||
getpgid( p->pid),
|
||||
j->pgid );
|
||||
|
||||
@ -863,7 +863,7 @@ static int set_child_group( job_t *j, process_t *p, int print_errors )
|
||||
{
|
||||
debug( 1, _( L"Could not send job %d ('%ls') to foreground" ),
|
||||
j->job_id,
|
||||
j->command );
|
||||
j->command_cstr() );
|
||||
wperror( L"tcsetpgrp" );
|
||||
res = -1;
|
||||
}
|
||||
@ -978,7 +978,7 @@ void exec( parser_t &parser, job_t *j )
|
||||
sigemptyset( &chldset );
|
||||
sigaddset( &chldset, SIGCHLD );
|
||||
|
||||
debug( 4, L"Exec job '%ls' with id %d", j->command, j->job_id );
|
||||
debug( 4, L"Exec job '%ls' with id %d", j->command_cstr(), j->job_id );
|
||||
|
||||
if( parser.block_io )
|
||||
{
|
||||
@ -1004,8 +1004,8 @@ void exec( parser_t &parser, job_t *j )
|
||||
Input redirection - create a new gobetween process to take
|
||||
care of buffering
|
||||
*/
|
||||
process_t *fake = (process_t *)halloc( j, sizeof(process_t) );
|
||||
fake->type = INTERNAL_BUFFER;
|
||||
process_t *fake = new process_t();
|
||||
fake->type = INTERNAL_BUFFER;
|
||||
fake->pipe_write_fd = 1;
|
||||
j->first_process->pipe_read_fd = input_redirect->fd;
|
||||
fake->next = j->first_process;
|
||||
@ -1187,31 +1187,33 @@ void exec( parser_t &parser, job_t *j )
|
||||
*/
|
||||
|
||||
signal_unblock();
|
||||
orig_def = function_get_definition( p->argv[0] );
|
||||
orig_def = function_get_definition( p->argv0() );
|
||||
|
||||
// function_get_named_arguments may trigger autoload, which deallocates the orig_def.
|
||||
// We should make function_get_definition return a wcstring (but how to handle NULL...)
|
||||
if (orig_def)
|
||||
orig_def = wcsdup(orig_def);
|
||||
|
||||
wcstring_list_t named_arguments = function_get_named_arguments( p->argv[0] );
|
||||
shadows = function_get_shadows( p->argv[0] );
|
||||
wcstring_list_t named_arguments = function_get_named_arguments( p->argv0() );
|
||||
shadows = function_get_shadows( p->argv0() );
|
||||
|
||||
signal_block();
|
||||
|
||||
if( orig_def )
|
||||
{
|
||||
def = (wchar_t *)halloc_register( j, const_cast<wchar_t *>(orig_def) );
|
||||
//def = (wchar_t *)halloc_register( j, const_cast<wchar_t *>(orig_def) );
|
||||
// PCA LEAKS
|
||||
def = (wchar_t *)orig_def;
|
||||
}
|
||||
if( def == 0 )
|
||||
{
|
||||
debug( 0, _( L"Unknown function '%ls'" ), p->argv[0] );
|
||||
debug( 0, _( L"Unknown function '%ls'" ), p->argv0() );
|
||||
break;
|
||||
}
|
||||
parser.push_block( shadows?FUNCTION_CALL:FUNCTION_CALL_NO_SHADOW );
|
||||
|
||||
parser.current_block->param2.function_call_process = p;
|
||||
parser.current_block->param1.function_call_name = (wchar_t *)halloc_register( parser.current_block, wcsdup( p->argv[0] ) );
|
||||
parser.current_block->param1.function_call_name = (wchar_t *)halloc_register( parser.current_block, wcsdup( p->argv0() ) );
|
||||
|
||||
|
||||
/*
|
||||
@ -1220,10 +1222,10 @@ void exec( parser_t &parser, job_t *j )
|
||||
signals.
|
||||
*/
|
||||
signal_unblock();
|
||||
parse_util_set_argv( p->argv+1, named_arguments );
|
||||
parse_util_set_argv( p->get_argv()+1, named_arguments );
|
||||
signal_block();
|
||||
|
||||
parser.forbid_function( p->argv[0] );
|
||||
parser.forbid_function( p->argv0() );
|
||||
|
||||
if( p->next )
|
||||
{
|
||||
@ -1247,7 +1249,7 @@ void exec( parser_t &parser, job_t *j )
|
||||
j->io = io_add( j->io, io_buffer );
|
||||
}
|
||||
|
||||
internal_exec_helper( parser, p->argv[0], TOP, j->io );
|
||||
internal_exec_helper( parser, p->argv0(), TOP, j->io );
|
||||
break;
|
||||
|
||||
}
|
||||
@ -1380,7 +1382,7 @@ void exec( parser_t &parser, job_t *j )
|
||||
|
||||
signal_unblock();
|
||||
|
||||
p->status = builtin_run( parser, p->argv, j->io );
|
||||
p->status = builtin_run( parser, p->get_argv(), j->io );
|
||||
|
||||
builtin_out_redirect=old_out;
|
||||
builtin_err_redirect=old_err;
|
||||
@ -1580,7 +1582,7 @@ void exec( parser_t &parser, job_t *j )
|
||||
p->completed=1;
|
||||
if( p->next == 0 )
|
||||
{
|
||||
debug( 3, L"Set status of %ls to %d using short circut", j->command, p->status );
|
||||
debug( 3, L"Set status of %ls to %d using short circut", j->command_cstr(), p->status );
|
||||
|
||||
int status = p->status;
|
||||
proc_set_last_status( job_get_flag( j, JOB_NEGATE )?(!status):status );
|
||||
|
17
expand.cpp
17
expand.cpp
@ -401,7 +401,7 @@ static int find_process( const wchar_t *proc,
|
||||
while ((j = jobs.next()))
|
||||
{
|
||||
wchar_t jid[16];
|
||||
if( j->command == 0 )
|
||||
if( j->command.size() == 0 )
|
||||
continue;
|
||||
|
||||
swprintf( jid, 16, L"%d", j->job_id );
|
||||
@ -414,7 +414,7 @@ static int find_process( const wchar_t *proc,
|
||||
|
||||
sb_printf( &desc_buff,
|
||||
COMPLETE_JOB_DESC_VAL,
|
||||
j->command );
|
||||
j->command_cstr() );
|
||||
|
||||
completion_allocate( out,
|
||||
jid+wcslen(proc),
|
||||
@ -437,7 +437,7 @@ static int find_process( const wchar_t *proc,
|
||||
if( jid > 0 && !errno && !*end )
|
||||
{
|
||||
j = job_get( jid );
|
||||
if( (j != 0) && (j->command != 0 ) )
|
||||
if( (j != 0) && (j->command_cstr() != 0 ) )
|
||||
{
|
||||
|
||||
{
|
||||
@ -460,15 +460,15 @@ static int find_process( const wchar_t *proc,
|
||||
{
|
||||
int offset;
|
||||
|
||||
if( j->command == 0 )
|
||||
if( j->command_cstr() == 0 )
|
||||
continue;
|
||||
|
||||
if( match_pid( j->command, proc, flags, &offset ) )
|
||||
if( match_pid( j->command_cstr(), proc, flags, &offset ) )
|
||||
{
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
completion_allocate( out,
|
||||
j->command + offset + wcslen(proc),
|
||||
j->command_cstr() + offset + wcslen(proc),
|
||||
COMPLETE_JOB_DESC,
|
||||
0 );
|
||||
}
|
||||
@ -493,7 +493,7 @@ static int find_process( const wchar_t *proc,
|
||||
while ((j = jobs.next()))
|
||||
{
|
||||
process_t *p;
|
||||
if( j->command == 0 )
|
||||
if( j->command.size() == 0 )
|
||||
continue;
|
||||
for( p=j->first_process; p; p=p->next )
|
||||
{
|
||||
@ -2621,7 +2621,8 @@ wchar_t *expand_one( void *context, wchar_t *string, int flags )
|
||||
// al_foreach( &l, &free );
|
||||
// al_destroy( &l );
|
||||
|
||||
halloc_register( context, one );
|
||||
if (context)
|
||||
halloc_register( context, one );
|
||||
return one;
|
||||
}
|
||||
|
||||
|
@ -600,11 +600,11 @@ void parse_util_token_extent( const wchar_t *buff,
|
||||
|
||||
}
|
||||
|
||||
void parse_util_set_argv( wchar_t **argv, const wcstring_list_t &named_arguments )
|
||||
void parse_util_set_argv( const wchar_t * const *argv, const wcstring_list_t &named_arguments )
|
||||
{
|
||||
if( *argv )
|
||||
{
|
||||
wchar_t **arg;
|
||||
const wchar_t * const *arg;
|
||||
string_buffer_t sb;
|
||||
sb_init( &sb );
|
||||
|
||||
@ -627,7 +627,7 @@ void parse_util_set_argv( wchar_t **argv, const wcstring_list_t &named_arguments
|
||||
|
||||
if( named_arguments.size() )
|
||||
{
|
||||
wchar_t **arg;
|
||||
const wchar_t * const *arg;
|
||||
size_t i;
|
||||
|
||||
for( i=0, arg=argv; i < named_arguments.size(); i++ )
|
||||
|
@ -116,7 +116,7 @@ int parse_util_get_offset( wchar_t *buff, int line, int line_offset );
|
||||
Set the argv environment variable to the specified null-terminated
|
||||
array of strings.
|
||||
*/
|
||||
void parse_util_set_argv( wchar_t **argv, const wcstring_list_t &named_arguments );
|
||||
void parse_util_set_argv( const wchar_t * const *argv, const wcstring_list_t &named_arguments );
|
||||
|
||||
/**
|
||||
Make a duplicate of the specified string, unescape wildcard
|
||||
|
58
parser.cpp
58
parser.cpp
@ -574,14 +574,9 @@ static const wchar_t *parser_find_end( const wchar_t * buff )
|
||||
}
|
||||
|
||||
|
||||
void parser_t::forbid_function( wchar_t *function )
|
||||
void parser_t::forbid_function( const wcstring &function )
|
||||
{
|
||||
/*
|
||||
if( function )
|
||||
debug( 2, L"Forbid %ls\n", function );
|
||||
*/
|
||||
CHECK( function, );
|
||||
forbidden_function.push_back(wcstring(function));
|
||||
forbidden_function.push_back(function);
|
||||
}
|
||||
|
||||
void parser_t::allow_function()
|
||||
@ -937,14 +932,14 @@ void parser_t::stack_trace( block_t *b, string_buffer_t *buff)
|
||||
|
||||
if( b->type == FUNCTION_CALL )
|
||||
{
|
||||
if( b->param2.function_call_process->argv[1] )
|
||||
if( b->param2.function_call_process->argv(1) )
|
||||
{
|
||||
string_buffer_t tmp;
|
||||
sb_init( &tmp );
|
||||
|
||||
for( i=1; b->param2.function_call_process->argv[i]; i++ )
|
||||
for( i=1; b->param2.function_call_process->argv(i); i++ )
|
||||
{
|
||||
sb_append( &tmp, i>1?L" ":L"", b->param2.function_call_process->argv[i], NULL );
|
||||
sb_append( &tmp, i>1?L" ":L"", b->param2.function_call_process->argv(i), NULL );
|
||||
}
|
||||
sb_printf( buff, _(L"\twith parameter list '%ls'\n"), (wchar_t *)tmp.buff );
|
||||
|
||||
@ -1202,7 +1197,7 @@ const wchar_t *parser_t::get_buffer() const
|
||||
}
|
||||
|
||||
|
||||
int parser_t::is_help( wchar_t *s, int min_match ) const
|
||||
int parser_t::is_help( const wchar_t *s, int min_match ) const
|
||||
{
|
||||
int len;
|
||||
|
||||
@ -1275,9 +1270,8 @@ void parser_t::parse_job_argument_list( process_t *p,
|
||||
return;
|
||||
}
|
||||
|
||||
if( !p->argv )
|
||||
halloc_register( j, p->argv = completions_to_char_arr( args ) );
|
||||
p->next = (process_t *)halloc( j, sizeof( process_t ) );
|
||||
p->set_argv(completions_to_char_arr(args));
|
||||
p->next = new process_t();
|
||||
|
||||
tok_next( tok );
|
||||
|
||||
@ -1298,8 +1292,8 @@ void parser_t::parse_job_argument_list( process_t *p,
|
||||
|
||||
case TOK_END:
|
||||
{
|
||||
if( !p->argv )
|
||||
halloc_register( j, p->argv = completions_to_char_arr( args ) );
|
||||
if( !p->get_argv() )
|
||||
p->set_argv(completions_to_char_arr(args));
|
||||
if( tok_has_next(tok))
|
||||
tok_next(tok);
|
||||
|
||||
@ -1447,7 +1441,7 @@ void parser_t::parse_job_argument_list( process_t *p,
|
||||
{
|
||||
case TOK_STRING:
|
||||
{
|
||||
target = (wchar_t *)expand_one( j,
|
||||
target = expand_one( j,
|
||||
wcsdup( tok_last( tok ) ),
|
||||
no_exec ? EXPAND_SKIP_VARIABLES : 0);
|
||||
|
||||
@ -2047,7 +2041,7 @@ int parser_t::parse_job( process_t *p,
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
UNKNOWN_BUILTIN_ERR_MSG,
|
||||
args->at( args->size() -1 ) );
|
||||
args->back().completion.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -2147,8 +2141,8 @@ int parser_t::parse_job( process_t *p,
|
||||
{
|
||||
if( p->type == INTERNAL_BUILTIN && parser_keywords_skip_arguments( (wchar_t *)args->at( 0 ).completion.c_str() ) )
|
||||
{
|
||||
if( !p->argv )
|
||||
halloc_register( j, p->argv = completions_to_char_arr( *args ) );
|
||||
if( !p->get_argv() )
|
||||
p->set_argv(completions_to_char_arr( *args ));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2194,14 +2188,14 @@ void parser_t::skipped_exec( job_t * j )
|
||||
{
|
||||
if( p->type == INTERNAL_BUILTIN )
|
||||
{
|
||||
if(( wcscmp( p->argv[0], L"for" )==0) ||
|
||||
( wcscmp( p->argv[0], L"switch" )==0) ||
|
||||
( wcscmp( p->argv[0], L"begin" )==0) ||
|
||||
( wcscmp( p->argv[0], L"function" )==0))
|
||||
if(( wcscmp( p->argv0(), L"for" )==0) ||
|
||||
( wcscmp( p->argv0(), L"switch" )==0) ||
|
||||
( wcscmp( p->argv0(), L"begin" )==0) ||
|
||||
( wcscmp( p->argv0(), L"function" )==0))
|
||||
{
|
||||
this->push_block( FAKE );
|
||||
}
|
||||
else if( wcscmp( p->argv[0], L"end" )==0)
|
||||
else if( wcscmp( p->argv0(), L"end" )==0)
|
||||
{
|
||||
if(!current_block->outer->skip )
|
||||
{
|
||||
@ -2210,7 +2204,7 @@ void parser_t::skipped_exec( job_t * j )
|
||||
}
|
||||
parser_t::pop_block();
|
||||
}
|
||||
else if( wcscmp( p->argv[0], L"else" )==0)
|
||||
else if( wcscmp( p->argv0(), L"else" )==0)
|
||||
{
|
||||
if( (current_block->type == IF ) &&
|
||||
(current_block->param1.if_state != 0))
|
||||
@ -2219,7 +2213,7 @@ void parser_t::skipped_exec( job_t * j )
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( wcscmp( p->argv[0], L"case" )==0)
|
||||
else if( wcscmp( p->argv0(), L"case" )==0)
|
||||
{
|
||||
if( (current_block->type == SWITCH ) )
|
||||
{
|
||||
@ -2287,12 +2281,12 @@ void parser_t::eval_job( tokenizer *tok )
|
||||
}
|
||||
}
|
||||
|
||||
j->first_process = (process_t *)halloc( j, sizeof( process_t ) );
|
||||
j->first_process = new process_t();
|
||||
|
||||
job_begin_pos = tok_get_pos( tok );
|
||||
|
||||
if( parse_job( j->first_process, j, tok ) &&
|
||||
j->first_process->argv )
|
||||
j->first_process->get_argv() )
|
||||
{
|
||||
if( job_start_pos < tok_get_pos( tok ) )
|
||||
{
|
||||
@ -2302,9 +2296,7 @@ void parser_t::eval_job( tokenizer *tok )
|
||||
if( newline )
|
||||
stop_pos = mini( stop_pos, newline - tok_string(tok) );
|
||||
|
||||
j->command = halloc_wcsndup( j,
|
||||
tok_string(tok)+start_pos,
|
||||
stop_pos-start_pos );
|
||||
j->command = wcstring(tok_string(tok)+start_pos, stop_pos-start_pos);
|
||||
}
|
||||
else
|
||||
j->command = L"";
|
||||
@ -2312,7 +2304,7 @@ void parser_t::eval_job( tokenizer *tok )
|
||||
if( profile )
|
||||
{
|
||||
t2 = get_time();
|
||||
profile_item->cmd = wcsdup( j->command );
|
||||
profile_item->cmd = wcsdup( j->command_cstr() );
|
||||
profile_item->skipped=current_block->skip;
|
||||
}
|
||||
|
||||
|
6
parser.h
6
parser.h
@ -236,7 +236,7 @@ class parser_t {
|
||||
int current_tokenizer_pos;
|
||||
|
||||
/** List of called functions, used to help prevent infinite recursion */
|
||||
std::vector<wcstring> forbidden_function;
|
||||
wcstring_list_t forbidden_function;
|
||||
|
||||
/** String index where the current job started. */
|
||||
int job_start_pos;
|
||||
@ -395,7 +395,7 @@ class parser_t {
|
||||
inside of a conditional block. This is to remove some possibilities
|
||||
of infinite recursion.
|
||||
*/
|
||||
void forbid_function( wchar_t *function );
|
||||
void forbid_function( const wcstring &function );
|
||||
/**
|
||||
Undo last call to parser_forbid_function().
|
||||
*/
|
||||
@ -417,7 +417,7 @@ class parser_t {
|
||||
\param s the string to test
|
||||
\param min_match is the minimum number of characters that must match in a long style option, i.e. the longest common prefix between --help and any other option. If less than 3, 3 will be assumed.
|
||||
*/
|
||||
int is_help( wchar_t *s, int min_match ) const;
|
||||
int is_help( const wchar_t *s, int min_match ) const;
|
||||
|
||||
/**
|
||||
Returns the file currently evaluated by the parser. This can be
|
||||
|
47
proc.cpp
47
proc.cpp
@ -178,7 +178,8 @@ void job_promote(job_t *job)
|
||||
void job_free( job_t * j )
|
||||
{
|
||||
job_remove( j );
|
||||
halloc_free( j );
|
||||
j->~job_t();
|
||||
halloc_free( j );
|
||||
}
|
||||
|
||||
void proc_destroy()
|
||||
@ -191,7 +192,7 @@ void proc_destroy()
|
||||
while( ! jobs.empty() )
|
||||
{
|
||||
job_t *job = jobs.front();
|
||||
debug( 2, L"freeing leaked job %ls", job->command );
|
||||
debug( 2, L"freeing leaked job %ls", job->command_cstr() );
|
||||
job_free( job );
|
||||
}
|
||||
}
|
||||
@ -209,11 +210,12 @@ int proc_get_last_status()
|
||||
job_t *job_create()
|
||||
{
|
||||
int free_id=1;
|
||||
job_t *res;
|
||||
|
||||
|
||||
while( job_get( free_id ) != 0 )
|
||||
free_id++;
|
||||
res = new job_t(free_id);
|
||||
|
||||
void *buff = halloc( 0, sizeof(job_t) );
|
||||
job_t *res = new (buff) job_t(free_id);
|
||||
job_list().push_front(res);
|
||||
|
||||
job_set_flag( res,
|
||||
@ -524,7 +526,7 @@ void job_handle_signal ( int signal, siginfo_t *info, void *con )
|
||||
static void format_job_info( const job_t *j, const wchar_t *status )
|
||||
{
|
||||
fwprintf (stdout, L"\r" );
|
||||
fwprintf (stdout, _( L"Job %d, \'%ls\' has %ls" ), j->job_id, j->command, status);
|
||||
fwprintf (stdout, _( L"Job %d, \'%ls\' has %ls" ), j->job_id, j->command_cstr(), status);
|
||||
fflush( stdout );
|
||||
tputs(clr_eol,1,&writeb);
|
||||
fwprintf (stdout, L"\n" );
|
||||
@ -608,7 +610,7 @@ int job_reap( int interactive )
|
||||
_( L"%ls: Job %d, \'%ls\' terminated by signal %ls (%ls)" ),
|
||||
program_name,
|
||||
j->job_id,
|
||||
j->command,
|
||||
j->command_cstr(),
|
||||
sig2wcs(WTERMSIG(p->status)),
|
||||
signal_get_desc( WTERMSIG(p->status) ) );
|
||||
else
|
||||
@ -616,9 +618,9 @@ int job_reap( int interactive )
|
||||
_( L"%ls: Process %d, \'%ls\' from job %d, \'%ls\' terminated by signal %ls (%ls)" ),
|
||||
program_name,
|
||||
p->pid,
|
||||
p->argv[0],
|
||||
p->argv0(),
|
||||
j->job_id,
|
||||
j->command,
|
||||
j->command_cstr(),
|
||||
sig2wcs(WTERMSIG(p->status)),
|
||||
signal_get_desc( WTERMSIG(p->status) ) );
|
||||
tputs(clr_eol,1,&writeb);
|
||||
@ -851,7 +853,7 @@ static void read_try( job_t *j )
|
||||
|
||||
if( buff )
|
||||
{
|
||||
debug( 3, L"proc::read_try('%ls')\n", j->command );
|
||||
debug( 3, L"proc::read_try('%ls')\n", j->command_cstr() );
|
||||
while(1)
|
||||
{
|
||||
char b[BUFFER_SIZE];
|
||||
@ -899,7 +901,7 @@ static int terminal_give_to_job( job_t *j, int cont )
|
||||
debug( 1,
|
||||
_( L"Could not send job %d ('%ls') to foreground" ),
|
||||
j->job_id,
|
||||
j->command );
|
||||
j->command_cstr() );
|
||||
wperror( L"tcsetpgrp" );
|
||||
return 0;
|
||||
}
|
||||
@ -911,7 +913,7 @@ static int terminal_give_to_job( job_t *j, int cont )
|
||||
debug( 1,
|
||||
_( L"Could not send job %d ('%ls') to foreground" ),
|
||||
j->job_id,
|
||||
j->command );
|
||||
j->command_cstr() );
|
||||
wperror( L"tcsetattr" );
|
||||
return 0;
|
||||
}
|
||||
@ -971,7 +973,7 @@ void job_continue (job_t *j, int cont)
|
||||
L"Continue job %d, gid %d (%ls), %ls, %ls",
|
||||
j->job_id,
|
||||
j->pgid,
|
||||
j->command,
|
||||
j->command_cstr(),
|
||||
job_is_completed( j )?L"COMPLETED":L"UNCOMPLETED",
|
||||
is_interactive?L"INTERACTIVE":L"NON-INTERACTIVE" );
|
||||
|
||||
@ -1169,9 +1171,6 @@ void proc_sanity_check()
|
||||
continue;
|
||||
|
||||
|
||||
validate_pointer( j->command,
|
||||
_( L"Job command" ),
|
||||
0 );
|
||||
validate_pointer( j->first_process,
|
||||
_( L"Process list pointer" ),
|
||||
0 );
|
||||
@ -1185,8 +1184,8 @@ void proc_sanity_check()
|
||||
{
|
||||
debug( 0,
|
||||
_( L"More than one job in foreground: job 1: '%ls' job 2: '%ls'"),
|
||||
fg_job->command,
|
||||
j->command );
|
||||
fg_job->command_cstr(),
|
||||
j->command_cstr() );
|
||||
sanity_lose();
|
||||
}
|
||||
fg_job = j;
|
||||
@ -1195,8 +1194,8 @@ void proc_sanity_check()
|
||||
p = j->first_process;
|
||||
while( p )
|
||||
{
|
||||
validate_pointer( p->argv, _( L"Process argument list" ), 0 );
|
||||
validate_pointer( p->argv[0], _( L"Process name" ), 0 );
|
||||
validate_pointer( p->get_argv(), _( L"Process argument list" ), 0 );
|
||||
validate_pointer( p->argv0(), _( L"Process name" ), 0 );
|
||||
validate_pointer( p->next, _( L"Process list pointer" ), 1 );
|
||||
validate_pointer( p->actual_cmd, _( L"Process command" ), 1 );
|
||||
|
||||
@ -1204,8 +1203,8 @@ void proc_sanity_check()
|
||||
{
|
||||
debug( 0,
|
||||
_( L"Job '%ls', process '%ls' has inconsistent state \'stopped\'=%d" ),
|
||||
j->command,
|
||||
p->argv[0],
|
||||
j->command_cstr(),
|
||||
p->argv0(),
|
||||
p->stopped );
|
||||
sanity_lose();
|
||||
}
|
||||
@ -1214,8 +1213,8 @@ void proc_sanity_check()
|
||||
{
|
||||
debug( 0,
|
||||
_( L"Job '%ls', process '%ls' has inconsistent state \'completed\'=%d" ),
|
||||
j->command,
|
||||
p->argv[0],
|
||||
j->command_cstr(),
|
||||
p->argv0(),
|
||||
p->completed );
|
||||
sanity_lose();
|
||||
}
|
||||
|
89
proc.h
89
proc.h
@ -19,6 +19,7 @@
|
||||
|
||||
#include "util.h"
|
||||
#include "io.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
The status code use when a command was not found
|
||||
@ -126,19 +127,84 @@ enum
|
||||
*/
|
||||
class process_t
|
||||
{
|
||||
private:
|
||||
/** argv parameter for for execv, builtin_run, etc. This is allocated via malloc, and furthermore, each string within it is allocated via malloc as well . Null terminated. */
|
||||
wchar_t **argv_array;
|
||||
|
||||
void free_argv(void) {
|
||||
if (argv_array != NULL) {
|
||||
for (size_t i = 0; argv_array[i] != NULL; i++) {
|
||||
free(argv_array[i]);
|
||||
}
|
||||
free(argv_array);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
process_t() :
|
||||
argv_array(NULL),
|
||||
type(0),
|
||||
actual_cmd(NULL),
|
||||
pid(0),
|
||||
pipe_write_fd(0),
|
||||
pipe_read_fd(0),
|
||||
completed(0),
|
||||
stopped(0),
|
||||
status(0),
|
||||
count_help_magic(0),
|
||||
next(NULL)
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
,last_time(),
|
||||
unsigned long last_jiffies(0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
~process_t()
|
||||
{
|
||||
if (this->next != NULL)
|
||||
delete this->next;
|
||||
this->free_argv();
|
||||
}
|
||||
|
||||
/**
|
||||
Type of process. Can be one of \c EXTERNAL, \c
|
||||
INTERNAL_BUILTIN, \c INTERNAL_FUNCTION, \c INTERNAL_BLOCK,
|
||||
INTERNAL_EXEC, or INTERNAL_BUFFER
|
||||
*/
|
||||
int type;
|
||||
|
||||
|
||||
/** Sets argv */
|
||||
void set_argv(wchar_t **argv) {
|
||||
free_argv();
|
||||
|
||||
/** argv parameter for for execv, builtin_run, etc. */
|
||||
wchar_t **argv;
|
||||
#if 0
|
||||
// argv must be a malloc'd array of malloc'd strings. This bit of nonsense below can help catch if someone doesn't pass us something from malloc.
|
||||
if (argv) {
|
||||
for (size_t i=0; argv[i]; i++) {
|
||||
wchar_t *tmp = wcsdup(argv[i]);
|
||||
free(argv[i]);
|
||||
argv[i] = tmp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
this->argv_array = argv;
|
||||
}
|
||||
|
||||
/** Returns argv */
|
||||
const wchar_t * const *get_argv(void) const { return argv_array; }
|
||||
|
||||
/** Returns argv[0] */
|
||||
const wchar_t *argv0(void) const { return argv_array[0]; }
|
||||
|
||||
/** Returns argv[idx] */
|
||||
const wchar_t *argv(size_t idx) const { return argv_array[idx]; }
|
||||
|
||||
/** actual command to pass to exec in case of EXTERNAL or INTERNAL_EXEC */
|
||||
wchar_t *actual_cmd;
|
||||
const wchar_t *actual_cmd;
|
||||
|
||||
/** process ID */
|
||||
pid_t pid;
|
||||
@ -161,8 +227,8 @@ class process_t
|
||||
/** Special flag to tell the evaluation function for count to print the help information */
|
||||
int count_help_magic;
|
||||
|
||||
/** next process in pipeline */
|
||||
struct process_t *next;
|
||||
/** Next process in pipeline. We own this and we are responsible for deleting it. */
|
||||
struct process_t *next;
|
||||
#ifdef HAVE__PROC_SELF_STAT
|
||||
/** Last time of cpu time check */
|
||||
struct timeval last_time;
|
||||
@ -239,7 +305,7 @@ class job_t
|
||||
public:
|
||||
|
||||
job_t(int jobid) :
|
||||
command(NULL),
|
||||
command(),
|
||||
first_process(NULL),
|
||||
pgid(0),
|
||||
tmodes(),
|
||||
@ -248,6 +314,11 @@ class job_t
|
||||
flags(0)
|
||||
{
|
||||
}
|
||||
|
||||
~job_t() {
|
||||
if (first_process != NULL)
|
||||
delete first_process;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -255,10 +326,12 @@ class job_t
|
||||
job. It is used for displaying messages about job status
|
||||
on the terminal.
|
||||
*/
|
||||
const wchar_t *command;
|
||||
wcstring command;
|
||||
|
||||
const wchar_t *command_cstr() const { return command.c_str(); }
|
||||
|
||||
/**
|
||||
A linked list of all the processes in this job.
|
||||
A linked list of all the processes in this job. We are responsible for deleting this when we are deallocated.
|
||||
*/
|
||||
process_t *first_process;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user