diff options
Diffstat (limited to 'sys/dev/filemon/filemon.c')
-rw-r--r-- | sys/dev/filemon/filemon.c | 40 |
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. */ |