6b202f4e3d
to contain headers shared by kernel and userland (mainly libroot). * Moved quite a few private kernel headers to the new location. Split several kernel headers into a shared part and one that is still kernel private. Adjusted all affected Jamfiles and source in the standard x86 build accordingly. The build for other architectures and for test code may be broken. * Quite a bit of userland code still includes private kernel headers. Mostly those are <util/*> headers. The ones that aren't strictly kernel-only should be moved to some other place (maybe headers/private/shared/util). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25486 a95241bf-73f2-0310-859d-f6bbb57e9c96
194 lines
3.8 KiB
C++
194 lines
3.8 KiB
C++
/*
|
|
* Copyright 2006, Haiku, Inc.
|
|
* Distributed under the terms of the MIT license.
|
|
*
|
|
* Author:
|
|
* Axel Dörfler, axeld@pinc-software.de
|
|
*/
|
|
|
|
|
|
#include <OS.h>
|
|
#include <fs_info.h>
|
|
|
|
#include <syscalls.h>
|
|
#include <vfs_defs.h>
|
|
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
|
|
enum info_mode {
|
|
kList,
|
|
kFilterDevice,
|
|
kFilterFile,
|
|
};
|
|
|
|
extern const char *__progname;
|
|
|
|
|
|
const char *
|
|
open_mode_to_string(int openMode)
|
|
{
|
|
switch (openMode & O_RWMASK) {
|
|
case O_RDONLY:
|
|
return "R ";
|
|
case O_WRONLY:
|
|
return " W";
|
|
default:
|
|
return "R/W";
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
print_fds(team_info &teamInfo)
|
|
{
|
|
printf("Team: (%ld) %s\n", teamInfo.team, teamInfo.args);
|
|
|
|
uint32 cookie = 0;
|
|
fd_info info;
|
|
|
|
while (_kern_get_next_fd_info(teamInfo.team, &cookie, &info, sizeof(fd_info)) == B_OK) {
|
|
printf("%5d %s %ld:%Ld\n", info.number, open_mode_to_string(info.open_mode),
|
|
info.device, info.node);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
filter_device(team_info &teamInfo, dev_t device, bool brief)
|
|
{
|
|
uint32 cookie = 0;
|
|
fd_info info;
|
|
|
|
while (_kern_get_next_fd_info(teamInfo.team, &cookie, &info, sizeof(fd_info)) == B_OK) {
|
|
if (info.device != device)
|
|
continue;
|
|
|
|
if (brief) {
|
|
printf("%5ld %s\n", teamInfo.team, teamInfo.args);
|
|
break;
|
|
}
|
|
|
|
printf("%5ld %3d %3s %ld:%Ld %s\n", teamInfo.team, info.number,
|
|
open_mode_to_string(info.open_mode), info.device, info.node,
|
|
teamInfo.args);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
filter_file(team_info &teamInfo, dev_t device, ino_t node, bool brief)
|
|
{
|
|
uint32 cookie = 0;
|
|
fd_info info;
|
|
|
|
while (_kern_get_next_fd_info(teamInfo.team, &cookie, &info, sizeof(fd_info)) == B_OK) {
|
|
if (info.device != device || info.node != node)
|
|
continue;
|
|
|
|
if (brief) {
|
|
printf("%5ld %s\n", teamInfo.team, teamInfo.args);
|
|
break;
|
|
}
|
|
|
|
printf("%5ld %3d %3s %s\n", teamInfo.team, info.number,
|
|
open_mode_to_string(info.open_mode), teamInfo.args);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
usage(bool failure)
|
|
{
|
|
printf("Usage: %s <id/pattern> or -[dD] <path-to-device> or -[fF] <file>\n"
|
|
" Shows info about the used file descriptors in the system.\n\n"
|
|
" -d\tOnly shows accesses to the given device\n"
|
|
" -D\tLikewise, but only shows the teams that access it\n"
|
|
" -f\tOnly shows accesses to the given file\n"
|
|
" -F\tLikewise, but only shows the teams that access it\n",
|
|
__progname);
|
|
|
|
exit(failure ? 1 : 0);
|
|
}
|
|
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
const char *pattern = NULL;
|
|
dev_t device = -1;
|
|
ino_t node = -1;
|
|
int32 id = -1;
|
|
info_mode mode = kList;
|
|
bool brief = false;
|
|
|
|
// parse arguments
|
|
|
|
if (argc == 2) {
|
|
// filter output
|
|
if (isdigit(argv[1][0]))
|
|
id = atol(argv[1]);
|
|
else if (argv[1][0] == '-')
|
|
usage(!strcmp(argv[1], "--help"));
|
|
else
|
|
pattern = argv[1];
|
|
} else if (argc > 2) {
|
|
if (!strcmp(argv[1], "-d") || !strcmp(argv[1], "-D")) {
|
|
// filter by device usage
|
|
device = dev_for_path(argv[2]);
|
|
if (device < 0) {
|
|
fprintf(stderr, "%s: could not find device: %s\n", __progname,
|
|
strerror(errno));
|
|
return 1;
|
|
}
|
|
mode = kFilterDevice;
|
|
if (argv[1][1] == 'D')
|
|
brief = true;
|
|
} else if (!strcmp(argv[1], "-f") || !strcmp(argv[1], "-F")) {
|
|
// filter by file usage
|
|
struct stat stat;
|
|
if (::stat(argv[2], &stat) < 0) {
|
|
fprintf(stderr, "%s: could not open file: %s\n", __progname,
|
|
strerror(errno));
|
|
return 1;
|
|
}
|
|
device = stat.st_dev;
|
|
node = stat.st_ino;
|
|
mode = kFilterFile;
|
|
if (argv[1][1] == 'F')
|
|
brief = true;
|
|
} else
|
|
usage(true);
|
|
}
|
|
|
|
// do the job!
|
|
|
|
team_info info;
|
|
int32 cookie = 0;
|
|
|
|
while (get_next_team_info(&cookie, &info) == B_OK) {
|
|
switch (mode) {
|
|
case kList:
|
|
if ((id != -1 && id != info.team)
|
|
|| pattern != NULL && !strstr(info.args, pattern))
|
|
continue;
|
|
print_fds(info);
|
|
break;
|
|
|
|
case kFilterDevice:
|
|
filter_device(info, device, brief);
|
|
break;
|
|
case kFilterFile:
|
|
filter_file(info, device, node, brief);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|