Added tool "fdinfo" to inspect file descriptors of other teams.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15993 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
7817211a38
commit
5fb1a4102a
@ -3,10 +3,9 @@ SubDir HAIKU_TOP src bin ;
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
UsePrivateHeaders app ;
|
||||
UsePrivateHeaders kernel ;
|
||||
UsePrivateHeaders shared ;
|
||||
UsePrivateHeaders storage ;
|
||||
UseArchHeaders $(TARGET_ARCH) ;
|
||||
UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ;
|
||||
SubDirHdrs $(HAIKU_TOP) src add-ons kernel file_cache ;
|
||||
|
||||
# standard commands that don't need any additional library
|
||||
@ -21,6 +20,7 @@ StdBinCommands
|
||||
# echo.c
|
||||
eject.c
|
||||
error.c
|
||||
fdinfo.cpp
|
||||
fortune.c
|
||||
finddir.c
|
||||
hd.c
|
||||
|
193
src/bin/fdinfo.cpp
Normal file
193
src/bin/fdinfo.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* 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 <vfs.h>
|
||||
#include <syscalls.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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user