diff options
author | Maciej Zygmanowski <sppmacd@pm.me> | 2020-09-26 17:58:58 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-09-26 21:23:58 +0200 |
commit | dd682168a97cc6c32b10b6df2b617130fa42c8b3 (patch) | |
tree | 067b17911f3a9162bda9edc956646f72f9234b06 /Userland/lsof.cpp | |
parent | 2ed0385075df3c157f801190da0b00ecee6b4f17 (diff) | |
download | serenity-dd682168a97cc6c32b10b6df2b617130fa42c8b3.zip |
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).
Diffstat (limited to 'Userland/lsof.cpp')
-rw-r--r-- | Userland/lsof.cpp | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/Userland/lsof.cpp b/Userland/lsof.cpp index 838c6ff592..94cd4047c9 100644 --- a/Userland/lsof.cpp +++ b/Userland/lsof.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <AK/GenericLexer.h> #include <AK/HashMap.h> #include <AK/JsonArray.h> #include <AK/JsonObject.h> @@ -39,9 +40,46 @@ struct OpenFile { int fd; int pid; + String type; 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) { 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; open_file.pid = pid; 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); }); 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) { - 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[]) @@ -106,11 +148,11 @@ int main(int argc, char* argv[]) if (argc == 1) arg_all_processes = true; else { - parser.add_option(arg_pid, "Select PID", nullptr, 'p', "pid"); - parser.add_option(arg_fd, "Select file descriptor", nullptr, 'd', "fd"); - parser.add_option(arg_uid, "Select login/UID", nullptr, 'u', "login/UID"); - parser.add_option(arg_pgid, "Select process group ID", nullptr, 'g', "PGID"); - parser.add_positional_argument(arg_file_name, "File name", "name", Core::ArgsParser::Required::No); + parser.add_option(arg_pid, "Select by PID", nullptr, 'p', "pid"); + parser.add_option(arg_fd, "Select by file descriptor", nullptr, 'd', "fd"); + parser.add_option(arg_uid, "Select by login/UID", nullptr, 'u', "login/UID"); + parser.add_option(arg_pgid, "Select by process group ID", nullptr, 'g', "PGID"); + parser.add_positional_argument(arg_file_name, "File name", "file name", Core::ArgsParser::Required::No); parser.parse(argc, argv); } { |