Mercurial > hg > aboriginal
comparison sources/toys/ccwrap.c @ 1745:8d82dc711a93 draft
Fix the darn ccwrap symlink resolution path logic that was finding the wrong /usr/include.
It wasn't distcc's fault. Test _before_ following symlinks, otherwise the
original location found doesn't get checked to see if it's valid.
author | Rob Landley <rob@landley.net> |
---|---|
date | Sun, 22 Feb 2015 20:45:25 -0600 |
parents | 156eb9b36245 |
children | 117f1c93212a |
comparison
equal
deleted
inserted
replaced
1744:4c3164f0d2c2 | 1745:8d82dc711a93 |
---|---|
158 int main(int argc, char *argv[]) | 158 int main(int argc, char *argv[]) |
159 { | 159 { |
160 char *topdir, *ccprefix, *dynlink, *cc, *temp, **keepv, **hdr, **outv; | 160 char *topdir, *ccprefix, *dynlink, *cc, *temp, **keepv, **hdr, **outv; |
161 int i, keepc, srcfiles, flags, outc; | 161 int i, keepc, srcfiles, flags, outc; |
162 struct dlist *libs = 0; | 162 struct dlist *libs = 0; |
163 | |
164 if (getenv("CCWRAP_DEBUG")) fprintf(stderr, "%s@%s\n", argv[0], getcwd(0, 0)); | |
163 | 165 |
164 keepv = xmalloc(argc*sizeof(char *)); | 166 keepv = xmalloc(argc*sizeof(char *)); |
165 flags = MASK_BIT(Clink)|MASK_BIT(Cstart)|MASK_BIT(Cstdinc)|MASK_BIT(Cstdlib) | 167 flags = MASK_BIT(Clink)|MASK_BIT(Cstart)|MASK_BIT(Cstdinc)|MASK_BIT(Cstdlib) |
166 |MASK_BIT(CPctordtor); | 168 |MASK_BIT(CPctordtor); |
167 keepc = srcfiles = 0; | 169 keepc = srcfiles = 0; |
189 else if (!strcmp("cc", ccprefix+i-2)) i-=2; | 191 else if (!strcmp("cc", ccprefix+i-2)) i-=2; |
190 else if (!strcmp("cpp", ccprefix+i-3)) { | 192 else if (!strcmp("cpp", ccprefix+i-3)) { |
191 i -= 3; | 193 i -= 3; |
192 CLEAR_FLAG(Clink); | 194 CLEAR_FLAG(Clink); |
193 } else return 1; // TODO: wrap ld | 195 } else return 1; // TODO: wrap ld |
194 if (!(ccprefix = strndup(ccprefix, i))) exit(1); | 196 if (!(ccprefix = strndup(ccprefix, (size_t)i))) exit(1); // todo: fix uclibc |
195 | 197 |
196 // Find the cannonical path to the directory containing our executable | 198 // Find the cannonical path to the directory containing our executable |
197 topdir = find_in_path(getenv("PATH"), *argv, 1); | 199 topdir = find_in_path(getenv("PATH"), *argv, 1); |
198 | 200 |
199 // Instead of realpath(), follow symlinks until we hit a real file or until | 201 // Instead of realpath(), follow symlinks until we hit a real file or until |
201 // include and lib directories you can add stuff to, realpath() will drill | 203 // include and lib directories you can add stuff to, realpath() will drill |
202 // past snapshots to a "real" filesystem that may be read-only.) | 204 // past snapshots to a "real" filesystem that may be read-only.) |
203 i = 99; | 205 i = 99; |
204 while (topdir && i--) { | 206 while (topdir && i--) { |
205 char buf[4200], *new, *libc; | 207 char buf[4200], *new, *libc; |
206 int len = readlink(topdir, buf, 4096); | 208 int len; |
207 | 209 |
208 if (len<1) break; | 210 // If this isn't a symlink, we stop here. |
209 | 211 if (1 > (len = readlink(topdir, buf, 4096))) break; |
210 // Absolute symlink replaces, relative symlink appends | |
211 buf[len] = 0; | 212 buf[len] = 0; |
213 | |
214 // if we can find libc.so from here, stop looking. | |
215 if (!(temp = strrchr(topdir, '/'))) break; // should never happen | |
216 *temp = 0; | |
217 libc = xmprintf("%s/../lib/libc.so", topdir); | |
218 *temp = '/'; | |
219 len = access(libc, R_OK); | |
220 free(libc); | |
221 if (!len) break; | |
222 | |
223 // Follow symlink. Absolute symlink replaces, relative symlink appends | |
212 if (buf[0] == '/') new = strdup(buf); | 224 if (buf[0] == '/') new = strdup(buf); |
213 else { | 225 else { |
214 temp = strrchr(topdir, '/'); | 226 temp = strrchr(topdir, '/'); |
215 if (temp) *temp = 0; | 227 if (temp) *temp = 0; |
216 new = xmprintf("%s/%s", topdir, buf); | 228 new = xmprintf("%s/%s", topdir, buf); |
217 } | 229 } |
218 free(topdir); | 230 free(topdir); |
219 topdir = new; | 231 topdir = new; |
220 | |
221 // if we can find libc.so from here, stop looking. | |
222 temp = strrchr(new, '/'); | |
223 *temp = 0; | |
224 libc = xmprintf("%s/../lib/libc.so", new); | |
225 *temp = '/'; | |
226 len = access(libc, R_OK); | |
227 free(libc); | |
228 if (!len) break; | |
229 } | 232 } |
230 | 233 |
231 if (!topdir || !(temp = strrchr(topdir, '/')) || strlen(*argv)<2) { | 234 if (!topdir || !(temp = strrchr(topdir, '/')) || strlen(*argv)<2) { |
232 fprintf(stderr, "Can't find %s in $PATH (did you export it?)\n", *argv); | 235 fprintf(stderr, "Can't find %s in $PATH (did you export it?)\n", *argv); |
233 exit(1); | 236 exit(1); |