11.5Smaya/* $NetBSD: h_tools.c,v 1.5 2018/01/17 00:22:29 maya Exp $ */ 21.1Sjmmv 31.1Sjmmv/* 41.1Sjmmv * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc. 51.1Sjmmv * All rights reserved. 61.1Sjmmv * 71.1Sjmmv * Redistribution and use in source and binary forms, with or without 81.1Sjmmv * modification, are permitted provided that the following conditions 91.1Sjmmv * are met: 101.1Sjmmv * 1. Redistributions of source code must retain the above copyright 111.1Sjmmv * notice, this list of conditions and the following disclaimer. 121.1Sjmmv * 2. Redistributions in binary form must reproduce the above copyright 131.1Sjmmv * notice, this list of conditions and the following disclaimer in the 141.1Sjmmv * documentation and/or other materials provided with the distribution. 151.1Sjmmv * 161.1Sjmmv * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 171.1Sjmmv * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 181.1Sjmmv * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 191.1Sjmmv * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 201.1Sjmmv * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 211.1Sjmmv * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 221.1Sjmmv * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 231.1Sjmmv * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 241.1Sjmmv * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 251.1Sjmmv * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 261.1Sjmmv * POSSIBILITY OF SUCH DAMAGE. 271.1Sjmmv */ 281.1Sjmmv 291.1Sjmmv/* 301.1Sjmmv * Helper tools for several tests. These are kept in a single file due 311.1Sjmmv * to the limitations of bsd.prog.mk to build a single program in a 321.1Sjmmv * given directory. 331.1Sjmmv */ 341.1Sjmmv 351.1Sjmmv#include <sys/param.h> 361.1Sjmmv#include <sys/types.h> 371.1Sjmmv#include <sys/event.h> 381.1Sjmmv#include <sys/mount.h> 391.1Sjmmv#include <sys/statvfs.h> 401.1Sjmmv#include <sys/socket.h> 411.1Sjmmv#include <sys/time.h> 421.1Sjmmv#include <sys/un.h> 431.1Sjmmv 441.1Sjmmv#include <assert.h> 451.1Sjmmv#include <err.h> 461.1Sjmmv#include <errno.h> 471.1Sjmmv#include <fcntl.h> 481.5Smaya#include <inttypes.h> 491.1Sjmmv#include <stdio.h> 501.1Sjmmv#include <stdlib.h> 511.1Sjmmv#include <string.h> 521.1Sjmmv#include <unistd.h> 531.1Sjmmv 541.1Sjmmv/* --------------------------------------------------------------------- */ 551.1Sjmmv 561.1Sjmmvstatic int getfh_main(int, char **); 571.1Sjmmvstatic int kqueue_main(int, char **); 581.1Sjmmvstatic int rename_main(int, char **); 591.1Sjmmvstatic int sockets_main(int, char **); 601.1Sjmmvstatic int statvfs_main(int, char **); 611.1Sjmmv 621.1Sjmmv/* --------------------------------------------------------------------- */ 631.1Sjmmv 641.1Sjmmvint 651.1Sjmmvgetfh_main(int argc, char **argv) 661.1Sjmmv{ 671.1Sjmmv int error; 681.1Sjmmv void *fh; 691.1Sjmmv size_t fh_size; 701.1Sjmmv 711.1Sjmmv if (argc < 2) 721.1Sjmmv return EXIT_FAILURE; 731.1Sjmmv 741.1Sjmmv fh_size = 0; 751.1Sjmmv fh = NULL; 761.1Sjmmv for (;;) { 771.1Sjmmv if (fh_size) { 781.1Sjmmv fh = malloc(fh_size); 791.1Sjmmv if (fh == NULL) { 801.1Sjmmv fprintf(stderr, "out of memory"); 811.1Sjmmv return EXIT_FAILURE; 821.1Sjmmv } 831.1Sjmmv } 841.1Sjmmv /* 851.1Sjmmv * The kernel provides the necessary size in fh_size - 861.1Sjmmv * but it may change if someone moves things around, 871.1Sjmmv * so retry untill we have enough memory. 881.1Sjmmv */ 891.1Sjmmv error = getfh(argv[1], fh, &fh_size); 901.1Sjmmv if (error == 0) { 911.1Sjmmv break; 921.1Sjmmv } else { 931.1Sjmmv if (fh != NULL) 941.1Sjmmv free(fh); 951.1Sjmmv if (errno != E2BIG) { 961.4Schristos warn("getfh"); 971.1Sjmmv return EXIT_FAILURE; 981.1Sjmmv } 991.1Sjmmv } 1001.1Sjmmv } 1011.1Sjmmv 1021.1Sjmmv error = write(STDOUT_FILENO, fh, fh_size); 1031.1Sjmmv if (error == -1) { 1041.4Schristos warn("write"); 1051.1Sjmmv return EXIT_FAILURE; 1061.1Sjmmv } 1071.1Sjmmv free(fh); 1081.1Sjmmv 1091.1Sjmmv return 0; 1101.1Sjmmv} 1111.1Sjmmv 1121.1Sjmmv/* --------------------------------------------------------------------- */ 1131.1Sjmmv 1141.1Sjmmvint 1151.1Sjmmvkqueue_main(int argc, char **argv) 1161.1Sjmmv{ 1171.1Sjmmv char *line; 1181.1Sjmmv int i, kq; 1191.1Sjmmv size_t len; 1201.1Sjmmv struct kevent *changes, event; 1211.1Sjmmv 1221.1Sjmmv if (argc < 2) 1231.1Sjmmv return EXIT_FAILURE; 1241.1Sjmmv 1251.1Sjmmv argc--; 1261.1Sjmmv argv++; 1271.1Sjmmv 1281.3Smartin changes = malloc(sizeof(struct kevent) * argc); 1291.1Sjmmv if (changes == NULL) 1301.1Sjmmv errx(EXIT_FAILURE, "not enough memory"); 1311.1Sjmmv 1321.1Sjmmv for (i = 0; i < argc; i++) { 1331.1Sjmmv int fd; 1341.1Sjmmv 1351.1Sjmmv fd = open(argv[i], O_RDONLY); 1361.1Sjmmv if (fd == -1) 1371.1Sjmmv err(EXIT_FAILURE, "cannot open %s", argv[i]); 1381.1Sjmmv 1391.1Sjmmv EV_SET(&changes[i], fd, EVFILT_VNODE, 1401.1Sjmmv EV_ADD | EV_ENABLE | EV_ONESHOT, 1411.1Sjmmv NOTE_ATTRIB | NOTE_DELETE | NOTE_EXTEND | NOTE_LINK | 1421.1Sjmmv NOTE_RENAME | NOTE_REVOKE | NOTE_WRITE, 1431.1Sjmmv 0, 0); 1441.1Sjmmv } 1451.1Sjmmv 1461.1Sjmmv kq = kqueue(); 1471.1Sjmmv if (kq == -1) 1481.1Sjmmv err(EXIT_FAILURE, "kqueue"); 1491.1Sjmmv 1501.1Sjmmv while ((line = fgetln(stdin, &len)) != NULL) { 1511.1Sjmmv int ec, nev; 1521.1Sjmmv struct timespec to; 1531.1Sjmmv 1541.1Sjmmv to.tv_sec = 0; 1551.1Sjmmv to.tv_nsec = 100000; 1561.1Sjmmv 1571.1Sjmmv (void)kevent(kq, changes, argc, &event, 1, &to); 1581.1Sjmmv 1591.1Sjmmv assert(len > 0); 1601.1Sjmmv assert(line[len - 1] == '\n'); 1611.1Sjmmv line[len - 1] = '\0'; 1621.1Sjmmv ec = system(line); 1631.1Sjmmv if (ec != EXIT_SUCCESS) 1641.1Sjmmv errx(ec, "%s returned %d", line, ec); 1651.1Sjmmv 1661.1Sjmmv do { 1671.1Sjmmv nev = kevent(kq, changes, argc, &event, 1, &to); 1681.1Sjmmv if (nev == -1) 1691.1Sjmmv err(EXIT_FAILURE, "kevent"); 1701.1Sjmmv else if (nev > 0) { 1711.1Sjmmv for (i = 0; i < argc; i++) 1721.1Sjmmv if (event.ident == changes[i].ident) 1731.1Sjmmv break; 1741.1Sjmmv 1751.1Sjmmv if (event.fflags & NOTE_ATTRIB) 1761.1Sjmmv printf("%s - NOTE_ATTRIB\n", argv[i]); 1771.1Sjmmv if (event.fflags & NOTE_DELETE) 1781.1Sjmmv printf("%s - NOTE_DELETE\n", argv[i]); 1791.1Sjmmv if (event.fflags & NOTE_EXTEND) 1801.1Sjmmv printf("%s - NOTE_EXTEND\n", argv[i]); 1811.1Sjmmv if (event.fflags & NOTE_LINK) 1821.1Sjmmv printf("%s - NOTE_LINK\n", argv[i]); 1831.1Sjmmv if (event.fflags & NOTE_RENAME) 1841.1Sjmmv printf("%s - NOTE_RENAME\n", argv[i]); 1851.1Sjmmv if (event.fflags & NOTE_REVOKE) 1861.1Sjmmv printf("%s - NOTE_REVOKE\n", argv[i]); 1871.1Sjmmv if (event.fflags & NOTE_WRITE) 1881.1Sjmmv printf("%s - NOTE_WRITE\n", argv[i]); 1891.1Sjmmv } 1901.1Sjmmv } while (nev > 0); 1911.1Sjmmv } 1921.1Sjmmv 1931.1Sjmmv for (i = 0; i < argc; i++) 1941.1Sjmmv close(changes[i].ident); 1951.1Sjmmv free(changes); 1961.1Sjmmv 1971.1Sjmmv return EXIT_SUCCESS; 1981.1Sjmmv} 1991.1Sjmmv 2001.1Sjmmv/* --------------------------------------------------------------------- */ 2011.1Sjmmv 2021.1Sjmmvint 2031.1Sjmmvrename_main(int argc, char **argv) 2041.1Sjmmv{ 2051.1Sjmmv 2061.1Sjmmv if (argc < 3) 2071.1Sjmmv return EXIT_FAILURE; 2081.1Sjmmv 2091.1Sjmmv if (rename(argv[1], argv[2]) == -1) { 2101.4Schristos warn("rename"); 2111.1Sjmmv return EXIT_FAILURE; 2121.1Sjmmv } 2131.1Sjmmv 2141.1Sjmmv return EXIT_SUCCESS; 2151.1Sjmmv} 2161.1Sjmmv 2171.1Sjmmv/* --------------------------------------------------------------------- */ 2181.1Sjmmv 2191.1Sjmmvint 2201.1Sjmmvsockets_main(int argc, char **argv) 2211.1Sjmmv{ 2221.1Sjmmv int error, fd; 2231.1Sjmmv struct sockaddr_un addr; 2241.1Sjmmv 2251.1Sjmmv if (argc < 2) 2261.1Sjmmv return EXIT_FAILURE; 2271.1Sjmmv 2281.1Sjmmv fd = socket(PF_LOCAL, SOCK_STREAM, 0); 2291.1Sjmmv if (fd == -1) { 2301.4Schristos warn("socket"); 2311.1Sjmmv return EXIT_FAILURE; 2321.1Sjmmv } 2331.1Sjmmv 2341.5Smaya memset(&addr, 0, sizeof(addr)); 2351.1Sjmmv (void)strlcpy(addr.sun_path, argv[1], sizeof(addr.sun_path)); 2361.1Sjmmv addr.sun_family = PF_UNIX; 2371.5Smaya error = bind(fd, (struct sockaddr *)&addr, SUN_LEN(&addr)); 2381.1Sjmmv if (error == -1) { 2391.4Schristos warn("connect"); 2401.5Smaya (void)close(fd); 2411.1Sjmmv return EXIT_FAILURE; 2421.1Sjmmv } 2431.1Sjmmv 2441.1Sjmmv close(fd); 2451.1Sjmmv 2461.1Sjmmv return EXIT_SUCCESS; 2471.1Sjmmv} 2481.1Sjmmv 2491.1Sjmmv/* --------------------------------------------------------------------- */ 2501.1Sjmmv 2511.1Sjmmvint 2521.1Sjmmvstatvfs_main(int argc, char **argv) 2531.1Sjmmv{ 2541.1Sjmmv int error; 2551.1Sjmmv struct statvfs buf; 2561.1Sjmmv 2571.1Sjmmv if (argc < 2) 2581.1Sjmmv return EXIT_FAILURE; 2591.1Sjmmv 2601.1Sjmmv error = statvfs(argv[1], &buf); 2611.1Sjmmv if (error != 0) { 2621.4Schristos warn("statvfs"); 2631.1Sjmmv return EXIT_FAILURE; 2641.1Sjmmv } 2651.1Sjmmv 2661.1Sjmmv (void)printf("f_bsize=%lu\n", buf.f_bsize); 2671.1Sjmmv (void)printf("f_blocks=%" PRId64 "\n", buf.f_blocks); 2681.1Sjmmv (void)printf("f_bfree=%" PRId64 "\n", buf.f_bfree); 2691.1Sjmmv (void)printf("f_files=%" PRId64 "\n", buf.f_files); 2701.1Sjmmv 2711.1Sjmmv return EXIT_SUCCESS; 2721.1Sjmmv} 2731.1Sjmmv 2741.1Sjmmv/* --------------------------------------------------------------------- */ 2751.1Sjmmv 2761.1Sjmmvint 2771.1Sjmmvmain(int argc, char **argv) 2781.1Sjmmv{ 2791.1Sjmmv int error; 2801.1Sjmmv 2811.1Sjmmv if (argc < 2) 2821.1Sjmmv return EXIT_FAILURE; 2831.1Sjmmv 2841.1Sjmmv argc -= 1; 2851.1Sjmmv argv += 1; 2861.1Sjmmv 2871.1Sjmmv if (strcmp(argv[0], "getfh") == 0) 2881.1Sjmmv error = getfh_main(argc, argv); 2891.1Sjmmv else if (strcmp(argv[0], "kqueue") == 0) 2901.1Sjmmv error = kqueue_main(argc, argv); 2911.1Sjmmv else if (strcmp(argv[0], "rename") == 0) 2921.1Sjmmv error = rename_main(argc, argv); 2931.1Sjmmv else if (strcmp(argv[0], "sockets") == 0) 2941.1Sjmmv error = sockets_main(argc, argv); 2951.1Sjmmv else if (strcmp(argv[0], "statvfs") == 0) 2961.1Sjmmv error = statvfs_main(argc, argv); 2971.1Sjmmv else 2981.1Sjmmv error = EXIT_FAILURE; 2991.1Sjmmv 3001.1Sjmmv return error; 3011.1Sjmmv} 302