1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <fnmatch.h>
6 #include <inttypes.h>
7 #include <libgen.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #include <zircon/syscalls.h>
13 #include <task-utils/walker.h>
14 
15 const char* kill_name;
16 int killed = 0;
17 
process_callback(void * unused_ctx,int depth,zx_handle_t process,zx_koid_t koid,zx_koid_t parent_koid)18 zx_status_t process_callback(void* unused_ctx, int depth, zx_handle_t process,
19                              zx_koid_t koid, zx_koid_t parent_koid) {
20     char name[ZX_MAX_NAME_LEN];
21     zx_status_t status =
22         zx_object_get_property(process, ZX_PROP_NAME, name, sizeof(name));
23     if (status != ZX_OK) {
24         return status;
25     }
26     if (!strcmp(name, kill_name) ||
27         !fnmatch(kill_name, name, 0) ||
28         !strcmp(basename(name), kill_name)) {
29         zx_task_kill(process);
30         printf("Killed %" PRIu64 " %s\n", koid, name);
31         killed++;
32     }
33     return ZX_OK;
34 }
35 
main(int argc,char ** argv)36 int main(int argc, char** argv) {
37     if (argc != 2) {
38         fprintf(stderr, "usage: %s <process>\n", argv[0]);
39         fprintf(stderr, "  <process> can be the name of a process, the basename of a process\n");
40         fprintf(stderr, "  or glob pattern matching a process name.\n");
41         return -1;
42     }
43 
44     kill_name = argv[1];
45 
46     walk_root_job_tree(NULL, process_callback, NULL, NULL);
47     if (killed == 0) {
48         fprintf(stderr, "no tasks found\n");
49         return -1;
50     }
51 }
52