libroot/posix/stdio: Remove unused portions.
[haiku.git] / src / bin / fdinfo.cpp
blob3d4e8ac7a8debb03054e5ae60c338ff363aa9568
1 /*
2 * Copyright 2006-2015, Haiku, Inc.
3 * Distributed under the terms of the MIT license.
5 * Author:
6 * Axel Dörfler, axeld@pinc-software.de
7 */
10 #include <OS.h>
11 #include <fs_info.h>
13 #include <syscalls.h>
14 #include <vfs_defs.h>
16 #include <ctype.h>
17 #include <errno.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
23 enum info_mode {
24 kList,
25 kFilterDevice,
26 kFilterFile,
29 extern const char *__progname;
32 const char *
33 open_mode_to_string(int openMode)
35 switch (openMode & O_RWMASK) {
36 case O_RDONLY:
37 return "R ";
38 case O_WRONLY:
39 return " W";
40 default:
41 return "R/W";
46 void
47 print_fds(team_info &teamInfo)
49 printf("Team: (%" B_PRId32 ") %s\n", teamInfo.team, teamInfo.args);
51 uint32 cookie = 0;
52 fd_info info;
54 while (_kern_get_next_fd_info(teamInfo.team, &cookie, &info, sizeof(fd_info)) == B_OK) {
55 printf("%5d %s %" B_PRIdDEV ":%" B_PRIdINO "\n", info.number,
56 open_mode_to_string(info.open_mode), info.device, info.node);
61 void
62 filter_device(team_info &teamInfo, dev_t device, bool brief)
64 uint32 cookie = 0;
65 fd_info info;
67 while (_kern_get_next_fd_info(teamInfo.team, &cookie, &info, sizeof(fd_info)) == B_OK) {
68 if (info.device != device)
69 continue;
71 if (brief) {
72 printf("%5" B_PRId32 " %s\n", teamInfo.team, teamInfo.args);
73 break;
76 printf("%5" B_PRId32 " %3d %3s %" B_PRIdDEV ":%" B_PRIdINO " %s\n",
77 teamInfo.team, info.number, open_mode_to_string(info.open_mode),
78 info.device, info.node, teamInfo.args);
83 void
84 filter_file(team_info &teamInfo, dev_t device, ino_t node, bool brief)
86 uint32 cookie = 0;
87 fd_info info;
89 while (_kern_get_next_fd_info(teamInfo.team, &cookie, &info, sizeof(fd_info)) == B_OK) {
90 if (info.device != device || info.node != node)
91 continue;
93 if (brief) {
94 printf("%5" B_PRId32 " %s\n", teamInfo.team, teamInfo.args);
95 break;
98 printf("%5" B_PRId32 " %3d %3s %s\n", teamInfo.team, info.number,
99 open_mode_to_string(info.open_mode), teamInfo.args);
104 void
105 usage(bool failure)
107 printf("Usage: %s <id/pattern> or -[dD] <path-to-device> or -[fF] <file>\n"
108 " Shows info about the used file descriptors in the system.\n\n"
109 " -d\tOnly shows accesses to the given device\n"
110 " -D\tLikewise, but only shows the teams that access it\n"
111 " -f\tOnly shows accesses to the given file\n"
112 " -F\tLikewise, but only shows the teams that access it\n",
113 __progname);
115 exit(failure ? 1 : 0);
120 main(int argc, char **argv)
122 const char *pattern = NULL;
123 dev_t device = -1;
124 ino_t node = -1;
125 int32 id = -1;
126 info_mode mode = kList;
127 bool brief = false;
129 // parse arguments
131 if (argc == 2) {
132 // filter output
133 if (isdigit(argv[1][0]))
134 id = atol(argv[1]);
135 else if (argv[1][0] == '-')
136 usage(!strcmp(argv[1], "--help"));
137 else
138 pattern = argv[1];
139 } else if (argc > 2) {
140 if (!strcmp(argv[1], "-d") || !strcmp(argv[1], "-D")) {
141 // filter by device usage
142 device = dev_for_path(argv[2]);
143 if (device < 0) {
144 fprintf(stderr, "%s: could not find device: %s\n", __progname,
145 strerror(errno));
146 return 1;
148 mode = kFilterDevice;
149 if (argv[1][1] == 'D')
150 brief = true;
151 } else if (!strcmp(argv[1], "-f") || !strcmp(argv[1], "-F")) {
152 // filter by file usage
153 struct stat stat;
154 if (::stat(argv[2], &stat) < 0) {
155 fprintf(stderr, "%s: could not open file: %s\n", __progname,
156 strerror(errno));
157 return 1;
159 device = stat.st_dev;
160 node = stat.st_ino;
161 mode = kFilterFile;
162 if (argv[1][1] == 'F')
163 brief = true;
164 } else
165 usage(true);
168 // do the job!
170 team_info info;
171 int32 cookie = 0;
173 while (get_next_team_info(&cookie, &info) == B_OK) {
174 switch (mode) {
175 case kList:
176 if ((id != -1 && id != info.team)
177 || (pattern != NULL && !strstr(info.args, pattern)))
178 continue;
179 print_fds(info);
180 break;
182 case kFilterDevice:
183 filter_device(info, device, brief);
184 break;
185 case kFilterFile:
186 filter_file(info, device, node, brief);
187 break;
191 return 0;