Module Name: src Committed By: sjg Date: Sun Feb 13 21:22:41 UTC 2011
Modified Files: src/usr.bin/make: meta.c Log Message: When making a target that involves creating itermediate dirs, realpath() will fail until after those dirs exist. Try to ensure the same meta file name is used regardless. To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/usr.bin/make/meta.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/make/meta.c diff -u src/usr.bin/make/meta.c:1.7 src/usr.bin/make/meta.c:1.8 --- src/usr.bin/make/meta.c:1.7 Tue Feb 8 05:29:13 2011 +++ src/usr.bin/make/meta.c Sun Feb 13 21:22:41 2011 @@ -169,6 +169,49 @@ } #endif +/* + * when realpath() fails, + * we use this, to clean up ./ and ../ + */ +static void +eat_dots(char *buf, size_t bufsz, int dots) +{ + char *cp; + char *cp2; + const char *eat; + size_t eatlen; + + switch (dots) { + case 1: + eat = "/./"; + eatlen = 2; + break; + case 2: + eat = "/../"; + eatlen = 3; + break; + default: + return; + } + + do { + cp = strstr(buf, eat); + if (cp) { + cp2 = cp + eatlen; + if (dots == 2 && cp > buf) { + do { + cp--; + } while (cp > buf && *cp != '/'); + } + if (*cp == '/') { + strlcpy(cp, cp2, bufsz - (cp - buf)); + } else { + return; /* can't happen? */ + } + } + } while (cp); +} + static char * meta_name(struct GNode *gn, char *mname, size_t mnamelen, const char *dname, @@ -188,6 +231,9 @@ if (!tname) tname = Var_Value(TARGET, gn, &p[i++]); + if (realpath(dname, cwd)) + dname = cwd; + /* * Weed out relative paths from the target file name. * We have to be careful though since if target is a @@ -204,10 +250,23 @@ strlcpy(rp, cp, sizeof(buf) - (rp - buf)); } tname = buf; + } else { + /* + * We likely have a directory which is about to be made. + * We pretend realpath() succeeded, to have a chance + * of generating the same meta file name that we will + * next time through. + */ + if (tname[0] == '/') { + strlcpy(buf, tname, sizeof(buf)); + } else { + snprintf(buf, sizeof(buf), "%s/%s", cwd, tname); + } + eat_dots(buf, sizeof(buf), 1); /* ./ */ + eat_dots(buf, sizeof(buf), 2); /* ../ */ + tname = buf; } } - if (realpath(dname, cwd)) - dname = cwd; /* on some systems dirname may modify its arg */ tp = bmake_strdup(tname); if (strcmp(dname, dirname(tp)) == 0) @@ -425,6 +484,11 @@ fname = meta_name(gn, pbm->meta_fname, sizeof(pbm->meta_fname), dname, tname); +#ifdef DEBUG_META_MODE + if (DEBUG(META)) + fprintf(debug_file, "meta_create: %s\n", fname); +#endif + if ((mf.fp = fopen(fname, "w")) == NULL) err(1, "Could not open meta file '%s'", fname); @@ -733,6 +797,11 @@ meta_name(gn, fname, sizeof(fname), NULL, NULL); +#ifdef DEBUG_META_MODE + if (DEBUG(META)) + fprintf(debug_file, "meta_oodate: %s\n", fname); +#endif + if ((fp = fopen(fname, "r")) != NULL) { static char *buf = NULL; static size_t bufsz;