summaryrefslogtreecommitdiff
blob: 8a7b37e878bb593bdf52b1ebba42b626ddff09ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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;
     }