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