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