From b03059cbda539657716b702ea22de72a92d2e3ad Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 2 Aug 2010 12:07:53 +0200 Subject: [PATCH] winebuild: Add a spawn() helper function to avoid starting a shell where possible. --- tools/winebuild/build.h | 16 ++++- tools/winebuild/import.c | 58 +++++------------ tools/winebuild/res32.c | 14 ++--- tools/winebuild/utils.c | 132 ++++++++++++++++++++++++++++----------- 4 files changed, 131 insertions(+), 89 deletions(-) diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 9c05d59bf71..ceaa68ad985 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -135,6 +135,13 @@ extern char *target_alias; extern enum target_cpu target_cpu; extern enum target_platform target_platform; +struct strarray +{ + const char **str; + unsigned int count; + unsigned int max; +}; + /* entry point flags */ #define FLAG_NORELAY 0x01 /* don't use relay debugging for this function */ #define FLAG_NONAME 0x02 /* don't export function by name */ @@ -200,6 +207,10 @@ extern char *xstrdup( const char *str ); extern char *strupper(char *s); extern int strendswith(const char* str, const char* end); extern char *strmake(const char* fmt, ...) __attribute__((__format__ (__printf__, 1, 2 ))); +extern struct strarray *strarray_init(void); +extern void strarray_add( struct strarray *array, ... ); +extern void strarray_addv( struct strarray *array, char * const *argv ); +extern void strarray_free( struct strarray *array ); extern DECLSPEC_NORETURN void fatal_error( const char *msg, ... ) __attribute__ ((__format__ (__printf__, 1, 2))); extern DECLSPEC_NORETURN void fatal_perror( const char *msg, ... ) @@ -212,9 +223,10 @@ extern int output( const char *format, ... ) __attribute__ ((__format__ (__printf__, 1, 2))); extern void output_cfi( const char *format, ... ) __attribute__ ((__format__ (__printf__, 1, 2))); +extern void spawn( struct strarray *array ); extern char *find_tool( const char *name, const char * const *names ); -extern const char *get_as_command(void); -extern const char *get_ld_command(void); +extern struct strarray *get_as_command(void); +extern struct strarray *get_ld_command(void); extern const char *get_nm_command(void); extern char *get_temp_file_name( const char *prefix, const char *suffix ); extern void output_standard_file_header(void); diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index faf71976722..68a4f6a35e3 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -524,23 +524,16 @@ static char *create_undef_symbols_file( DLLSPEC *spec ) /* returns the name of the combined file */ static const char *ldcombine_files( DLLSPEC *spec, char **argv ) { - unsigned int i, len = 0; - const char *prog = get_ld_command(); - char *cmd, *p, *ld_tmp_file, *undef_file; - int err; + char *ld_tmp_file, *undef_file; + struct strarray *args = get_ld_command(); undef_file = create_undef_symbols_file( spec ); - len += strlen(undef_file) + 1; ld_tmp_file = get_temp_file_name( output_file_name, ".o" ); - for (i = 0; argv[i]; i++) len += strlen(argv[i]) + 1; - cmd = p = xmalloc( len + strlen(ld_tmp_file) + 8 + strlen(prog) ); - p += sprintf( cmd, "%s -r -o %s %s", prog, ld_tmp_file, undef_file ); - for (i = 0; argv[i]; i++) - p += sprintf( p, " %s", argv[i] ); - if (verbose) fprintf( stderr, "%s\n", cmd ); - err = system( cmd ); - if (err) fatal_error( "%s -r failed with status %d\n", prog, err ); - free( cmd ); + + strarray_add( args, "-r", "-o", ld_tmp_file, undef_file, NULL ); + strarray_addv( args, argv ); + spawn( args ); + strarray_free( args ); return ld_tmp_file; } @@ -1318,9 +1311,8 @@ void output_imports( DLLSPEC *spec ) /* output an import library for a Win32 module and additional object files */ void output_import_lib( DLLSPEC *spec, char **argv ) { - char *dlltool, *def_file; - char *cmd; - int err; + struct strarray *args = strarray_init(); + char *def_file; if (target_platform != PLATFORM_WINDOWS) fatal_error( "Unix-style import libraries not supported yet\n" ); @@ -1333,33 +1325,17 @@ void output_import_lib( DLLSPEC *spec, char **argv ) fclose( output_file ); output_file = NULL; - dlltool = find_tool( "dlltool", NULL ); - cmd = xmalloc( strlen(dlltool) + strlen(output_file_name) + strlen(def_file) + 12 ); - sprintf( cmd, "%s -k -l %s -d %s", dlltool, output_file_name, def_file ); - if (verbose) fprintf( stderr, "%s\n", cmd ); - err = system( cmd ); - if (err) fatal_error( "%s failed with status %d\n", dlltool, err ); - free( cmd ); - free( dlltool ); + strarray_add( args, find_tool( "dlltool", NULL ), "-k", "-l", output_file_name, "-d", def_file, NULL ); + spawn( args ); + strarray_free( args ); if (argv[0]) { - char *ar = find_tool( "ar", NULL ); - int i, len; - - for (i = len = 0; argv[i]; i++) len += strlen(argv[i]) + 1; - cmd = xmalloc( strlen(ar) + strlen(output_file_name) + len + 5 ); - sprintf( cmd, "%s rs %s", ar, output_file_name ); - for (i = 0; argv[i]; i++) - { - strcat( cmd, " " ); - strcat( cmd, argv[i] ); - } - if (verbose) fprintf( stderr, "%s\n", cmd ); - err = system( cmd ); - if (err) fatal_error( "%s failed with status %d\n", dlltool, err ); - free( cmd ); - free( ar ); + args = strarray_init(); + strarray_add( args, find_tool( "ar", NULL ), "rs", output_file_name, NULL ); + strarray_addv( args, argv ); + spawn( args ); + strarray_free( args ); } output_file_name = NULL; } diff --git a/tools/winebuild/res32.c b/tools/winebuild/res32.c index 28b950cc2f3..8a2ac3a5696 100644 --- a/tools/winebuild/res32.c +++ b/tools/winebuild/res32.c @@ -601,7 +601,7 @@ void output_res_o_file( DLLSPEC *spec ) { unsigned int i; char *res_file = NULL; - int fd, err; + int fd; if (!spec->nb_resources) fatal_error( "--resources mode needs at least one resource file as input\n" ); if (!output_file_name) fatal_error( "No output file name specified\n" ); @@ -656,14 +656,10 @@ void output_res_o_file( DLLSPEC *spec ) if (res_file) { - char *prog = find_tool( "windres", NULL ); - char *cmd = xmalloc( strlen(prog) + strlen(res_file) + strlen(output_file_name) + 9 ); - sprintf( cmd, "%s -i %s -o %s", prog, res_file, output_file_name ); - if (verbose) fprintf( stderr, "%s\n", cmd ); - err = system( cmd ); - if (err) fatal_error( "%s failed with status %d\n", prog, err ); - free( cmd ); - free( prog ); + struct strarray *args = strarray_init(); + strarray_add( args, find_tool( "windres", NULL ), "-i", res_file, "-o", output_file_name, NULL ); + spawn( args ); + strarray_free( args ); } output_file_name = NULL; /* so we don't try to assemble it */ } diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c index d5de2209c7b..251ab00f997 100644 --- a/tools/winebuild/utils.c +++ b/tools/winebuild/utils.c @@ -138,6 +138,46 @@ char *strmake( const char* fmt, ... ) } } +struct strarray *strarray_init(void) +{ + struct strarray *array = xmalloc( sizeof(*array) ); + array->count = 0; + array->max = 16; + array->str = xmalloc( array->max * sizeof(*array->str) ); + return array; +} + +static void strarray_add_one( struct strarray *array, const char *str ) +{ + if (array->count == array->max) + { + array->max *= 2; + array->str = xrealloc( array->str, array->max * sizeof(*array->str) ); + } + array->str[array->count++] = str; +} + +void strarray_add( struct strarray *array, ... ) +{ + va_list valist; + const char *str; + + va_start( valist, array ); + while ((str = va_arg( valist, const char *))) strarray_add_one( array, str ); + va_end( valist ); +} + +void strarray_addv( struct strarray *array, char * const *argv ) +{ + while (*argv) strarray_add_one( array, *argv++ ); +} + +void strarray_free( struct strarray *array ) +{ + free( array->str ); + free( array ); +} + void fatal_error( const char *msg, ... ) { va_list valist; @@ -218,6 +258,24 @@ int output( const char *format, ... ) return ret; } +void spawn( struct strarray *args ) +{ + unsigned int i; + int status; + + strarray_add_one( args, NULL ); + if (verbose) + for (i = 0; args->str[i]; i++) + fprintf( stderr, "%s%c", args->str[i], args->str[i+1] ? ' ' : '\n' ); + + if ((status = spawnvp( _P_WAIT, args->str[0], args->str ))) + { + if (status > 0) fatal_error( "%s failed with status %u\n", args->str[0], status ); + else fatal_perror( "winebuild" ); + exit( 1 ); + } +} + /* find a build tool in the path, trying the various names */ char *find_tool( const char *name, const char * const *names ) { @@ -282,53 +340,59 @@ char *find_tool( const char *name, const char * const *names ) return xstrdup( name ); } -const char *get_as_command(void) +struct strarray *get_as_command(void) { + struct strarray *args = strarray_init(); + if (!as_command) { static const char * const commands[] = { "gas", "as", NULL }; as_command = find_tool( "as", commands ); + } + strarray_add_one( args, as_command ); - if (force_pointer_size) + if (force_pointer_size) + { + switch (target_platform) { - const char *args = (target_platform == PLATFORM_APPLE) ? - ((force_pointer_size == 8) ? " -arch x86_64" : " -arch i386") : - ((force_pointer_size == 8) ? " --64" : " --32"); - as_command = xrealloc( as_command, strlen(as_command) + strlen(args) + 1 ); - strcat( as_command, args ); + case PLATFORM_APPLE: + strarray_add( args, "-arch", (force_pointer_size == 8) ? "x86_64" : "i386", NULL ); + break; + default: + strarray_add_one( args, (force_pointer_size == 8) ? "--64" : "--32" ); + break; } } - return as_command; + return args; } -const char *get_ld_command(void) +struct strarray *get_ld_command(void) { + struct strarray *args = strarray_init(); + if (!ld_command) { static const char * const commands[] = { "ld", "gld", NULL }; ld_command = find_tool( "ld", commands ); + } + strarray_add_one( args, ld_command ); - if (force_pointer_size) + if (force_pointer_size) + { + switch (target_platform) { - const char *args; - - switch (target_platform) - { - case PLATFORM_APPLE: - args = (force_pointer_size == 8) ? " -arch x86_64" : " -arch i386"; - break; - case PLATFORM_FREEBSD: - args = (force_pointer_size == 8) ? " -m elf_x86_64_fbsd" : " -m elf_i386_fbsd"; - break; - default: - args = (force_pointer_size == 8) ? " -m elf_x86_64" : " -m elf_i386"; - break; - } - ld_command = xrealloc( ld_command, strlen(ld_command) + strlen(args) + 1 ); - strcat( ld_command, args ); + case PLATFORM_APPLE: + strarray_add( args, "-arch", (force_pointer_size == 8) ? "x86_64" : "i386", NULL ); + break; + case PLATFORM_FREEBSD: + strarray_add( args, "-m", (force_pointer_size == 8) ? "elf_x86_64_fbsd" : "elf_i386_fbsd", NULL ); + break; + default: + strarray_add( args, "-m", (force_pointer_size == 8) ? "elf_x86_64" : "elf_i386", NULL ); + break; } } - return ld_command; + return args; } const char *get_nm_command(void) @@ -614,16 +678,10 @@ int remove_stdcall_decoration( char *name ) */ void assemble_file( const char *src_file, const char *obj_file ) { - const char *prog = get_as_command(); - char *cmd; - int err; - - cmd = xmalloc( strlen(prog) + strlen(obj_file) + strlen(src_file) + 6 ); - sprintf( cmd, "%s -o %s %s", prog, obj_file, src_file ); - if (verbose) fprintf( stderr, "%s\n", cmd ); - err = system( cmd ); - if (err) fatal_error( "%s failed with status %d\n", prog, err ); - free( cmd ); + struct strarray *args = get_as_command(); + strarray_add( args, "-o", obj_file, src_file, NULL ); + spawn( args ); + strarray_free( args ); }