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