Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / test / stress / stress2 / misc / kevent4.sh
1 #!/bin/sh
2
3 #
4 # Copyright (c) 2008 Peter Holm <pho@FreeBSD.org>
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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 # SUCH DAMAGE.
27 #
28 # $FreeBSD$
29 #
30 # Test scenario by kib@
31
32 . ../default.cfg
33
34 odir=`pwd`
35
36 cd /tmp
37 sed '1,/^EOF/d' < $odir/$0 > kevent.c
38 cc -o kevent -Wall kevent.c -pthread
39 rm -f kevent.c
40
41 cd $odir/..
42 export runRUNTIME=3m
43 ./run.sh &
44 rpid=$!
45
46 cd $RUNDIR
47 /tmp/kevent $rpid &
48
49 sleep 120
50 kill $rpid
51 kill $!
52 rm -f /tmp/kevent
53
54 exit
55 EOF
56 // $FreeBSD$
57
58 #include <unistd.h>
59 #include <sys/types.h>
60 #include <sys/event.h>
61 #include <errno.h>
62 #include <string.h>
63 #include <stdio.h>
64 #include <stdlib.h>
65 #ifndef true
66 # define true 1
67 #endif
68
69 int kq;
70
71 void
72 err(const char *msg, int err_no)
73 {
74         fprintf(stderr, "%s: %s\n", msg, strerror(err_no));
75         exit(1);
76 }
77
78 void
79 init_kq()
80 {
81         kq = kqueue();
82         if (kq == -1)
83                 err("kqueue", errno);
84 }
85
86 void
87 add_watch(pid_t pid)
88 {
89         struct kevent kev;
90         bzero(&kev, sizeof(kev));
91         kev.ident = pid;
92         kev.flags = EV_ADD | EV_ENABLE;
93         kev.filter = EVFILT_PROC;
94         kev.fflags = NOTE_EXIT | NOTE_FORK | NOTE_EXEC | NOTE_TRACK;
95
96         while (true) {
97                 int res = kevent(kq, &kev, 1, NULL, 0, NULL);
98                 if (res == -1) {
99                         if (errno == EINTR)
100                                 continue;
101                         if (errno == ESRCH)
102                                 break;
103
104                         int err_no = errno;
105                         char msg[64];
106                         snprintf(msg, sizeof(msg),
107                                  "kevent - add watch for pid %u", pid);
108                         err(msg, err_no);
109                 }
110                 else
111                         break;
112         }
113 }
114
115 void
116 del_watch(pid_t pid)
117 {
118         struct kevent kev;
119         bzero(&kev, sizeof(kev));
120         kev.ident = pid;
121         kev.flags = EV_DELETE;
122         kev.filter = EVFILT_PROC;
123
124         while (true) {
125                 int res = kevent(kq, &kev, 1, NULL, 0, NULL);
126                 if (res == -1) {
127                         if (errno == EINTR)
128                                 continue;
129                         if (errno == ESRCH)
130                                 break;
131
132                         int err_no = errno;
133                         char msg[64];
134                         snprintf(msg, sizeof(msg),
135                                  "kevent - del watch for pid %u", pid);
136                         err(msg, err_no);
137                 }
138                 else
139                         break;
140         }
141 }
142
143 void polling()
144 {
145         struct kevent kev[10];
146         pid_t pid;
147         int i;
148
149         while (true) {
150                 bzero(&kev, sizeof(kev));
151                 int res = kevent(kq, NULL, 0, kev,
152                                  sizeof(kev) / sizeof(kev[0]), NULL);
153                 if (res == -1) {
154                         if (errno == EINTR)
155                                 continue;
156
157                         if (errno == ESRCH)
158                                 continue;
159
160                         err("kevent", errno);
161                 }
162
163                 for (i = 0; i < res; i++) {
164                         pid = kev[i].ident;
165                         if (kev[i].fflags & NOTE_CHILD) {
166                                 add_watch(pid);
167                                 printf("%u - new process, parent %u\n", pid, kev[i].data);
168                         }
169                         if (kev[i].fflags & NOTE_FORK) {
170                                 printf("%u forked\n", pid);
171                         }
172                         if (kev[i].fflags & NOTE_EXEC) {
173                                 printf("%u called exec\n", pid);
174                         }
175                         if (kev[i].fflags & NOTE_EXIT) {
176                                 printf("%u exited\n", pid);
177 //                              del_watch(pid);
178                         }
179                         if (kev[i].fflags & NOTE_TRACK) {
180                                 printf("%u forked - track\n", pid);
181                         }
182                         if (kev[i].fflags & NOTE_TRACKERR) {
183                                 fprintf(stderr, "%u - track error\n", pid);
184                         }
185                 }
186         }
187 }
188
189 int main(int argc, char *argv[])
190 {
191         if (argc != 2) {
192                 fprintf(stderr, "pid ?\n");
193                 return (2);
194         }
195         pid_t parent = atoi(argv[1]);
196
197         init_kq();
198         add_watch(parent);
199         polling();
200
201         return (0);
202 }