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