xref: /haiku/src/bin/pidof.cpp (revision da8162be21b36442f34a731873d2358a0d63c25a)
1 /*
2  * Copyright 2022, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Oscar Lesta <oscar.lesta@gmail.com>
7  */
8 
9 #include <stdio.h>
10 #include <string.h>
11 
12 #include <OS.h>
13 
14 #include <extended_system_info.h>
15 #include <extended_system_info_defs.h>
16 #include <util/KMessage.h>
17 
18 
19 static void
usage(FILE * output=stdout)20 usage(FILE* output = stdout)
21 {
22 	fprintf(output, "Return the process id(s) (PID) for the given process name.\n\n"
23 		"Usage:\tpidof [-hsv] process_name\n"
24 		"\t\t-h : Show this help.\n"
25 		"\t\t-s : Print only the PID for the first matching process.\n"
26 		"\t\t-v : Verbose output.\n"
27 	);
28 }
29 
30 
31 int
main(int argc,char * argv[])32 main(int argc, char* argv[])
33 {
34 	bool singleShot = false;
35 	bool verbose = false;
36 
37 	int c;
38 	while ((c = getopt(argc, argv, "hvs")) != -1) {
39 		switch (c) {
40 			case 'h':
41 				usage();
42 				return 0;
43 			case 's':
44 				singleShot = true;
45 				break;
46 			case 'v':
47 				verbose = true;
48 				break;
49 			default:
50 				usage(stderr);
51 				return 1;
52 		}
53 	}
54 
55 	if ((argc == optind) || (argc - optind) > 1) {
56 		if (verbose)
57 			fprintf(stderr, "Error: A (single) process name is expected.\n");
58 
59 		usage(stderr);
60 		return 1;
61 	}
62 
63 	int32 cookie = 0;
64 	team_info teamInfo;
65 	bool processFound = false;
66 	const char* processName = argv[argc - 1];
67 
68 	while (get_next_team_info(&cookie, &teamInfo) == B_OK) {
69 		KMessage extendedInfo;
70 		status_t status = get_extended_team_info(teamInfo.team, B_TEAM_INFO_BASIC, extendedInfo);
71 
72 		if (status == B_BAD_TEAM_ID) {
73 			// The team might have simply ended between the last function calls.
74 			continue;
75 		} else if (status != B_OK) {
76 			fprintf(stderr, "Error: get_extended_team_info() == 0x%" B_PRIx32 " (%s)\n",
77 				status, strerror(status));
78 			return 1;
79 		}
80 
81 		const char* teamName = NULL;
82 		if (extendedInfo.FindString("name", &teamName) != B_OK)
83 			continue;
84 
85 		if (strcmp(teamName, processName) == 0) {
86 			processFound = true;
87 			printf("%" B_PRId32 "\n", teamInfo.team);
88 			if (singleShot)
89 				return 0;
90 		}
91 	}
92 
93 	if (verbose && !processFound)
94 		fprintf(stderr, "Error: Process name not found.\n");
95 
96 	return processFound ? 0 : 1;
97 }
98