From 5fb1a4102af7774950a99e3499baee9ac38ae2d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 17 Jan 2006 01:47:05 +0000 Subject: [PATCH] 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 --- src/bin/Jamfile | 4 +- src/bin/fdinfo.cpp | 193 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 src/bin/fdinfo.cpp diff --git a/src/bin/Jamfile b/src/bin/Jamfile index c1698c9654..fdddae5dcf 100644 --- a/src/bin/Jamfile +++ b/src/bin/Jamfile @@ -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 diff --git a/src/bin/fdinfo.cpp b/src/bin/fdinfo.cpp new file mode 100644 index 0000000000..335d443286 --- /dev/null +++ b/src/bin/fdinfo.cpp @@ -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 +#include + +#include +#include + +#include +#include +#include +#include +#include + + +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 or -[dD] or -[fF] \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; +} +