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