diff -Naurp distcc-2.18.3.orig/src/distcc.c distcc-2.18.3/src/distcc.c --- distcc-2.18.3.orig/src/distcc.c 2004-10-01 17:47:07.000000000 -0700 +++ distcc-2.18.3/src/distcc.c 2005-01-30 22:15:43.883870942 -0800 @@ -135,7 +135,106 @@ static void dcc_client_catch_signals(voi signal(SIGHUP, &dcc_client_signalled); } +#define MAXNEWFLAGS 32 +#define MAXFLAGLEN 127 +static char **getNewArgv(char **argv, const char *newflagsStr) { + char **newargv; + char newflags[MAXNEWFLAGS][MAXFLAGLEN + 1]; + unsigned newflagsCount = 0; + unsigned argc; + unsigned i; + char **p; + + unsigned s, f; /* start/finish of each flag. f points to + * the char AFTER the end (ie the space/\0 + */ + + /* Tokenize the flag list */ + for(s=0; s < strlen(newflagsStr); s=f+1) { + /* Put s at the start of the next flag */ + while(newflagsStr[s] == ' ' || + newflagsStr[s] == '\t') + s++; + if(s == strlen(newflagsStr)) + break; + + f = s + 1; + while(newflagsStr[f] != ' ' && + newflagsStr[f] != '\t' && + newflagsStr[f] != '\0') + f++; + + /* Detect overrun */ + if(MAXFLAGLEN < f - s || MAXNEWFLAGS == newflagsCount) + return NULL; + + strncpy(newflags[newflagsCount], newflagsStr + s, f - s); + newflags[newflagsCount][f - s]='\0'; + newflagsCount++; + } + + /* Calculate original argc and see if it contains -m{abi,32,64} */ + for(argc=0, p=argv; *p; p++, argc++) { + if(newflagsCount && (strncmp(*p, "-m32", 4) == 0 || + strncmp(*p, "-m64", 4) == 0 || + strncmp(*p, "-mabi", 5) == 0)) { + /* Our command line sets the ABI, warn the user about this and ignore + newArgs by setting newflagsCount to 0. + */ + newflagsCount = 0; + fprintf(stderr, "%s: %s detected on the command line overrides implicit %s added by the wrapper.\n", argv[0], *p, newflagsStr); + } + } + + /* Allocate our array */ + newargv = (char **)malloc(sizeof(char *) * (argc + newflagsCount + 1)); + + /* Make room for the original, new ones, and the NULL terminator */ + if(!newargv) + return NULL; + + /* Build argv */ + newargv[0] = argv[0]; + + /* The newFlags come first since we want the environment to override them. */ + for(i=1; i - 1 < newflagsCount; i++) { + newargv[i] = newflags[i - 1]; + } + + /* We just use the existing argv[i] as the start. */ + for(; i - newflagsCount < argc; i++) { + newargv[i] = argv[i - newflagsCount]; + } + + /* And now cap it off... */ + newargv[i] = NULL; + + return newargv; +} + +static char **getNewArgvFromEnv(char **argv) { + char **newargv = argv; + + if(getenv("ABI")) { + char *envar = (char *)malloc(sizeof(char) * (strlen("CFLAGS_") + strlen(getenv("ABI")) + 1 )); + + if(!envar) + return NULL; + + /* We use CFLAGS_${ABI} for gcc, g++, g77, etc as they are + * the same no matter which compiler we are using. + */ + sprintf(envar, "CFLAGS_%s", getenv("ABI")); + + if(getenv(envar)) + newargv = getNewArgv(argv, getenv(envar)); + + free(envar); + } + + return newargv; +} /** * distcc client entry point. @@ -150,6 +249,7 @@ int main(int argc, char **argv) int status, sg_level, tweaked_path = 0; char **compiler_args; char *compiler_name; + char **newargv; int ret; dcc_client_catch_signals(); @@ -183,7 +283,12 @@ int main(int argc, char **argv) goto out; } - dcc_find_compiler(argv, &compiler_args); + if(!(newargv = getNewArgvFromEnv(argv))) { + ret = EXIT_OUT_OF_MEMORY; + goto out; + } + dcc_find_compiler(newargv, &compiler_args); + if (newargv != argv) free(newargv); /* compiler_args is now respectively either "cc -c hello.c" or * "gcc -c hello.c" */ @@ -200,7 +305,12 @@ int main(int argc, char **argv) &tweaked_path)) != 0) goto out; - dcc_copy_argv(argv, &compiler_args, 0); + if(!(newargv = getNewArgvFromEnv(argv))) { + ret = EXIT_OUT_OF_MEMORY; + goto out; + } + dcc_copy_argv(newargv, &compiler_args, 0); + if (newargv != argv) free(newargv); compiler_args[0] = compiler_name; }