summaryrefslogtreecommitdiff
path: root/vpath.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>1993-02-08 22:50:00 +0000
committerRoland McGrath <roland@redhat.com>1993-02-08 22:50:00 +0000
commitbede66b7096a93147dda7058a4ab6c1e87e14476 (patch)
tree4e5a2e26e66712a646f8e27559be4685084900c0 /vpath.c
parentcc1433e8085cdae7e5e337f9239045a14ee409e8 (diff)
downloadgunmake-bede66b7096a93147dda7058a4ab6c1e87e14476.tar.gz
Formerly vpath.c.~9~
Diffstat (limited to 'vpath.c')
-rw-r--r--vpath.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/vpath.c b/vpath.c
index 730f989..e58cf07 100644
--- a/vpath.c
+++ b/vpath.c
@@ -246,13 +246,15 @@ construct_vpath_list (pattern, dirpath)
}
/* Search the VPATH list whose pattern matches *FILE for a directory
- where the name pointed to by FILE exists. If it is found, the pointer
- in FILE is set to the newly malloc'd name of the existing file and
- we return 1. Otherwise we return 0. */
+ where the name pointed to by FILE exists. If it is found, we set *FILE to
+ the newly malloc'd name of the existing file, *MTIME_PTR (if MTIME_PTR is
+ not NULL) to its modtime (or zero if no stat call was done), and return 1.
+ Otherwise we return 0. */
int
-vpath_search (file)
+vpath_search (file, mtime_ptr)
char **file;
+ time_t *mtime_ptr;
{
register struct vpath *v;
@@ -264,11 +266,11 @@ vpath_search (file)
for (v = vpaths; v != 0; v = v->next)
if (pattern_matches (v->pattern, v->percent, *file))
- if (selective_vpath_search (v, file))
+ if (selective_vpath_search (v, file, mtime_ptr))
return 1;
if (general_vpath != 0
- && selective_vpath_search (general_vpath, file))
+ && selective_vpath_search (general_vpath, file, mtime_ptr))
return 1;
return 0;
@@ -276,14 +278,16 @@ vpath_search (file)
/* Search the given VPATH list for a directory where the name pointed
- to by FILE exists. If it is found, the pointer in FILE
- is set to the newly malloc'd name of the existing file and we return 1.
+ to by FILE exists. If it is found, we set *FILE to the newly malloc'd
+ name of the existing file, *MTIME_PTR (if MTIME_PTR is not NULL) to
+ its modtime (or zero if no stat call was done), and we return 1.
Otherwise we return 0. */
static int
-selective_vpath_search (path, file)
+selective_vpath_search (path, file, mtime_ptr)
struct vpath *path;
char **file;
+ time_t *mtime_ptr;
{
int not_target;
char *name, *n;
@@ -323,6 +327,8 @@ selective_vpath_search (path, file)
/* Try each VPATH entry. */
for (i = 0; vpath[i] != 0; ++i)
{
+ int exists_in_cache = 0;
+
n = name;
/* Put the next VPATH entry into NAME at N and increment N past it. */
@@ -360,20 +366,38 @@ selective_vpath_search (path, file)
/* We know the directory is in the hash table now because either
construct_vpath_list or the code just above put it there.
Does the file we seek exist in it? */
- exists = dir_file_exists_p (name, filename);
+ exists_in_cache = exists = dir_file_exists_p (name, filename);
}
if (exists)
{
- /* We have found a file.
- Store the name we found into *FILE for the caller. */
+ /* The file is in the directory cache.
+ Now check that it actually exists in the filesystem.
+ The cache may be out of date. When vpath thinks a file
+ exists, but stat fails for it, confusion results in the
+ higher levels. */
+
+ struct stat st;
/* Put the slash back in NAME. */
*n = '/';
- *file = savestring (name, (n + 1 - name) + flen);
+ if (!exists_in_cache /* Makefile-mentioned file need not exist. */
+ || stat (name, &st) == 0) /* Does it really exist? */
+ {
+ /* We have found a file.
+ Store the name we found into *FILE for the caller. */
- return 1;
+ *file = savestring (name, (n + 1 - name) + flen);
+
+ if (mtime_ptr != 0)
+ /* Store the modtime into *MTIME_PTR for the caller.
+ If we have had no need to stat the file here,
+ we record a zero modtime to indicate this. */
+ *mtime_ptr = exists_in_cache ? st.st_mtime : (time_t) 0;
+
+ return 1;
+ }
}
}