xref: /netbsd-src/usr.bin/make/filemon/filemon_dev.c (revision e56a2ae17f3b6ad3437c91c08c4a5d0ad7021dcc)
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