summaryrefslogtreecommitdiffstats
path: root/usr.bin/make/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/make/dir.c')
-rw-r--r--usr.bin/make/dir.c103
1 files changed, 83 insertions, 20 deletions
diff --git a/usr.bin/make/dir.c b/usr.bin/make/dir.c
index c66b2bf..7cee3d4 100644
--- a/usr.bin/make/dir.c
+++ b/usr.bin/make/dir.c
@@ -61,6 +61,10 @@ __FBSDID("$FreeBSD$");
* If it exists, the entire path is returned.
* Otherwise NULL is returned.
*
+ * Dir_FindHereOrAbove Search for a path in the current directory and
+ * then all the directories above it in turn until
+ * the path is found or we reach the root ("/").
+ *
* Dir_MTime Return the modification time of a node. The file
* is searched for along the default search path.
* The path and mtime fields of the node are filled in.
@@ -83,14 +87,13 @@ __FBSDID("$FreeBSD$");
* Dir_PrintDirectories Print stats about the directory cache.
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/stat.h>
#include <dirent.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
#include "arch.h"
#include "dir.h"
@@ -98,7 +101,6 @@ __FBSDID("$FreeBSD$");
#include "GNode.h"
#include "hash.h"
#include "lst.h"
-#include "make.h"
#include "str.h"
#include "targ.h"
#include "util.h"
@@ -832,21 +834,6 @@ Path_FindFile(char *name, struct Path *path)
* When searching for $(FILE), we will find it in $(INSTALLDIR)
* b/c we added it here. This is not good...
*/
-#ifdef notdef
- cp[-1] = '\0';
- Path_AddDir(path, name);
- cp[-1] = '/';
-
- bigmisses += 1;
- pe = TAILQ_LAST(path, Path);
- if (pe == NULL)
- return (NULL);
-
- if (Hash_FindEntry(&pe->dir->files, cp) != NULL) {
- return (estrdup(name));
-
- return (NULL);
-#else /* !notdef */
DEBUGF(DIR, ("Looking for \"%s\"...", name));
bigmisses += 1;
@@ -864,7 +851,83 @@ Path_FindFile(char *name, struct Path *path)
DEBUGF(DIR, ("failed. Returning NULL\n"));
return (NULL);
}
-#endif /* notdef */
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_FindHereOrAbove --
+ * search for a path starting at a given directory and then working
+ * our way up towards the root.
+ *
+ * Input:
+ * here starting directory
+ * search_path the path we are looking for
+ * result the result of a successful search is placed here
+ * rlen the length of the result buffer
+ * (typically MAXPATHLEN + 1)
+ *
+ * Results:
+ * 0 on failure, 1 on success [in which case the found path is put
+ * in the result buffer].
+ *
+ * Side Effects:
+ *-----------------------------------------------------------------------
+ */
+int
+Dir_FindHereOrAbove(char *here, char *search_path, char *result, int rlen)
+{
+ struct stat st;
+ char dirbase[MAXPATHLEN + 1], *db_end;
+ char try[MAXPATHLEN + 1], *try_end;
+
+ /* copy out our starting point */
+ snprintf(dirbase, sizeof(dirbase), "%s", here);
+ db_end = dirbase + strlen(dirbase);
+
+ /* loop until we determine a result */
+ while (1) {
+ /* try and stat(2) it ... */
+ snprintf(try, sizeof(try), "%s/%s", dirbase, search_path);
+ if (stat(try, &st) != -1) {
+ /*
+ * Success! If we found a file, chop off
+ * the filename so we return a directory.
+ */
+ if ((st.st_mode & S_IFMT) != S_IFDIR) {
+ try_end = try + strlen(try);
+ while (try_end > try && *try_end != '/')
+ try_end--;
+ if (try_end > try)
+ *try_end = 0; /* chop! */
+ }
+
+ /*
+ * Done!
+ */
+ snprintf(result, rlen, "%s", try);
+ return(1);
+ }
+
+ /*
+ * Nope, we didn't find it. If we used up dirbase we've
+ * reached the root and failed.
+ */
+ if (db_end == dirbase)
+ break; /* Failed! */
+
+ /*
+ * truncate dirbase from the end to move up a dir
+ */
+ while (db_end > dirbase && *db_end != '/')
+ db_end--;
+ *db_end = 0; /* chop! */
+
+ } /* while (1) */
+
+ /*
+ * We failed...
+ */
+ return(0);
}
/*-
@@ -878,7 +941,7 @@ Path_FindFile(char *name, struct Path *path)
*
* Side Effects:
* The modification time is placed in the node's mtime slot.
- * If the node didn't have a path entry before, and Dir_FindFile
+ * If the node didn't have a path entry before, and Path_FindFile
* found one for it, the full name is placed in the path slot.
*-----------------------------------------------------------------------
*/
OpenPOWER on IntegriCloud