Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/make meta_oodate(): we should track 'latestdir' on a...
details: https://anonhg.NetBSD.org/src/rev/48711a9a1b1b
branches: trunk
changeset: 759444:48711a9a1b1b
user: sjg <sjg%NetBSD.org@localhost>
date: Thu Dec 09 22:30:16 2010 +0000
description:
meta_oodate(): we should track 'latestdir' on a per process basis.
Also, only consider target out of date if a not-found file is outside
'CWD'. Ignore anything in "/tmp/" or tmpdir.
diffstat:
usr.bin/make/main.c | 43 ++++++----
usr.bin/make/meta.c | 184 ++++++++++++++++++++++++++++++++++++++++--------
usr.bin/make/nonints.h | 3 +-
3 files changed, 181 insertions(+), 49 deletions(-)
diffs (truncated from 362 to 300 lines):
diff -r f6f974c6a4c1 -r 48711a9a1b1b usr.bin/make/main.c
--- a/usr.bin/make/main.c Thu Dec 09 21:27:31 2010 +0000
+++ b/usr.bin/make/main.c Thu Dec 09 22:30:16 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.190 2010/09/13 15:36:57 sjg Exp $ */
+/* $NetBSD: main.c,v 1.191 2010/12/09 22:30:16 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.190 2010/09/13 15:36:57 sjg Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.191 2010/12/09 22:30:16 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
@@ -81,7 +81,7 @@
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: main.c,v 1.190 2010/09/13 15:36:57 sjg Exp $");
+__RCSID("$NetBSD: main.c,v 1.191 2010/12/09 22:30:16 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -1966,6 +1966,27 @@
}
}
+char *
+getTmpdir(void)
+{
+ static char *tmpdir = NULL;
+
+ if (!tmpdir) {
+ struct stat st;
+
+ /*
+ * Honor $TMPDIR but only if it is valid.
+ * Ensure it ends with /.
+ */
+ tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL, 0);
+ if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
+ free(tmpdir);
+ tmpdir = bmake_strdup(_PATH_TMP);
+ }
+ }
+ return tmpdir;
+}
+
/*
* Create and open a temp file using "pattern".
* If "fnamep" is provided set it to a copy of the filename created.
@@ -1980,20 +2001,8 @@
if (!pattern)
pattern = TMPPAT;
-
- if (!tmpdir) {
- struct stat st;
-
- /*
- * Honor $TMPDIR but only if it is valid.
- * Ensure it ends with /.
- */
- tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL, 0);
- if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
- free(tmpdir);
- tmpdir = bmake_strdup(_PATH_TMP);
- }
- }
+ if (!tmpdir)
+ tmpdir = getTmpdir();
if (pattern[0] == '/') {
snprintf(tfile, sizeof(tfile), "%s", pattern);
} else {
diff -r f6f974c6a4c1 -r 48711a9a1b1b usr.bin/make/meta.c
--- a/usr.bin/make/meta.c Thu Dec 09 21:27:31 2010 +0000
+++ b/usr.bin/make/meta.c Thu Dec 09 22:30:16 2010 +0000
@@ -695,15 +695,24 @@
/*
* When running with 'meta' functionality, a target can be out-of-date
* if any of the references in it's meta data file is more recent.
+ * We have to track the latestdir on a per-process basis.
*/
+#define LDIR_VNAME_FMT ".meta.%d.ldir"
+
Boolean
meta_oodate(GNode *gn, Boolean oodate)
{
+ static char *tmpdir = NULL;
+ char ldir_vname[64];
+ char cwd[MAXPATHLEN];
char latestdir[MAXPATHLEN];
char fname[MAXPATHLEN];
char fname1[MAXPATHLEN];
+ char fname2[MAXPATHLEN];
char *p;
char *cp;
+ size_t cwdlen;
+ size_t tmplen = 0;
FILE *fp;
Boolean ignoreOODATE = FALSE;
@@ -718,7 +727,7 @@
*/
Make_DoAllVar(gn);
- if (getcwd(latestdir, sizeof(latestdir)) == NULL)
+ if (getcwd(cwd, sizeof(cwd)) == NULL)
err(1, "Could not get current working directory");
meta_name(gn, fname, sizeof(fname), NULL, NULL);
@@ -727,6 +736,8 @@
static char *buf = NULL;
static size_t bufsz;
int lineno = 0;
+ int lastpid = 0;
+ int pid;
int f = 0;
int x;
LstNode ln;
@@ -736,10 +747,17 @@
bufsz = 8 * BUFSIZ;
buf = bmake_malloc(bufsz);
}
-
+
+ if (!tmpdir) {
+ tmpdir = getTmpdir();
+ tmplen = strlen(tmpdir);
+ }
+
/* we want to track all the .meta we read */
Var_Append(".MAKE.META.FILES", fname, VAR_GLOBAL);
+ cwdlen = strlen(cwd);
+
ln = Lst_First(gn->commands);
while (!oodate && (x = fgetLine(&buf, &bufsz, 0, fp)) > 0) {
lineno++;
@@ -764,28 +782,102 @@
p = buf;
strsep(&p, " ");
if (f) {
+ /*
+ * We are in the 'filemon' output section.
+ * Each record from filemon follows the general form:
+ *
+ * <key> <pid> <data>
+ *
+ * Where:
+ * <key> is a single letter, denoting the syscall.
+ * <pid> is the process that made the syscall.
+ * <data> is the arguments (of interest).
+ */
+ switch(buf[0]) {
+ case '#': /* comment */
+ case 'V': /* version */
+ break;
+ default:
+ /*
+ * We need to track pathnames per-process.
+ *
+ * Each process run by make, starts off in the 'CWD'
+ * recorded in the .meta file, if it chdirs ('C')
+ * elsewhere we need to track that - but only for
+ * that process. If it forks ('F'), we initialize
+ * the child to have the same cwd as its parent.
+ *
+ * We also need to track the 'latestdir' of
+ * interest. This is usually the same as cwd, but
+ * not if a process is reading directories.
+ *
+ * Each time we spot a different process ('pid')
+ * we save the current value of 'latestdir' in a
+ * variable qualified by 'lastpid', and
+ * re-initialize 'latestdir' to any pre-saved
+ * value for the current 'pid' and 'CWD' if none.
+ */
+ pid = atoi(p);
+ if (pid > 0 && pid != lastpid) {
+ char *ldir;
+ char *tp;
+
+ if (lastpid > 0) {
+ /* We need to remember this. */
+ Var_Set(ldir_vname, latestdir, VAR_GLOBAL, 0);
+ }
+ snprintf(ldir_vname, sizeof(ldir_vname), LDIR_VNAME_FMT, pid);
+ lastpid = pid;
+ ldir = Var_Value(ldir_vname, VAR_GLOBAL, &tp);
+ if (ldir) {
+ strlcpy(latestdir, ldir, sizeof(latestdir));
+ if (tp)
+ free(tp);
+ } else
+ strlcpy(latestdir, cwd, sizeof(latestdir));
+ }
+ /* Skip past the pid. */
+ if (strsep(&p, " ") == NULL)
+ continue;
+ break;
+ }
+
/* Process according to record type. */
switch (buf[0]) {
- case 'C':
- /* Skip the pid. */
- if (strsep(&p, " ") == NULL)
- break;
+ case 'X': /* eXit */
+ Var_Delete(ldir_vname, VAR_GLOBAL);
+ lastpid = 0; /* no need to save ldir_vname */
+ break;
+
+ case 'F': /* [v]Fork */
+ {
+ char cldir[64];
+ int child;
+ child = atoi(p);
+ if (child > 0) {
+ snprintf(cldir, sizeof(cldir), LDIR_VNAME_FMT, child);
+ Var_Set(cldir, latestdir, VAR_GLOBAL, 0);
+ }
+ }
+ break;
+
+ case 'C': /* Chdir */
/* Update the latest directory. */
strlcpy(latestdir, p, sizeof(latestdir));
break;
- case 'R':
- case 'E':
- /* Skip the pid. */
- if (strsep(&p, " ") == NULL)
- break;
-
+ case 'R': /* Read */
+ case 'E': /* Exec */
/*
* Check for runtime files that can't
* be part of the dependencies because
* they are _expected_ to change.
*/
+ if (strncmp(p, "/tmp/", 5) == 0 ||
+ strncmp(p, tmpdir, tmplen) == 0)
+ break;
+
if (strncmp(p, "/var/", 5) == 0)
break;
@@ -798,39 +890,69 @@
break;
/*
- * The rest of the record is the
- * file name.
- * Check if it's not an absolute
- * path.
+ * The rest of the record is the file name.
+ * Check if it's not an absolute path.
*/
- if (*p != '/') {
- /* Use the latest path seen. */
- snprintf(fname1, sizeof(fname1), "%s/%s", latestdir, p);
- p = fname1;
- }
+ {
+ char *sdirs[4];
+ char **sdp;
+ int sdx = 0;
+ int found = 0;
+
+ if (*p == '/') {
+ sdirs[sdx++] = p; /* done */
+ } else {
+ if (strcmp(".", p) == 0)
+ continue; /* no point */
+
+ /* Check vs latestdir */
+ snprintf(fname1, sizeof(fname1), "%s/%s", latestdir, p);
+ sdirs[sdx++] = fname1;
+
+ if (strcmp(latestdir, cwd) != 0) {
+ /* Check vs cwd */
+ snprintf(fname2, sizeof(fname2), "%s/%s", cwd, p);
+ sdirs[sdx++] = fname2;
+ }
+ }
+ sdirs[sdx++] = NULL;
- if (stat(p, &fs) == 0) {
- if (!S_ISDIR(fs.st_mode) &&
- fs.st_mtime > gn->mtime) {
+ for (sdp = sdirs; *sdp && !found; sdp++) {
Home |
Main Index |
Thread Index |
Old Index