]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - tools/regression/tmpfs/h_tools.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / tools / regression / tmpfs / h_tools.c
1 /*      $NetBSD: h_tools.c,v 1.8 2007/07/23 15:05:43 jmmv Exp $ */
2
3 /*-
4  * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
9  * 2005 program.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  * $FreeBSD$
33  */
34
35 /*
36  * Helper tools for several tests.  These are kept in a single file due
37  * to the limitations of bsd.prog.mk to build a single program in a
38  * given directory.
39  */
40
41 #include <sys/param.h>
42 #include <sys/types.h>
43 #include <sys/event.h>
44 #include <sys/mount.h>
45 #include <sys/statvfs.h>
46 #include <sys/stdint.h>
47 #include <sys/socket.h>
48 #include <sys/time.h>
49 #include <sys/un.h>
50
51 #include <assert.h>
52 #include <err.h>
53 #include <errno.h>
54 #include <fcntl.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <string.h>
58 #include <unistd.h>
59
60 /* --------------------------------------------------------------------- */
61
62 static int getfh_main(int, char **);
63 static int kqueue_main(int, char **);
64 static int rename_main(int, char **);
65 static int sockets_main(int, char **);
66 static int statvfs_main(int, char **);
67
68 /* --------------------------------------------------------------------- */
69
70 int
71 getfh_main(int argc, char **argv)
72 {
73         int error;
74         fhandle_t fh;
75
76         if (argc < 2)
77                 return EXIT_FAILURE;
78
79         error = getfh(argv[1], &fh);
80         if (error == 0) 
81                 err(EXIT_FAILURE, "can not getfh");     
82
83         error = write(STDOUT_FILENO, &fh, sizeof(fh));
84         if (error == -1) {
85                 perror("write");
86                 return EXIT_FAILURE;
87         }
88
89         return 0;
90 }
91
92 /* --------------------------------------------------------------------- */
93
94 int
95 kqueue_main(int argc, char **argv)
96 {
97         char *line;
98         int i, kq;
99         size_t len;
100         struct kevent *changes, event;
101
102         if (argc < 2)
103                 return EXIT_FAILURE;
104
105         argc--;
106         argv++;
107
108         changes = malloc(sizeof(struct kevent) * (argc - 1));
109         if (changes == NULL)
110                 errx(EXIT_FAILURE, "not enough memory");
111
112         for (i = 0; i < argc; i++) {
113                 int fd;
114
115                 fd = open(argv[i], O_RDONLY);
116                 if (fd == -1)
117                         err(EXIT_FAILURE, "cannot open %s", argv[i]);
118
119                 EV_SET(&changes[i], fd, EVFILT_VNODE,
120                     EV_ADD | EV_ENABLE | EV_ONESHOT,
121                     NOTE_ATTRIB | NOTE_DELETE | NOTE_EXTEND | NOTE_LINK |
122                     NOTE_RENAME | NOTE_REVOKE | NOTE_WRITE,
123                     0, 0);
124         }
125
126         kq = kqueue();
127         if (kq == -1)
128                 err(EXIT_FAILURE, "kqueue");
129
130         while ((line = fgetln(stdin, &len)) != NULL) {
131                 int ec, nev;
132                 struct timespec to;
133
134                 to.tv_sec = 0;
135                 to.tv_nsec = 100000;
136
137                 (void)kevent(kq, changes, argc, &event, 1, &to);
138
139                 assert(len > 0);
140                 assert(line[len - 1] == '\n');
141                 line[len - 1] = '\0';
142                 ec = system(line);
143                 if (ec != EXIT_SUCCESS)
144                         errx(ec, "%s returned %d", line, ec);
145
146                 do {
147                         nev = kevent(kq, changes, argc, &event, 1, &to);
148                         if (nev == -1)
149                                 err(EXIT_FAILURE, "kevent");
150                         else if (nev > 0) {
151                                 for (i = 0; i < argc; i++)
152                                         if (event.ident == changes[i].ident)
153                                                 break;
154
155                                 if (event.fflags & NOTE_ATTRIB)
156                                         printf("%s - NOTE_ATTRIB\n", argv[i]);
157                                 if (event.fflags & NOTE_DELETE)
158                                         printf("%s - NOTE_DELETE\n", argv[i]);
159                                 if (event.fflags & NOTE_EXTEND)
160                                         printf("%s - NOTE_EXTEND\n", argv[i]);
161                                 if (event.fflags & NOTE_LINK)
162                                         printf("%s - NOTE_LINK\n", argv[i]);
163                                 if (event.fflags & NOTE_RENAME)
164                                         printf("%s - NOTE_RENAME\n", argv[i]);
165                                 if (event.fflags & NOTE_REVOKE)
166                                         printf("%s - NOTE_REVOKE\n", argv[i]);
167                                 if (event.fflags & NOTE_WRITE)
168                                         printf("%s - NOTE_WRITE\n", argv[i]);
169                         }
170                 } while (nev > 0);
171         }
172
173         for (i = 0; i < argc; i++)
174                 close(changes[i].ident);
175         free(changes);
176
177         return EXIT_SUCCESS;
178 }
179
180 /* --------------------------------------------------------------------- */
181
182 int
183 rename_main(int argc, char **argv)
184 {
185
186         if (argc < 3)
187                 return EXIT_FAILURE;
188
189         if (rename(argv[1], argv[2]) == -1) {
190                 perror("rename");
191                 return EXIT_FAILURE;
192         }
193
194         return EXIT_SUCCESS;
195 }
196
197 /* --------------------------------------------------------------------- */
198
199 int
200 sockets_main(int argc, char **argv)
201 {
202         int error, fd;
203         struct sockaddr_un addr;
204
205         if (argc < 2)
206                 return EXIT_FAILURE;
207
208         fd = socket(PF_LOCAL, SOCK_STREAM, 0);
209         if (fd == -1) {
210                 perror("socket");
211                 return EXIT_FAILURE;
212         }
213
214         (void)strlcpy(addr.sun_path, argv[1], sizeof(addr.sun_path));
215         addr.sun_family = PF_UNIX;
216
217         error = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
218         if (error == -1) {
219                 perror("connect");
220                 return EXIT_FAILURE;
221         }
222
223         close(fd);
224
225         return EXIT_SUCCESS;
226 }
227
228 /* --------------------------------------------------------------------- */
229
230 int
231 statvfs_main(int argc, char **argv)
232 {
233         int error;
234         struct statfs buf;
235
236         if (argc < 2)
237                 return EXIT_FAILURE;
238
239         memset(&buf, 0, sizeof(buf));
240         buf.f_version = STATFS_VERSION;
241         error = statfs(argv[1], &buf);
242         if (error != 0) {
243                 perror("statvfs");
244                 return EXIT_FAILURE;
245         }
246
247         (void)printf("f_bsize=%ju\n", (uintmax_t)buf.f_bsize);
248         (void)printf("f_blocks=%ju\n", (uintmax_t)buf.f_blocks);
249         (void)printf("f_bfree=%ju\n", (uintmax_t)buf.f_bfree);
250         (void)printf("f_files=%ju\n", (uintmax_t)buf.f_files);
251
252         return EXIT_SUCCESS;
253 }
254
255 /* --------------------------------------------------------------------- */
256
257 int
258 main(int argc, char **argv)
259 {
260         int error;
261
262         if (argc < 2)
263                 return EXIT_FAILURE;
264
265         argc -= 1;
266         argv += 1;
267
268         if (strcmp(argv[0], "getfh") == 0)
269                 error = getfh_main(argc, argv);
270         else if (strcmp(argv[0], "kqueue") == 0)
271                 error = kqueue_main(argc, argv);
272         else if (strcmp(argv[0], "rename") == 0)
273                 error = rename_main(argc, argv);
274         else if (strcmp(argv[0], "sockets") == 0)
275                 error = sockets_main(argc, argv);
276         else if (strcmp(argv[0], "statvfs") == 0)
277                 error = statvfs_main(argc, argv);
278         else
279                 error = EXIT_FAILURE;
280
281         return error;
282 }