summaryrefslogtreecommitdiffstats
path: root/sys/dev/filemon/filemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/filemon/filemon.c')
-rw-r--r--sys/dev/filemon/filemon.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/sys/dev/filemon/filemon.c b/sys/dev/filemon/filemon.c
index b302de9..352f682 100644
--- a/sys/dev/filemon/filemon.c
+++ b/sys/dev/filemon/filemon.c
@@ -89,7 +89,7 @@ struct filemon {
TAILQ_ENTRY(filemon) link; /* Link into the in-use list. */
struct sx lock; /* Lock mutex for this filemon. */
struct file *fp; /* Output file pointer. */
- pid_t pid; /* The process ID being monitored. */
+ struct proc *p; /* The process being monitored. */
char fname1[MAXPATHLEN]; /* Temporary filename buffer. */
char fname2[MAXPATHLEN]; /* Temporary filename buffer. */
char msgbufr[1024]; /* Output message buffer. */
@@ -105,26 +105,45 @@ static struct cdev *filemon_dev;
#include "filemon_wrapper.c"
static void
+filemon_comment(struct filemon *filemon)
+{
+ int len;
+ struct timeval now;
+
+ getmicrotime(&now);
+
+ len = snprintf(filemon->msgbufr, sizeof(filemon->msgbufr),
+ "# filemon version %d\n# Target pid %d\n# Start %ju.%06ju\nV %d\n",
+ FILEMON_VERSION, curproc->p_pid, (uintmax_t)now.tv_sec,
+ (uintmax_t)now.tv_usec, FILEMON_VERSION);
+
+ filemon_output(filemon, filemon->msgbufr, len);
+}
+
+static void
filemon_dtr(void *data)
{
struct filemon *filemon = data;
if (filemon != NULL) {
- struct file *fp = filemon->fp;
+ struct file *fp;
- /* Get exclusive write access. */
+ /* Follow same locking order as filemon_pid_check. */
filemon_lock_write();
+ filemon_filemon_lock(filemon);
/* Remove from the in-use list. */
TAILQ_REMOVE(&filemons_inuse, filemon, link);
+ fp = filemon->fp;
filemon->fp = NULL;
- filemon->pid = -1;
+ filemon->p = NULL;
/* Add to the free list. */
TAILQ_INSERT_TAIL(&filemons_free, filemon, link);
/* Give up write access. */
+ filemon_filemon_unlock(filemon);
filemon_unlock_write();
if (fp != NULL)
@@ -143,11 +162,17 @@ filemon_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag __unused,
cap_rights_t rights;
#endif
- devfs_get_cdevpriv((void **) &filemon);
+ if ((error = devfs_get_cdevpriv((void **) &filemon)) != 0)
+ return (error);
+
+ filemon_filemon_lock(filemon);
switch (cmd) {
/* Set the output file descriptor. */
case FILEMON_SET_FD:
+ if (filemon->fp != NULL)
+ fdrop(filemon->fp, td);
+
error = fget_write(td, *(int *)data,
#if __FreeBSD_version >= 900041
cap_rights_init(&rights, CAP_PWRITE),
@@ -163,7 +188,7 @@ filemon_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag __unused,
error = pget(*((pid_t *)data), PGET_CANDEBUG | PGET_NOTWEXIT,
&p);
if (error == 0) {
- filemon->pid = p->p_pid;
+ filemon->p = p;
PROC_UNLOCK(p);
}
break;
@@ -173,6 +198,7 @@ filemon_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag __unused,
break;
}
+ filemon_filemon_unlock(filemon);
return (error);
}
@@ -197,8 +223,6 @@ filemon_open(struct cdev *dev, int oflags __unused, int devtype __unused,
sx_init(&filemon->lock, "filemon");
}
- filemon->pid = curproc->p_pid;
-
devfs_set_cdevpriv(filemon, filemon_dtr);
/* Get exclusive write access. */
OpenPOWER on IntegriCloud