xref: /netbsd-src/tests/fs/tmpfs/h_tools.c (revision 687000d2158126ebf9a2e443357211c9fdcf7618)
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