1*687000d2Smaya /* $NetBSD: h_tools.c,v 1.5 2018/01/17 00:22:29 maya Exp $ */
29b7401e7Sjmmv
39b7401e7Sjmmv /*
49b7401e7Sjmmv * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
59b7401e7Sjmmv * All rights reserved.
69b7401e7Sjmmv *
79b7401e7Sjmmv * Redistribution and use in source and binary forms, with or without
89b7401e7Sjmmv * modification, are permitted provided that the following conditions
99b7401e7Sjmmv * are met:
109b7401e7Sjmmv * 1. Redistributions of source code must retain the above copyright
119b7401e7Sjmmv * notice, this list of conditions and the following disclaimer.
129b7401e7Sjmmv * 2. Redistributions in binary form must reproduce the above copyright
139b7401e7Sjmmv * notice, this list of conditions and the following disclaimer in the
149b7401e7Sjmmv * documentation and/or other materials provided with the distribution.
159b7401e7Sjmmv *
169b7401e7Sjmmv * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
179b7401e7Sjmmv * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
189b7401e7Sjmmv * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
199b7401e7Sjmmv * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
209b7401e7Sjmmv * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
219b7401e7Sjmmv * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
229b7401e7Sjmmv * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
239b7401e7Sjmmv * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
249b7401e7Sjmmv * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
259b7401e7Sjmmv * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
269b7401e7Sjmmv * POSSIBILITY OF SUCH DAMAGE.
279b7401e7Sjmmv */
289b7401e7Sjmmv
299b7401e7Sjmmv /*
309b7401e7Sjmmv * Helper tools for several tests. These are kept in a single file due
319b7401e7Sjmmv * to the limitations of bsd.prog.mk to build a single program in a
329b7401e7Sjmmv * given directory.
339b7401e7Sjmmv */
349b7401e7Sjmmv
359b7401e7Sjmmv #include <sys/param.h>
369b7401e7Sjmmv #include <sys/types.h>
379b7401e7Sjmmv #include <sys/event.h>
389b7401e7Sjmmv #include <sys/mount.h>
399b7401e7Sjmmv #include <sys/statvfs.h>
409b7401e7Sjmmv #include <sys/socket.h>
419b7401e7Sjmmv #include <sys/time.h>
429b7401e7Sjmmv #include <sys/un.h>
439b7401e7Sjmmv
449b7401e7Sjmmv #include <assert.h>
459b7401e7Sjmmv #include <err.h>
469b7401e7Sjmmv #include <errno.h>
479b7401e7Sjmmv #include <fcntl.h>
48*687000d2Smaya #include <inttypes.h>
499b7401e7Sjmmv #include <stdio.h>
509b7401e7Sjmmv #include <stdlib.h>
519b7401e7Sjmmv #include <string.h>
529b7401e7Sjmmv #include <unistd.h>
539b7401e7Sjmmv
549b7401e7Sjmmv /* --------------------------------------------------------------------- */
559b7401e7Sjmmv
569b7401e7Sjmmv static int getfh_main(int, char **);
579b7401e7Sjmmv static int kqueue_main(int, char **);
589b7401e7Sjmmv static int rename_main(int, char **);
599b7401e7Sjmmv static int sockets_main(int, char **);
609b7401e7Sjmmv static int statvfs_main(int, char **);
619b7401e7Sjmmv
629b7401e7Sjmmv /* --------------------------------------------------------------------- */
639b7401e7Sjmmv
649b7401e7Sjmmv int
getfh_main(int argc,char ** argv)659b7401e7Sjmmv getfh_main(int argc, char **argv)
669b7401e7Sjmmv {
679b7401e7Sjmmv int error;
689b7401e7Sjmmv void *fh;
699b7401e7Sjmmv size_t fh_size;
709b7401e7Sjmmv
719b7401e7Sjmmv if (argc < 2)
729b7401e7Sjmmv return EXIT_FAILURE;
739b7401e7Sjmmv
749b7401e7Sjmmv fh_size = 0;
759b7401e7Sjmmv fh = NULL;
769b7401e7Sjmmv for (;;) {
779b7401e7Sjmmv if (fh_size) {
789b7401e7Sjmmv fh = malloc(fh_size);
799b7401e7Sjmmv if (fh == NULL) {
809b7401e7Sjmmv fprintf(stderr, "out of memory");
819b7401e7Sjmmv return EXIT_FAILURE;
829b7401e7Sjmmv }
839b7401e7Sjmmv }
849b7401e7Sjmmv /*
859b7401e7Sjmmv * The kernel provides the necessary size in fh_size -
869b7401e7Sjmmv * but it may change if someone moves things around,
879b7401e7Sjmmv * so retry untill we have enough memory.
889b7401e7Sjmmv */
899b7401e7Sjmmv error = getfh(argv[1], fh, &fh_size);
909b7401e7Sjmmv if (error == 0) {
919b7401e7Sjmmv break;
929b7401e7Sjmmv } else {
939b7401e7Sjmmv if (fh != NULL)
949b7401e7Sjmmv free(fh);
959b7401e7Sjmmv if (errno != E2BIG) {
962a18cea9Schristos warn("getfh");
979b7401e7Sjmmv return EXIT_FAILURE;
989b7401e7Sjmmv }
999b7401e7Sjmmv }
1009b7401e7Sjmmv }
1019b7401e7Sjmmv
1029b7401e7Sjmmv error = write(STDOUT_FILENO, fh, fh_size);
1039b7401e7Sjmmv if (error == -1) {
1042a18cea9Schristos warn("write");
1059b7401e7Sjmmv return EXIT_FAILURE;
1069b7401e7Sjmmv }
1079b7401e7Sjmmv free(fh);
1089b7401e7Sjmmv
1099b7401e7Sjmmv return 0;
1109b7401e7Sjmmv }
1119b7401e7Sjmmv
1129b7401e7Sjmmv /* --------------------------------------------------------------------- */
1139b7401e7Sjmmv
1149b7401e7Sjmmv int
kqueue_main(int argc,char ** argv)1159b7401e7Sjmmv kqueue_main(int argc, char **argv)
1169b7401e7Sjmmv {
1179b7401e7Sjmmv char *line;
1189b7401e7Sjmmv int i, kq;
1199b7401e7Sjmmv size_t len;
1209b7401e7Sjmmv struct kevent *changes, event;
1219b7401e7Sjmmv
1229b7401e7Sjmmv if (argc < 2)
1239b7401e7Sjmmv return EXIT_FAILURE;
1249b7401e7Sjmmv
1259b7401e7Sjmmv argc--;
1269b7401e7Sjmmv argv++;
1279b7401e7Sjmmv
1282f62f26aSmartin changes = malloc(sizeof(struct kevent) * argc);
1299b7401e7Sjmmv if (changes == NULL)
1309b7401e7Sjmmv errx(EXIT_FAILURE, "not enough memory");
1319b7401e7Sjmmv
1329b7401e7Sjmmv for (i = 0; i < argc; i++) {
1339b7401e7Sjmmv int fd;
1349b7401e7Sjmmv
1359b7401e7Sjmmv fd = open(argv[i], O_RDONLY);
1369b7401e7Sjmmv if (fd == -1)
1379b7401e7Sjmmv err(EXIT_FAILURE, "cannot open %s", argv[i]);
1389b7401e7Sjmmv
1399b7401e7Sjmmv EV_SET(&changes[i], fd, EVFILT_VNODE,
1409b7401e7Sjmmv EV_ADD | EV_ENABLE | EV_ONESHOT,
1419b7401e7Sjmmv NOTE_ATTRIB | NOTE_DELETE | NOTE_EXTEND | NOTE_LINK |
1429b7401e7Sjmmv NOTE_RENAME | NOTE_REVOKE | NOTE_WRITE,
1439b7401e7Sjmmv 0, 0);
1449b7401e7Sjmmv }
1459b7401e7Sjmmv
1469b7401e7Sjmmv kq = kqueue();
1479b7401e7Sjmmv if (kq == -1)
1489b7401e7Sjmmv err(EXIT_FAILURE, "kqueue");
1499b7401e7Sjmmv
1509b7401e7Sjmmv while ((line = fgetln(stdin, &len)) != NULL) {
1519b7401e7Sjmmv int ec, nev;
1529b7401e7Sjmmv struct timespec to;
1539b7401e7Sjmmv
1549b7401e7Sjmmv to.tv_sec = 0;
1559b7401e7Sjmmv to.tv_nsec = 100000;
1569b7401e7Sjmmv
1579b7401e7Sjmmv (void)kevent(kq, changes, argc, &event, 1, &to);
1589b7401e7Sjmmv
1599b7401e7Sjmmv assert(len > 0);
1609b7401e7Sjmmv assert(line[len - 1] == '\n');
1619b7401e7Sjmmv line[len - 1] = '\0';
1629b7401e7Sjmmv ec = system(line);
1639b7401e7Sjmmv if (ec != EXIT_SUCCESS)
1649b7401e7Sjmmv errx(ec, "%s returned %d", line, ec);
1659b7401e7Sjmmv
1669b7401e7Sjmmv do {
1679b7401e7Sjmmv nev = kevent(kq, changes, argc, &event, 1, &to);
1689b7401e7Sjmmv if (nev == -1)
1699b7401e7Sjmmv err(EXIT_FAILURE, "kevent");
1709b7401e7Sjmmv else if (nev > 0) {
1719b7401e7Sjmmv for (i = 0; i < argc; i++)
1729b7401e7Sjmmv if (event.ident == changes[i].ident)
1739b7401e7Sjmmv break;
1749b7401e7Sjmmv
1759b7401e7Sjmmv if (event.fflags & NOTE_ATTRIB)
1769b7401e7Sjmmv printf("%s - NOTE_ATTRIB\n", argv[i]);
1779b7401e7Sjmmv if (event.fflags & NOTE_DELETE)
1789b7401e7Sjmmv printf("%s - NOTE_DELETE\n", argv[i]);
1799b7401e7Sjmmv if (event.fflags & NOTE_EXTEND)
1809b7401e7Sjmmv printf("%s - NOTE_EXTEND\n", argv[i]);
1819b7401e7Sjmmv if (event.fflags & NOTE_LINK)
1829b7401e7Sjmmv printf("%s - NOTE_LINK\n", argv[i]);
1839b7401e7Sjmmv if (event.fflags & NOTE_RENAME)
1849b7401e7Sjmmv printf("%s - NOTE_RENAME\n", argv[i]);
1859b7401e7Sjmmv if (event.fflags & NOTE_REVOKE)
1869b7401e7Sjmmv printf("%s - NOTE_REVOKE\n", argv[i]);
1879b7401e7Sjmmv if (event.fflags & NOTE_WRITE)
1889b7401e7Sjmmv printf("%s - NOTE_WRITE\n", argv[i]);
1899b7401e7Sjmmv }
1909b7401e7Sjmmv } while (nev > 0);
1919b7401e7Sjmmv }
1929b7401e7Sjmmv
1939b7401e7Sjmmv for (i = 0; i < argc; i++)
1949b7401e7Sjmmv close(changes[i].ident);
1959b7401e7Sjmmv free(changes);
1969b7401e7Sjmmv
1979b7401e7Sjmmv return EXIT_SUCCESS;
1989b7401e7Sjmmv }
1999b7401e7Sjmmv
2009b7401e7Sjmmv /* --------------------------------------------------------------------- */
2019b7401e7Sjmmv
2029b7401e7Sjmmv int
rename_main(int argc,char ** argv)2039b7401e7Sjmmv rename_main(int argc, char **argv)
2049b7401e7Sjmmv {
2059b7401e7Sjmmv
2069b7401e7Sjmmv if (argc < 3)
2079b7401e7Sjmmv return EXIT_FAILURE;
2089b7401e7Sjmmv
2099b7401e7Sjmmv if (rename(argv[1], argv[2]) == -1) {
2102a18cea9Schristos warn("rename");
2119b7401e7Sjmmv return EXIT_FAILURE;
2129b7401e7Sjmmv }
2139b7401e7Sjmmv
2149b7401e7Sjmmv return EXIT_SUCCESS;
2159b7401e7Sjmmv }
2169b7401e7Sjmmv
2179b7401e7Sjmmv /* --------------------------------------------------------------------- */
2189b7401e7Sjmmv
2199b7401e7Sjmmv int
sockets_main(int argc,char ** argv)2209b7401e7Sjmmv sockets_main(int argc, char **argv)
2219b7401e7Sjmmv {
2229b7401e7Sjmmv int error, fd;
2239b7401e7Sjmmv struct sockaddr_un addr;
2249b7401e7Sjmmv
2259b7401e7Sjmmv if (argc < 2)
2269b7401e7Sjmmv return EXIT_FAILURE;
2279b7401e7Sjmmv
2289b7401e7Sjmmv fd = socket(PF_LOCAL, SOCK_STREAM, 0);
2299b7401e7Sjmmv if (fd == -1) {
2302a18cea9Schristos warn("socket");
2319b7401e7Sjmmv return EXIT_FAILURE;
2329b7401e7Sjmmv }
2339b7401e7Sjmmv
234*687000d2Smaya memset(&addr, 0, sizeof(addr));
2359b7401e7Sjmmv (void)strlcpy(addr.sun_path, argv[1], sizeof(addr.sun_path));
2369b7401e7Sjmmv addr.sun_family = PF_UNIX;
237*687000d2Smaya error = bind(fd, (struct sockaddr *)&addr, SUN_LEN(&addr));
2389b7401e7Sjmmv if (error == -1) {
2392a18cea9Schristos warn("connect");
240*687000d2Smaya (void)close(fd);
2419b7401e7Sjmmv return EXIT_FAILURE;
2429b7401e7Sjmmv }
2439b7401e7Sjmmv
2449b7401e7Sjmmv close(fd);
2459b7401e7Sjmmv
2469b7401e7Sjmmv return EXIT_SUCCESS;
2479b7401e7Sjmmv }
2489b7401e7Sjmmv
2499b7401e7Sjmmv /* --------------------------------------------------------------------- */
2509b7401e7Sjmmv
2519b7401e7Sjmmv int
statvfs_main(int argc,char ** argv)2529b7401e7Sjmmv statvfs_main(int argc, char **argv)
2539b7401e7Sjmmv {
2549b7401e7Sjmmv int error;
2559b7401e7Sjmmv struct statvfs buf;
2569b7401e7Sjmmv
2579b7401e7Sjmmv if (argc < 2)
2589b7401e7Sjmmv return EXIT_FAILURE;
2599b7401e7Sjmmv
2609b7401e7Sjmmv error = statvfs(argv[1], &buf);
2619b7401e7Sjmmv if (error != 0) {
2622a18cea9Schristos warn("statvfs");
2639b7401e7Sjmmv return EXIT_FAILURE;
2649b7401e7Sjmmv }
2659b7401e7Sjmmv
2669b7401e7Sjmmv (void)printf("f_bsize=%lu\n", buf.f_bsize);
2679b7401e7Sjmmv (void)printf("f_blocks=%" PRId64 "\n", buf.f_blocks);
2689b7401e7Sjmmv (void)printf("f_bfree=%" PRId64 "\n", buf.f_bfree);
2699b7401e7Sjmmv (void)printf("f_files=%" PRId64 "\n", buf.f_files);
2709b7401e7Sjmmv
2719b7401e7Sjmmv return EXIT_SUCCESS;
2729b7401e7Sjmmv }
2739b7401e7Sjmmv
2749b7401e7Sjmmv /* --------------------------------------------------------------------- */
2759b7401e7Sjmmv
2769b7401e7Sjmmv int
main(int argc,char ** argv)2779b7401e7Sjmmv main(int argc, char **argv)
2789b7401e7Sjmmv {
2799b7401e7Sjmmv int error;
2809b7401e7Sjmmv
2819b7401e7Sjmmv if (argc < 2)
2829b7401e7Sjmmv return EXIT_FAILURE;
2839b7401e7Sjmmv
2849b7401e7Sjmmv argc -= 1;
2859b7401e7Sjmmv argv += 1;
2869b7401e7Sjmmv
2879b7401e7Sjmmv if (strcmp(argv[0], "getfh") == 0)
2889b7401e7Sjmmv error = getfh_main(argc, argv);
2899b7401e7Sjmmv else if (strcmp(argv[0], "kqueue") == 0)
2909b7401e7Sjmmv error = kqueue_main(argc, argv);
2919b7401e7Sjmmv else if (strcmp(argv[0], "rename") == 0)
2929b7401e7Sjmmv error = rename_main(argc, argv);
2939b7401e7Sjmmv else if (strcmp(argv[0], "sockets") == 0)
2949b7401e7Sjmmv error = sockets_main(argc, argv);
2959b7401e7Sjmmv else if (strcmp(argv[0], "statvfs") == 0)
2969b7401e7Sjmmv error = statvfs_main(argc, argv);
2979b7401e7Sjmmv else
2989b7401e7Sjmmv error = EXIT_FAILURE;
2999b7401e7Sjmmv
3009b7401e7Sjmmv return error;
3019b7401e7Sjmmv }
302