summaryrefslogtreecommitdiff
path: root/meta.c
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2020-05-20 19:34:48 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2020-05-20 19:34:48 +0000
commitb897d72a5adf5cfad8c79f90e155bae99bdde48c (patch)
tree0e06330d11aebdabb067f53e790c38664297ec4e /meta.c
parent14ade6f03183ea07683d6775a858bfd51fac9990 (diff)
Notes
Diffstat (limited to 'meta.c')
-rw-r--r--meta.c192
1 files changed, 145 insertions, 47 deletions
diff --git a/meta.c b/meta.c
index a852f3f5aa42..ca40c6dd8224 100644
--- a/meta.c
+++ b/meta.c
@@ -1,4 +1,4 @@
-/* $NetBSD: meta.c,v 1.70 2018/02/13 19:37:30 sjg Exp $ */
+/* $NetBSD: meta.c,v 1.81 2020/04/03 03:32:28 sjg Exp $ */
/*
* Implement 'meta' mode.
@@ -36,7 +36,6 @@
# include "config.h"
#endif
#include <sys/stat.h>
-#include <sys/ioctl.h>
#ifdef HAVE_LIBGEN_H
#include <libgen.h>
#elif !defined(HAVE_DIRNAME)
@@ -50,11 +49,8 @@ char * dirname(char *);
#include "make.h"
#include "job.h"
-#ifdef HAVE_FILEMON_H
-# include <filemon.h>
-#endif
-#if !defined(USE_FILEMON) && defined(FILEMON_SET_FD)
-# define USE_FILEMON
+#ifdef USE_FILEMON
+#include "filemon/filemon.h"
#endif
static BuildMon Mybm; /* for compat */
@@ -121,30 +117,24 @@ extern char **environ;
* the benefits are more limited.
*/
#ifdef USE_FILEMON
-# ifndef _PATH_FILEMON
-# define _PATH_FILEMON "/dev/filemon"
-# endif
/*
* Open the filemon device.
*/
static void
-filemon_open(BuildMon *pbm)
+meta_open_filemon(BuildMon *pbm)
{
- int retry;
-
- pbm->mon_fd = pbm->filemon_fd = -1;
- if (!useFilemon)
- return;
+ int dupfd;
- for (retry = 5; retry >= 0; retry--) {
- if ((pbm->filemon_fd = open(_PATH_FILEMON, O_RDWR)) >= 0)
- break;
- }
+ pbm->mon_fd = -1;
+ pbm->filemon = NULL;
+ if (!useFilemon || !pbm->mfp)
+ return;
- if (pbm->filemon_fd < 0) {
+ pbm->filemon = filemon_open();
+ if (pbm->filemon == NULL) {
useFilemon = FALSE;
- warn("Could not open %s", _PATH_FILEMON);
+ warn("Could not open filemon %s", filemon_path());
return;
}
@@ -155,12 +145,15 @@ filemon_open(BuildMon *pbm)
* We only care about the descriptor.
*/
pbm->mon_fd = mkTempFile("filemon.XXXXXX", NULL);
- if (ioctl(pbm->filemon_fd, FILEMON_SET_FD, &pbm->mon_fd) < 0) {
+ if ((dupfd = dup(pbm->mon_fd)) == -1) {
+ err(1, "Could not dup filemon output!");
+ }
+ (void)fcntl(dupfd, F_SETFD, FD_CLOEXEC);
+ if (filemon_setfd(pbm->filemon, dupfd) == -1) {
err(1, "Could not set filemon file descriptor!");
}
/* we don't need these once we exec */
(void)fcntl(pbm->mon_fd, F_SETFD, FD_CLOEXEC);
- (void)fcntl(pbm->filemon_fd, F_SETFD, FD_CLOEXEC);
}
/*
@@ -473,7 +466,7 @@ meta_create(BuildMon *pbm, GNode *gn)
const char *tname;
char *fname;
const char *cp;
- char *p[4]; /* >= possible uses */
+ char *p[5]; /* >= possible uses */
int i;
mf.fp = NULL;
@@ -528,7 +521,10 @@ meta_create(BuildMon *pbm, GNode *gn)
fprintf(mf.fp, "CWD %s\n", getcwd(buf, sizeof(buf)));
fprintf(mf.fp, "TARGET %s\n", tname);
-
+ cp = Var_Value(".OODATE", gn, &p[i++]);
+ if (cp && *cp) {
+ fprintf(mf.fp, "OODATE %s\n", cp);
+ }
if (metaEnv) {
for (ptr = environ; *ptr != NULL; ptr++)
fprintf(mf.fp, "ENV %s\n", *ptr);
@@ -574,7 +570,7 @@ meta_init(void)
{
#ifdef USE_FILEMON
/* this allows makefiles to test if we have filemon support */
- Var_Set(".MAKE.PATH_FILEMON", _PATH_FILEMON, VAR_GLOBAL, 0);
+ Var_Set(".MAKE.PATH_FILEMON", filemon_path(), VAR_GLOBAL, 0);
#endif
}
@@ -684,9 +680,10 @@ meta_job_start(Job *job, GNode *gn)
#endif
#ifdef USE_FILEMON
if (pbm->mfp != NULL && useFilemon) {
- filemon_open(pbm);
+ meta_open_filemon(pbm);
} else {
- pbm->mon_fd = pbm->filemon_fd = -1;
+ pbm->mon_fd = -1;
+ pbm->filemon = NULL;
}
#endif
}
@@ -708,11 +705,11 @@ meta_job_child(Job *job)
}
if (pbm->mfp != NULL) {
close(fileno(pbm->mfp));
- if (useFilemon) {
+ if (useFilemon && pbm->filemon) {
pid_t pid;
pid = getpid();
- if (ioctl(pbm->filemon_fd, FILEMON_SET_PID, &pid) < 0) {
+ if (filemon_setpid_child(pbm->filemon, pid) == -1) {
err(1, "Could not set filemon pid!");
}
}
@@ -721,6 +718,59 @@ meta_job_child(Job *job)
}
void
+meta_job_parent(Job *job, pid_t pid)
+{
+#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
+ BuildMon *pbm;
+
+ if (job != NULL) {
+ pbm = &job->bm;
+ } else {
+ pbm = &Mybm;
+ }
+ if (useFilemon && pbm->filemon) {
+ filemon_setpid_parent(pbm->filemon, pid);
+ }
+#endif
+}
+
+int
+meta_job_fd(Job *job)
+{
+#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
+ BuildMon *pbm;
+
+ if (job != NULL) {
+ pbm = &job->bm;
+ } else {
+ pbm = &Mybm;
+ }
+ if (useFilemon && pbm->filemon) {
+ return filemon_readfd(pbm->filemon);
+ }
+#endif
+ return -1;
+}
+
+int
+meta_job_event(Job *job)
+{
+#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
+ BuildMon *pbm;
+
+ if (job != NULL) {
+ pbm = &job->bm;
+ } else {
+ pbm = &Mybm;
+ }
+ if (useFilemon && pbm->filemon) {
+ return filemon_process(pbm->filemon);
+ }
+#endif
+ return 0;
+}
+
+void
meta_job_error(Job *job, GNode *gn, int flags, int status)
{
char cwd[MAXPATHLEN];
@@ -798,13 +848,16 @@ meta_cmd_finish(void *pbmp)
pbm = &Mybm;
#ifdef USE_FILEMON
- if (pbm->filemon_fd >= 0) {
- if (close(pbm->filemon_fd) < 0)
+ if (pbm->filemon) {
+ while (filemon_process(pbm->filemon) > 0)
+ continue;
+ if (filemon_close(pbm->filemon) == -1)
error = errno;
x = filemon_read(pbm->mfp, pbm->mon_fd);
if (error == 0 && x != 0)
error = x;
- pbm->filemon_fd = pbm->mon_fd = -1;
+ pbm->mon_fd = -1;
+ pbm->filemon = NULL;
} else
#endif
fprintf(pbm->mfp, "\n"); /* ensure end with newline */
@@ -1509,7 +1562,8 @@ meta_oodate(GNode *gn, Boolean oodate)
if (buf[x - 1] == '\n')
buf[x - 1] = '\0';
}
- if (!hasOODATE &&
+ if (p &&
+ !hasOODATE &&
!(gn->type & OP_NOMETA_CMP) &&
strcmp(p, cmd) != 0) {
if (DEBUG(META))
@@ -1530,6 +1584,7 @@ meta_oodate(GNode *gn, Boolean oodate)
fprintf(debug_file, "%s: %d: there are extra build commands now that weren't in the meta data file\n", fname, lineno);
oodate = TRUE;
}
+ CHECK_VALID_META(p);
if (strcmp(p, cwd) != 0) {
if (DEBUG(META))
fprintf(debug_file, "%s: %d: the current working directory has changed from '%s' to '%s'\n", fname, lineno, p, curdir);
@@ -1603,9 +1658,10 @@ meta_compat_start(void)
BuildMon *pbm = &Mybm;
if (pbm->mfp != NULL && useFilemon) {
- filemon_open(pbm);
+ meta_open_filemon(pbm);
} else {
- pbm->mon_fd = pbm->filemon_fd = -1;
+ pbm->mon_fd = -1;
+ pbm->filemon = NULL;
}
#endif
if (pipe(childPipe) < 0)
@@ -1627,19 +1683,61 @@ meta_compat_child(void)
}
void
-meta_compat_parent(void)
+meta_compat_parent(pid_t child)
{
- FILE *fp;
- char buf[BUFSIZ];
-
+ int outfd, metafd, maxfd, nfds;
+ char buf[BUFSIZ+1];
+ fd_set readfds;
+
+ meta_job_parent(NULL, child);
close(childPipe[1]); /* child side */
- fp = fdopen(childPipe[0], "r");
- while (fgets(buf, sizeof(buf), fp)) {
- meta_job_output(NULL, buf, "");
- printf("%s", buf);
- fflush(stdout);
+ outfd = childPipe[0];
+#ifdef USE_FILEMON
+ metafd = Mybm.filemon ? filemon_readfd(Mybm.filemon) : -1;
+#else
+ metafd = -1;
+#endif
+ maxfd = -1;
+ if (outfd > maxfd)
+ maxfd = outfd;
+ if (metafd > maxfd)
+ maxfd = metafd;
+
+ while (outfd != -1 || metafd != -1) {
+ FD_ZERO(&readfds);
+ if (outfd != -1) {
+ FD_SET(outfd, &readfds);
+ }
+ if (metafd != -1) {
+ FD_SET(metafd, &readfds);
+ }
+ nfds = select(maxfd + 1, &readfds, NULL, NULL, NULL);
+ if (nfds == -1) {
+ if (errno == EINTR)
+ continue;
+ err(1, "select");
+ }
+
+ if (outfd != -1 && FD_ISSET(outfd, &readfds)) do {
+ /* XXX this is not line-buffered */
+ ssize_t nread = read(outfd, buf, sizeof(buf) - 1);
+ if (nread == -1)
+ err(1, "read");
+ if (nread == 0) {
+ close(outfd);
+ outfd = -1;
+ break;
+ }
+ fwrite(buf, 1, (size_t)nread, stdout);
+ fflush(stdout);
+ buf[nread] = '\0';
+ meta_job_output(NULL, buf, "");
+ } while (0);
+ if (metafd != -1 && FD_ISSET(metafd, &readfds)) {
+ if (meta_job_event(NULL) <= 0)
+ metafd = -1;
+ }
}
- fclose(fp);
}
#endif /* USE_META */