mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-26 19:32:06 -05:00
lsof: Separate file name components
In /proc/PID/fds we get not only file name, but also additional information about file type, state etc. This commit makes `lsof' command separate these components. When you are filtering files by file name, only actual file name is checked (not additional data).
This commit is contained in:
parent
2ed0385075
commit
dd682168a9
1 changed files with 49 additions and 7 deletions
|
@ -24,6 +24,7 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <AK/GenericLexer.h>
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
#include <AK/JsonArray.h>
|
#include <AK/JsonArray.h>
|
||||||
#include <AK/JsonObject.h>
|
#include <AK/JsonObject.h>
|
||||||
|
@ -39,9 +40,46 @@
|
||||||
struct OpenFile {
|
struct OpenFile {
|
||||||
int fd;
|
int fd;
|
||||||
int pid;
|
int pid;
|
||||||
|
String type;
|
||||||
String name;
|
String name;
|
||||||
|
String state;
|
||||||
|
String full_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool parse_name(StringView name, OpenFile& file)
|
||||||
|
{
|
||||||
|
GenericLexer lexer(name);
|
||||||
|
auto component1 = lexer.consume_until(':');
|
||||||
|
|
||||||
|
if (lexer.tell_remaining() == 0) {
|
||||||
|
file.name = component1;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
file.type = component1;
|
||||||
|
auto component2 = lexer.consume_while([](char c) { return is_printable(c) && !is_whitespace(c) && c != '('; });
|
||||||
|
lexer.ignore_while(is_whitespace);
|
||||||
|
file.name = component2;
|
||||||
|
|
||||||
|
if (lexer.tell_remaining() == 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (!lexer.consume_specific('(')) {
|
||||||
|
dbg() << "parse_name: expected (";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto component3 = lexer.consume_until(')');
|
||||||
|
if (lexer.tell_remaining() != 0) {
|
||||||
|
dbg() << "parse_name: expected EOF";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.state = component3;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Vector<OpenFile> get_open_files_by_pid(pid_t pid)
|
static Vector<OpenFile> get_open_files_by_pid(pid_t pid)
|
||||||
{
|
{
|
||||||
auto file = Core::File::open(String::format("/proc/%d/fds", pid), Core::IODevice::OpenMode::ReadOnly);
|
auto file = Core::File::open(String::format("/proc/%d/fds", pid), Core::IODevice::OpenMode::ReadOnly);
|
||||||
|
@ -63,7 +101,11 @@ static Vector<OpenFile> get_open_files_by_pid(pid_t pid)
|
||||||
OpenFile open_file;
|
OpenFile open_file;
|
||||||
open_file.pid = pid;
|
open_file.pid = pid;
|
||||||
open_file.fd = object.as_object().get("fd").to_int();
|
open_file.fd = object.as_object().get("fd").to_int();
|
||||||
open_file.name = object.as_object().get("absolute_path").to_string();
|
|
||||||
|
String name = object.as_object().get("absolute_path").to_string();
|
||||||
|
ASSERT(parse_name(name, open_file));
|
||||||
|
open_file.full_name = name;
|
||||||
|
|
||||||
files.append(open_file);
|
files.append(open_file);
|
||||||
});
|
});
|
||||||
return files;
|
return files;
|
||||||
|
@ -71,7 +113,7 @@ static Vector<OpenFile> get_open_files_by_pid(pid_t pid)
|
||||||
|
|
||||||
static void display_entry(const OpenFile& file, const Core::ProcessStatistics& statistics)
|
static void display_entry(const OpenFile& file, const Core::ProcessStatistics& statistics)
|
||||||
{
|
{
|
||||||
printf("%-28s %4d %4d %-10s %4d %s\n", statistics.name.characters(), file.pid, statistics.pgid, statistics.username.characters(), file.fd, file.name.characters());
|
printf("%-28s %4d %4d %-10s %4d %s\n", statistics.name.characters(), file.pid, statistics.pgid, statistics.username.characters(), file.fd, file.full_name.characters());
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
|
@ -106,11 +148,11 @@ int main(int argc, char* argv[])
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
arg_all_processes = true;
|
arg_all_processes = true;
|
||||||
else {
|
else {
|
||||||
parser.add_option(arg_pid, "Select PID", nullptr, 'p', "pid");
|
parser.add_option(arg_pid, "Select by PID", nullptr, 'p', "pid");
|
||||||
parser.add_option(arg_fd, "Select file descriptor", nullptr, 'd', "fd");
|
parser.add_option(arg_fd, "Select by file descriptor", nullptr, 'd', "fd");
|
||||||
parser.add_option(arg_uid, "Select login/UID", nullptr, 'u', "login/UID");
|
parser.add_option(arg_uid, "Select by login/UID", nullptr, 'u', "login/UID");
|
||||||
parser.add_option(arg_pgid, "Select process group ID", nullptr, 'g', "PGID");
|
parser.add_option(arg_pgid, "Select by process group ID", nullptr, 'g', "PGID");
|
||||||
parser.add_positional_argument(arg_file_name, "File name", "name", Core::ArgsParser::Required::No);
|
parser.add_positional_argument(arg_file_name, "File name", "file name", Core::ArgsParser::Required::No);
|
||||||
parser.parse(argc, argv);
|
parser.parse(argc, argv);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue