1*e56a2ae1Ssjg /* $NetBSD: filemon_dev.c,v 1.9 2022/03/04 23:17:16 sjg Exp $ */
2bea0f8c1Sriastradh
385aee7a6Srillig /*
4bea0f8c1Sriastradh * Copyright (c) 2020 The NetBSD Foundation, Inc.
5bea0f8c1Sriastradh * All rights reserved.
6bea0f8c1Sriastradh *
7bea0f8c1Sriastradh * This code is derived from software contributed to The NetBSD Foundation
8bea0f8c1Sriastradh * by Taylor R. Campbell.
9bea0f8c1Sriastradh *
10bea0f8c1Sriastradh * Redistribution and use in source and binary forms, with or without
11bea0f8c1Sriastradh * modification, are permitted provided that the following conditions
12bea0f8c1Sriastradh * are met:
13bea0f8c1Sriastradh * 1. Redistributions of source code must retain the above copyright
14bea0f8c1Sriastradh * notice, this list of conditions and the following disclaimer.
15bea0f8c1Sriastradh * 2. Redistributions in binary form must reproduce the above copyright
16bea0f8c1Sriastradh * notice, this list of conditions and the following disclaimer in the
17bea0f8c1Sriastradh * documentation and/or other materials provided with the distribution.
18bea0f8c1Sriastradh *
19bea0f8c1Sriastradh * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20bea0f8c1Sriastradh * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21bea0f8c1Sriastradh * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22bea0f8c1Sriastradh * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23bea0f8c1Sriastradh * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24bea0f8c1Sriastradh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25bea0f8c1Sriastradh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26bea0f8c1Sriastradh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27bea0f8c1Sriastradh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28bea0f8c1Sriastradh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29bea0f8c1Sriastradh * POSSIBILITY OF SUCH DAMAGE.
30bea0f8c1Sriastradh */
31bea0f8c1Sriastradh
32bea0f8c1Sriastradh #include "filemon.h"
33bea0f8c1Sriastradh
34bea0f8c1Sriastradh #include <sys/ioctl.h>
35bea0f8c1Sriastradh
36bea0f8c1Sriastradh #include <errno.h>
37bea0f8c1Sriastradh #include <fcntl.h>
38bea0f8c1Sriastradh #include <stdlib.h>
39bea0f8c1Sriastradh #include <unistd.h>
40bea0f8c1Sriastradh
41bea0f8c1Sriastradh #ifdef HAVE_FILEMON_H
42bea0f8c1Sriastradh # include <filemon.h>
43bea0f8c1Sriastradh #endif
44bea0f8c1Sriastradh
45bea0f8c1Sriastradh #ifndef _PATH_FILEMON
46bea0f8c1Sriastradh #define _PATH_FILEMON "/dev/filemon"
47bea0f8c1Sriastradh #endif
48bea0f8c1Sriastradh
49*e56a2ae1Ssjg #ifndef MAKE_ATTR_UNUSED
50*e56a2ae1Ssjg #define MAKE_ATTR_UNUSED __attribute__((__unused__))
51*e56a2ae1Ssjg #endif
52*e56a2ae1Ssjg
53bea0f8c1Sriastradh struct filemon {
54bea0f8c1Sriastradh int fd;
55bea0f8c1Sriastradh };
56bea0f8c1Sriastradh
57bea0f8c1Sriastradh const char *
filemon_path(void)58bea0f8c1Sriastradh filemon_path(void)
59bea0f8c1Sriastradh {
60bea0f8c1Sriastradh
61bea0f8c1Sriastradh return _PATH_FILEMON;
62bea0f8c1Sriastradh }
63bea0f8c1Sriastradh
64bea0f8c1Sriastradh struct filemon *
filemon_open(void)65bea0f8c1Sriastradh filemon_open(void)
66bea0f8c1Sriastradh {
67bea0f8c1Sriastradh struct filemon *F;
68bea0f8c1Sriastradh unsigned i;
69bea0f8c1Sriastradh int error;
70bea0f8c1Sriastradh
71bea0f8c1Sriastradh /* Allocate and zero a struct filemon object. */
72143a3267Srillig F = calloc(1, sizeof *F);
73bea0f8c1Sriastradh if (F == NULL)
74bea0f8c1Sriastradh return NULL;
75bea0f8c1Sriastradh
76bea0f8c1Sriastradh /* Try opening /dev/filemon, up to six times (cargo cult!). */
7707bbd59eSsjg for (i = 0; (F->fd = open(_PATH_FILEMON, O_RDWR|O_CLOEXEC)) == -1; i++) {
78bea0f8c1Sriastradh if (i == 5) {
79bea0f8c1Sriastradh error = errno;
80bea0f8c1Sriastradh goto fail0;
81bea0f8c1Sriastradh }
82bea0f8c1Sriastradh }
83bea0f8c1Sriastradh
84bea0f8c1Sriastradh /* Success! */
85bea0f8c1Sriastradh return F;
86bea0f8c1Sriastradh
87bea0f8c1Sriastradh fail0: free(F);
88bea0f8c1Sriastradh errno = error;
89bea0f8c1Sriastradh return NULL;
90bea0f8c1Sriastradh }
91bea0f8c1Sriastradh
92bea0f8c1Sriastradh int
filemon_setfd(struct filemon * F,int fd)93bea0f8c1Sriastradh filemon_setfd(struct filemon *F, int fd)
94bea0f8c1Sriastradh {
95bea0f8c1Sriastradh
96bea0f8c1Sriastradh /* Point the kernel at this file descriptor. */
97bea0f8c1Sriastradh if (ioctl(F->fd, FILEMON_SET_FD, &fd) == -1)
98bea0f8c1Sriastradh return -1;
99bea0f8c1Sriastradh
100bea0f8c1Sriastradh /* No need for it in userland any more; close it. */
101bea0f8c1Sriastradh (void)close(fd);
102bea0f8c1Sriastradh
103bea0f8c1Sriastradh /* Success! */
104bea0f8c1Sriastradh return 0;
105bea0f8c1Sriastradh }
106bea0f8c1Sriastradh
107bea0f8c1Sriastradh void
filemon_setpid_parent(struct filemon * F MAKE_ATTR_UNUSED,pid_t pid MAKE_ATTR_UNUSED)108*e56a2ae1Ssjg filemon_setpid_parent(struct filemon *F MAKE_ATTR_UNUSED, pid_t pid MAKE_ATTR_UNUSED)
109bea0f8c1Sriastradh {
110bea0f8c1Sriastradh /* Nothing to do! */
111bea0f8c1Sriastradh }
112bea0f8c1Sriastradh
113bea0f8c1Sriastradh int
filemon_setpid_child(const struct filemon * F,pid_t pid)114bea0f8c1Sriastradh filemon_setpid_child(const struct filemon *F, pid_t pid)
115bea0f8c1Sriastradh {
116bea0f8c1Sriastradh
117bea0f8c1Sriastradh /* Just pass it on to the kernel. */
118bea0f8c1Sriastradh return ioctl(F->fd, FILEMON_SET_PID, &pid);
119bea0f8c1Sriastradh }
120bea0f8c1Sriastradh
121bea0f8c1Sriastradh int
filemon_close(struct filemon * F)122bea0f8c1Sriastradh filemon_close(struct filemon *F)
123bea0f8c1Sriastradh {
124bea0f8c1Sriastradh int error = 0;
125bea0f8c1Sriastradh
126bea0f8c1Sriastradh /* Close the filemon device fd. */
127bea0f8c1Sriastradh if (close(F->fd) == -1 && error == 0)
128bea0f8c1Sriastradh error = errno;
129bea0f8c1Sriastradh
130bea0f8c1Sriastradh /* Free the filemon descriptor. */
131bea0f8c1Sriastradh free(F);
132bea0f8c1Sriastradh
133bea0f8c1Sriastradh /* Set errno and return -1 if anything went wrong. */
1344adbce36Srillig if (error != 0) {
135bea0f8c1Sriastradh errno = error;
136bea0f8c1Sriastradh return -1;
137bea0f8c1Sriastradh }
138bea0f8c1Sriastradh
139bea0f8c1Sriastradh /* Success! */
140bea0f8c1Sriastradh return 0;
141bea0f8c1Sriastradh }
142bea0f8c1Sriastradh
143bea0f8c1Sriastradh int
filemon_readfd(const struct filemon * F MAKE_ATTR_UNUSED)144*e56a2ae1Ssjg filemon_readfd(const struct filemon *F MAKE_ATTR_UNUSED)
145bea0f8c1Sriastradh {
146bea0f8c1Sriastradh
147bea0f8c1Sriastradh return -1;
148bea0f8c1Sriastradh }
149bea0f8c1Sriastradh
150bea0f8c1Sriastradh int
filemon_process(struct filemon * F MAKE_ATTR_UNUSED)151*e56a2ae1Ssjg filemon_process(struct filemon *F MAKE_ATTR_UNUSED)
152bea0f8c1Sriastradh {
153bea0f8c1Sriastradh
154bea0f8c1Sriastradh return 0;
155bea0f8c1Sriastradh }
156