Clean up how argv is stored in process_t

This commit is contained in:
ridiculousfish 2012-01-31 18:06:20 -08:00
parent 207ab2aa5b
commit beece6a828
7 changed files with 48 additions and 61 deletions

View file

@ -156,20 +156,14 @@ wchar_t **list_to_char_arr( array_list_t *l )
return res; return res;
} }
wchar_t **completions_to_char_arr( std::vector<completion_t> &l ) wcstring_list_t completions_to_wcstring_list( const std::vector<completion_t> &list )
{ {
wchar_t ** res = (wchar_t **)malloc( sizeof(wchar_t *)*( l.size() + 1) ); wcstring_list_t strings;
size_t i; strings.reserve(list.size());
if( res == 0 ) for (std::vector<completion_t>::const_iterator iter = list.begin(); iter != list.end(); iter++) {
{ strings.push_back(iter->completion);
DIE_MEM(); }
} return strings;
for( i=0; i< l.size(); i++ )
{
res[i] = wcsdup(l.at(i).completion.c_str());
}
res[i]='\0';
return res;
} }

View file

@ -195,7 +195,7 @@ void show_stackframe();
*/ */
wchar_t **list_to_char_arr( array_list_t *l ); wchar_t **list_to_char_arr( array_list_t *l );
wchar_t **completions_to_char_arr( std::vector<completion_t> &l ); wcstring_list_t completions_to_wcstring_list( const std::vector<completion_t> &completions );
/** /**
Read a line from the stream f into the buffer buff of length len. If Read a line from the stream f into the buffer buff of length len. If

View file

@ -2159,4 +2159,3 @@ void complete_print( string_buffer_t *out )
} }
} }
} }

View file

@ -534,29 +534,20 @@ static void launch_process( process_t *p )
if( (read==1) && (begin[0] == ':') ) if( (read==1) && (begin[0] == ':') )
{ {
int count = 0;
int i = 1;
wchar_t **res;
char **res_real;
while( p->argv(count) != 0 ) wcstring_list_t argv;
count++;
res = (wchar_t **)malloc( sizeof(wchar_t*)*(count+3));
const wchar_t *sh_command = L"/bin/sh"; const wchar_t *sh_command = L"/bin/sh";
argv.push_back(sh_command);
res[0] = wcsdup(sh_command); argv.push_back(p->actual_cmd);
res[1] = wcsdup(p->actual_cmd); for(size_t i=1; p->argv(i) != NULL; i++ ){
argv.push_back(p->argv(i));
for( i=1; p->argv(i) != NULL; i++ ){
res[i+1] = wcsdup(p->argv(i));
} }
res[i+1] = 0; p->set_argv(argv);
p->set_argv(res);
p->actual_cmd = wcsdup(sh_command); p->actual_cmd = wcsdup(sh_command);
res_real = wcsv2strv( (const wchar_t **) res); char **res_real = wcsv2strv( p->get_argv() );
execve ( wcs2str(p->actual_cmd), execve ( wcs2str(p->actual_cmd),
res_real, res_real,

View file

@ -1270,7 +1270,7 @@ void parser_t::parse_job_argument_list( process_t *p,
return; return;
} }
p->set_argv(completions_to_char_arr(args)); p->set_argv(completions_to_wcstring_list(args));
p->next = new process_t(); p->next = new process_t();
tok_next( tok ); tok_next( tok );
@ -1293,7 +1293,7 @@ void parser_t::parse_job_argument_list( process_t *p,
case TOK_END: case TOK_END:
{ {
if( !p->get_argv() ) if( !p->get_argv() )
p->set_argv(completions_to_char_arr(args)); p->set_argv(completions_to_wcstring_list(args));
if( tok_has_next(tok)) if( tok_has_next(tok))
tok_next(tok); tok_next(tok);
@ -2133,7 +2133,7 @@ int parser_t::parse_job( process_t *p,
if( p->type == INTERNAL_BUILTIN && parser_keywords_skip_arguments(args.at(0).completion)) if( p->type == INTERNAL_BUILTIN && parser_keywords_skip_arguments(args.at(0).completion))
{ {
if( !p->get_argv() ) if( !p->get_argv() )
p->set_argv(completions_to_char_arr(args)); p->set_argv(completions_to_wcstring_list(args));
} }
else else
{ {

View file

@ -183,6 +183,31 @@ void job_free( job_t * j )
halloc_free( j ); halloc_free( j );
} }
void process_t::free_argv(void) {
if (argv_array != NULL) {
for (size_t i = 0; argv_array[i] != NULL; i++) {
delete [] argv_array[i];
}
delete [] argv_array;
}
argv_array = NULL;
}
void process_t::set_argv(const wcstring_list_t &argv) {
/* Get rid of the old argv */
free_argv();
/* Allocate our null-terminated array of null-terminated strings */
size_t i, count = argv.size();
argv_array = new wchar_t* [count + 1];
for (i=0; i < count; i++) {
const wcstring &str = argv.at(i);
argv_array[i] = new wchar_t [1 + str.size()];
wcscpy(argv_array[i], str.c_str());
}
argv_array[i] = NULL;
}
void proc_destroy() void proc_destroy()
{ {
delete event.arguments; delete event.arguments;

28
proc.h
View file

@ -128,17 +128,10 @@ enum
class process_t class process_t
{ {
private: 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. */ /** argv parameter for for execv, builtin_run, etc. This is allocated via new, and furthermore, each string within it is allocated via new as well. Null terminated. */
wchar_t **argv_array; wchar_t **argv_array;
void free_argv(void) { 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: public:
@ -178,22 +171,7 @@ class process_t
/** Sets argv */ /** Sets argv */
void set_argv(wchar_t **argv) { void set_argv(const wcstring_list_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
free_argv();
this->argv_array = argv;
}
/** Returns argv */ /** Returns argv */
const wchar_t * const *get_argv(void) const { return argv_array; } const wchar_t * const *get_argv(void) const { return argv_array; }