xref: /haiku/src/tests/system/libroot/os/system_watching_test.cpp (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
1 /*
2  * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 
11 #include <OS.h>
12 
13 #include <system_info.h>
14 #include <util/KMessage.h>
15 
16 
17 extern const char* __progname;
18 
19 
20 static void
21 print_usage(bool error)
22 {
23 	fprintf(error ? stderr : stdout,
24 		"Usage: %s [ <teamID> [ <events> ] ]\n"
25 		"  teamID  - The team ID of the team to watch or -1 for all teams\n"
26 		"            (-1 is the default).\n"
27 		"  events  - A string specifying the events to watch, consisting of:\n"
28 		"            'C': team creation\n"
29 		"            'D': team deletion\n"
30 		"            'c': thread creation\n"
31 		"            'd': thread deletion\n"
32 		"            'p': thread properties\n"
33 		"            The default is all events.\n",
34 		__progname);
35 }
36 
37 
38 static void
39 print_usage_and_exit(bool error)
40 {
41 	print_usage(error);
42 	exit(error ? 1 : 0);
43 }
44 
45 
46 int
47 main(int argc, const char* const* argv)
48 {
49 	int32 watchTeam = -1;
50 	uint32 watchEvents = B_WATCH_SYSTEM_ALL;
51 
52 	if (argc > 3)
53 		print_usage_and_exit(true);
54 
55 	if (argc > 1) {
56 		const char* arg = argv[1];
57 		if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0)
58 			print_usage_and_exit(false);
59 
60 		// first parameter is the team ID
61 		watchTeam = atol(arg);
62 
63 		if (argc > 2) {
64 			// second parameter is the events string
65 			arg = argv[2];
66 			watchEvents = 0;
67 			while (*arg != '\0') {
68 				switch (*arg) {
69 					case 'C':
70 						watchEvents |= B_WATCH_SYSTEM_TEAM_CREATION;
71 						break;
72 					case 'D':
73 						watchEvents |= B_WATCH_SYSTEM_TEAM_DELETION;
74 						break;
75 					case 'c':
76 						watchEvents |= B_WATCH_SYSTEM_THREAD_CREATION;
77 						break;
78 					case 'd':
79 						watchEvents |= B_WATCH_SYSTEM_THREAD_DELETION;
80 						break;
81 					case 'p':
82 						watchEvents |= B_WATCH_SYSTEM_THREAD_PROPERTIES;
83 						break;
84 					default:
85 						print_usage_and_exit(true);
86 				}
87 				arg++;
88 			}
89 		}
90 	}
91 
92 	// create a port
93 	port_id port = create_port(10, "system watching test");
94 	if (port < 0) {
95 		fprintf(stderr, "Failed to create port: %s\n", strerror(port));
96 		exit(1);
97 	}
98 
99 	// start watching
100 	status_t error = __start_watching_system(watchTeam, watchEvents, port, 0);
101 	if (error != B_OK) {
102 		fprintf(stderr, "Failed to start watching: %s\n", strerror(error));
103 		exit(1);
104 	}
105 
106 	// receive notifications
107 	while (true) {
108 		// read the message from the port
109 		char buffer[1024];
110 		int32 messageCode;
111 		ssize_t bytesRead = read_port(port, &messageCode, buffer,
112 			sizeof(buffer));
113 		if (bytesRead < 0) {
114 			if (bytesRead == B_INTERRUPTED)
115 				continue;
116 			fprintf(stderr, "Failed to read from port: %s\n",
117 				strerror(bytesRead));
118 			exit(1);
119 		}
120 
121 		// create a KMessage
122 		KMessage message;
123 		error = message.SetTo((const void*)buffer, bytesRead);
124 		if (error != B_OK) {
125 			fprintf(stderr, "Failed to create message: %s\n", strerror(error));
126 			continue;
127 		}
128 
129 		message.Dump((void(*)(const char*,...))printf);
130 
131 		// check "what"
132 		if (message.What() != B_SYSTEM_OBJECT_UPDATE)
133 			fprintf(stderr, "Unexpected message what!\n");
134 
135 		// get opcode
136 		int32 opcode = 0;
137 		if (message.FindInt32("opcode", &opcode) != B_OK)
138 			fprintf(stderr, "Failed to get message opcode!\n");
139 
140 		switch (opcode) {
141 			case B_TEAM_CREATED:
142 			{
143 				printf("B_TEAM_CREATED: ");
144 				int32 teamID;
145 				if (message.FindInt32("team", &teamID) == B_OK)
146 					printf("team: %" B_PRId32 "\n", teamID);
147 				else
148 					printf("no \"team\" field\n");
149 
150 				break;
151 			}
152 			case B_TEAM_DELETED:
153 			{
154 				printf("B_TEAM_DELETED: ");
155 				int32 teamID;
156 				if (message.FindInt32("team", &teamID) == B_OK)
157 					printf("team: %" B_PRId32 "\n", teamID);
158 				else
159 					printf("no \"team\" field\n");
160 
161 				break;
162 			}
163 			case B_TEAM_EXEC:
164 			{
165 				printf("B_TEAM_EXEC: ");
166 				int32 teamID;
167 				if (message.FindInt32("team", &teamID) == B_OK)
168 					printf("team: %" B_PRId32 "\n", teamID);
169 				else
170 					printf("no \"team\" field\n");
171 
172 				break;
173 			}
174 
175 			case B_THREAD_CREATED:
176 			{
177 				printf("B_THREAD_CREATED: ");
178 				int32 threadID;
179 				if (message.FindInt32("thread", &threadID) == B_OK)
180 					printf("thread: %" B_PRId32 "\n", threadID);
181 				else
182 					printf("no \"thread\" field\n");
183 
184 				break;
185 			}
186 			case B_THREAD_DELETED:
187 			{
188 				printf("B_THREAD_DELETED: ");
189 				int32 threadID;
190 				if (message.FindInt32("thread", &threadID) == B_OK)
191 					printf("thread: %" B_PRId32 "\n", threadID);
192 				else
193 					printf("no \"thread\" field\n");
194 
195 				break;
196 			}
197 			case B_THREAD_NAME_CHANGED:
198 			{
199 				printf("B_THREAD_NAME_CHANGED: ");
200 				int32 threadID;
201 				if (message.FindInt32("thread", &threadID) == B_OK)
202 					printf("thread: %" B_PRId32 "\n", threadID);
203 				else
204 					printf("no \"thread\" field\n");
205 
206 				break;
207 			}
208 
209 			default:
210 				fprintf(stderr, "Unknown opcode!\n");
211 				break;
212 		}
213 	}
214 
215 	return 0;
216 }
217