1 |
vapier 09/01/02 00:43:32 |
2 |
|
3 |
Modified: wrapper-1.5.1.c |
4 |
Log: |
5 |
optimize memory/string usage a bit more |
6 |
(Portage version: 2.2_rc20/cvs/Linux 2.6.28 x86_64) |
7 |
|
8 |
Revision Changes Path |
9 |
1.2 sys-devel/gcc-config/files/wrapper-1.5.1.c |
10 |
|
11 |
file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/sys-devel/gcc-config/files/wrapper-1.5.1.c?rev=1.2&view=markup |
12 |
plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/sys-devel/gcc-config/files/wrapper-1.5.1.c?rev=1.2&content-type=text/plain |
13 |
diff : http://sources.gentoo.org/viewcvs.py/gentoo-x86/sys-devel/gcc-config/files/wrapper-1.5.1.c?r1=1.1&r2=1.2 |
14 |
|
15 |
Index: wrapper-1.5.1.c |
16 |
=================================================================== |
17 |
RCS file: /var/cvsroot/gentoo-x86/sys-devel/gcc-config/files/wrapper-1.5.1.c,v |
18 |
retrieving revision 1.1 |
19 |
retrieving revision 1.2 |
20 |
diff -u -r1.1 -r1.2 |
21 |
--- wrapper-1.5.1.c 16 Mar 2008 01:20:11 -0000 1.1 |
22 |
+++ wrapper-1.5.1.c 2 Jan 2009 00:43:32 -0000 1.2 |
23 |
@@ -1,28 +1,41 @@ |
24 |
/* |
25 |
* Copyright 1999-2008 Gentoo Foundation |
26 |
* Distributed under the terms of the GNU General Public License v2 |
27 |
- * $Header: /var/cvsroot/gentoo-x86/sys-devel/gcc-config/files/wrapper-1.5.1.c,v 1.1 2008/03/16 01:20:11 vapier Exp $ |
28 |
+ * $Header: /var/cvsroot/gentoo-x86/sys-devel/gcc-config/files/wrapper-1.5.1.c,v 1.2 2009/01/02 00:43:32 vapier Exp $ |
29 |
* Author: Martin Schlemmer <azarah@g.o> |
30 |
* az's lackey: Mike Frysinger <vapier@g.o> |
31 |
*/ |
32 |
|
33 |
-#define _GNU_SOURCE |
34 |
+#ifdef DEBUG |
35 |
+# define USE_DEBUG 1 |
36 |
+#else |
37 |
+# define USE_DEBUG 0 |
38 |
+#endif |
39 |
|
40 |
+#include <errno.h> |
41 |
+#include <libgen.h> |
42 |
+#include <limits.h> |
43 |
#include <stdio.h> |
44 |
#include <stdlib.h> |
45 |
-#include <sys/types.h> |
46 |
-#include <sys/stat.h> |
47 |
-#include <sys/param.h> |
48 |
-#include <unistd.h> |
49 |
-#include <sys/wait.h> |
50 |
-#include <libgen.h> |
51 |
#include <string.h> |
52 |
-#include <stdarg.h> |
53 |
-#include <errno.h> |
54 |
+#include <unistd.h> |
55 |
+#include <sys/stat.h> |
56 |
+#include <sys/types.h> |
57 |
|
58 |
#define GCC_CONFIG "/usr/bin/gcc-config" |
59 |
#define ENVD_BASE "/etc/env.d/05gcc" |
60 |
|
61 |
+#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) |
62 |
+ |
63 |
+/* basename(3) is allowed to modify memory */ |
64 |
+#undef basename |
65 |
+#define basename(path) \ |
66 |
+({ \ |
67 |
+ char *__path = path; \ |
68 |
+ char *__ret = strrchr(__path, '/'); \ |
69 |
+ __ret ? __ret + 1 : __path; \ |
70 |
+}) |
71 |
+ |
72 |
struct wrapper_data { |
73 |
char *name, *fullname, *bin, *path; |
74 |
}; |
75 |
@@ -33,27 +46,19 @@ |
76 |
} wrapper_aliases[] = { |
77 |
{ "cc", "gcc" }, |
78 |
{ "f77", "g77" }, |
79 |
- { NULL, NULL } |
80 |
}; |
81 |
|
82 |
-static void wrapper_err(char *msg, ...) |
83 |
-{ |
84 |
- va_list args; |
85 |
- fprintf(stderr, "gcc-config error: "); |
86 |
- va_start(args, msg); |
87 |
- vfprintf(stderr, msg, args); |
88 |
- va_end(args); |
89 |
- fprintf(stderr, "\n"); |
90 |
- exit(1); |
91 |
-} |
92 |
+#define wrapper_warn(fmt, ...) fprintf(stderr, "%s" fmt "\n", "gcc-config: ", ## __VA_ARGS__) |
93 |
+#define wrapper_err(fmt, ...) ({ wrapper_warn("%s" fmt, "error: ", ## __VA_ARGS__); exit(1); }) |
94 |
#define wrapper_errp(fmt, ...) wrapper_err(fmt ": %s", ## __VA_ARGS__, strerror(errno)) |
95 |
+#define wrapper_dbg(fmt, ...) ({ if (USE_DEBUG) wrapper_warn(fmt, ## __VA_ARGS__); }) |
96 |
|
97 |
#define xmemwrap(func, proto, use) \ |
98 |
static void *x ## func proto \ |
99 |
{ \ |
100 |
void *ret = func use; \ |
101 |
if (!ret) \ |
102 |
- wrapper_err(#func "out of memory"); \ |
103 |
+ wrapper_err(#func "%s", ": out of memory"); \ |
104 |
return ret; \ |
105 |
} |
106 |
xmemwrap(malloc, (size_t size), (size)) |
107 |
@@ -67,25 +72,34 @@ |
108 |
static int check_for_target(char *path, struct wrapper_data *data) |
109 |
{ |
110 |
struct stat sbuf; |
111 |
- char str[MAXPATHLEN + 1]; |
112 |
- size_t len = strlen(path) + strlen(data->name) + 2; |
113 |
- |
114 |
- snprintf(str, sizeof(str), "%s/%s", path, data->name); |
115 |
+ char str[PATH_MAX + 1]; |
116 |
+ size_t path_len = strlen(path); |
117 |
+ size_t len = path_len + strlen(data->name) + 2; |
118 |
+ |
119 |
+ if (sizeof(str) < len) |
120 |
+ wrapper_warn("path too long: %s", path); |
121 |
+ |
122 |
+ strcpy(str, path); |
123 |
+ str[path_len] = '/'; |
124 |
+ str[path_len+1] = '\0'; |
125 |
+ strcat(str, data->name); |
126 |
|
127 |
/* Stat possible file to check that |
128 |
* 1) it exist and is a regular file, and |
129 |
* 2) it is not the wrapper itself, and |
130 |
* 3) it is in a /gcc-bin/ directory tree |
131 |
*/ |
132 |
- if (stat(str, &sbuf) == 0 && |
133 |
- (S_ISREG(sbuf.st_mode) || S_ISLNK(sbuf.st_mode)) && |
134 |
- (strcmp(str, data->fullname) != 0) && |
135 |
- (strstr(str, "/gcc-bin/") != 0)) |
136 |
+ if (strcmp(str, data->fullname) != 0 && |
137 |
+ strstr(str, "/gcc-bin/") != NULL && |
138 |
+ stat(str, &sbuf) == 0 && |
139 |
+ (S_ISREG(sbuf.st_mode) || S_ISLNK(sbuf.st_mode))) |
140 |
{ |
141 |
+ wrapper_dbg("%s: found in %s", data->name, path); |
142 |
data->bin = xstrdup(str); |
143 |
return 1; |
144 |
} |
145 |
|
146 |
+ wrapper_dbg("%s: did not find in %s", data->name, path); |
147 |
return 0; |
148 |
} |
149 |
|
150 |
@@ -112,6 +126,7 @@ |
151 |
token = strtok_r(NULL, ":", &state); |
152 |
} |
153 |
|
154 |
+ wrapper_dbg("%s: did not find in PATH", data->name); |
155 |
return 0; |
156 |
} |
157 |
|
158 |
@@ -123,9 +138,9 @@ |
159 |
{ |
160 |
FILE *envfile = NULL; |
161 |
char *token = NULL, *state; |
162 |
- char str[MAXPATHLEN + 1]; |
163 |
+ char str[PATH_MAX + 1]; |
164 |
char *strp = str; |
165 |
- char envd_file[MAXPATHLEN + 1]; |
166 |
+ char envd_file[PATH_MAX + 1]; |
167 |
|
168 |
if (!cross_compile) { |
169 |
/* for the sake of speed, we'll keep a symlink around for |
170 |
@@ -138,7 +153,7 @@ |
171 |
return 0; |
172 |
ctarget = xstrdup(data->name); |
173 |
ctarget[end - data->name] = '\0'; |
174 |
- snprintf(envd_file, MAXPATHLEN, "%s-%s", ENVD_BASE, ctarget); |
175 |
+ snprintf(envd_file, PATH_MAX, "%s-%s", ENVD_BASE, ctarget); |
176 |
free(ctarget); |
177 |
} |
178 |
|
179 |
@@ -146,7 +161,7 @@ |
180 |
if (envfile == NULL) |
181 |
return 0; |
182 |
|
183 |
- while (fgets(strp, MAXPATHLEN, envfile) != NULL) { |
184 |
+ while (fgets(strp, PATH_MAX, envfile) != NULL) { |
185 |
/* Keep reading ENVD_FILE until we get a line that |
186 |
* starts with 'GCC_PATH=' ... keep 'PATH=' around |
187 |
* for older gcc versions. |
188 |
@@ -156,13 +171,13 @@ |
189 |
continue; |
190 |
|
191 |
token = strtok_r(strp, "=", &state); |
192 |
- if ((token != NULL) && strlen(token)) |
193 |
+ if ((token != NULL) && token[0]) |
194 |
/* The second token should be the value of PATH .. */ |
195 |
token = strtok_r(NULL, "=", &state); |
196 |
else |
197 |
goto bail; |
198 |
|
199 |
- if ((token != NULL) && strlen(token)) { |
200 |
+ if ((token != NULL) && token[0]) { |
201 |
strp = token; |
202 |
/* A bash variable may be unquoted, quoted with " or |
203 |
* quoted with ', so extract the value without those .. |
204 |
@@ -202,8 +217,8 @@ |
205 |
if (inpipe == NULL) |
206 |
wrapper_errp("could not open pipe"); |
207 |
|
208 |
- char str[MAXPATHLEN + 1]; |
209 |
- if (fgets(str, MAXPATHLEN, inpipe) == 0) |
210 |
+ char str[PATH_MAX + 1]; |
211 |
+ if (fgets(str, PATH_MAX, inpipe) == 0) |
212 |
wrapper_errp("could not get compiler binary path"); |
213 |
|
214 |
/* chomp! */ |
215 |
@@ -211,7 +226,7 @@ |
216 |
if (str[plen-1] == '\n') |
217 |
str[plen-1] = '\0'; |
218 |
|
219 |
- data->bin = xmalloc(strlen(str) + 1 + strlen(data->name) + 1); |
220 |
+ data->bin = xmalloc(plen + 1 + strlen(data->name) + 1); |
221 |
sprintf(data->bin, "%s/%s", str, data->name); |
222 |
|
223 |
pclose(inpipe); |
224 |
@@ -221,28 +236,28 @@ |
225 |
static void modify_path(struct wrapper_data *data) |
226 |
{ |
227 |
char *newpath = NULL, *token = NULL, *state; |
228 |
- char dname_data[MAXPATHLEN + 1], str[MAXPATHLEN + 1]; |
229 |
+ char dname_data[PATH_MAX + 1], str[PATH_MAX + 1]; |
230 |
char *str2 = dname_data, *dname = dname_data; |
231 |
size_t len = 0; |
232 |
|
233 |
if (data->bin == NULL) |
234 |
return; |
235 |
|
236 |
- snprintf(str2, MAXPATHLEN + 1, "%s", data->bin); |
237 |
- |
238 |
- if ((dname = dirname(str2)) == NULL) |
239 |
+ if (data->path == NULL) |
240 |
return; |
241 |
|
242 |
- if (data->path == NULL) |
243 |
+ snprintf(str2, PATH_MAX + 1, "%s", data->bin); |
244 |
+ |
245 |
+ if ((dname = dirname(str2)) == NULL) |
246 |
return; |
247 |
|
248 |
/* Make a copy since strtok_r will modify path */ |
249 |
- snprintf(str, MAXPATHLEN + 1, "%s", data->path); |
250 |
+ snprintf(str, PATH_MAX + 1, "%s", data->path); |
251 |
|
252 |
token = strtok_r(str, ":", &state); |
253 |
|
254 |
/* Check if we already appended our bin location to PATH */ |
255 |
- if ((token != NULL) && strlen(token)) |
256 |
+ if ((token != NULL) && token[0]) |
257 |
if (!strcmp(token, dname)) |
258 |
return; |
259 |
|
260 |
@@ -256,7 +271,7 @@ |
261 |
} |
262 |
|
263 |
static char *abi_flags[] = { |
264 |
- "-m32", "-m64", "-mabi", NULL |
265 |
+ "-m32", "-m64", "-mabi", |
266 |
}; |
267 |
static char **build_new_argv(char **argv, const char *newflags_str) |
268 |
{ |
269 |
@@ -274,7 +289,7 @@ |
270 |
* of the time ... |
271 |
*/ |
272 |
for (argc = 0; argv[argc]; ++argc) |
273 |
- for (i = 0; abi_flags[i]; ++i) |
274 |
+ for (i = 0; i < ARRAY_SIZE(abi_flags); ++i) |
275 |
if (!strncmp(argv[argc], abi_flags[i], strlen(abi_flags[i]))) |
276 |
return retargv; |
277 |
|
278 |
@@ -308,11 +323,11 @@ |
279 |
data.path = xstrdup(getenv("PATH")); |
280 |
|
281 |
/* What should we find ? */ |
282 |
- data.name = basename(xstrdup(argv[0])); |
283 |
+ data.name = basename(argv[0]); |
284 |
|
285 |
/* Allow for common compiler names like cc->gcc */ |
286 |
size_t i; |
287 |
- for (i = 0; wrapper_aliases[i].alias; ++i) |
288 |
+ for (i = 0; i < ARRAY_SIZE(wrapper_aliases); ++i) |
289 |
if (!strcmp(data.name, wrapper_aliases[i].alias)) |
290 |
data.name = wrapper_aliases[i].target; |