diff --git a/Applications/FileManager/DirectoryTableModel.cpp b/Applications/FileManager/DirectoryTableModel.cpp index 757a00a62d..f610bcbecc 100644 --- a/Applications/FileManager/DirectoryTableModel.cpp +++ b/Applications/FileManager/DirectoryTableModel.cpp @@ -11,6 +11,7 @@ DirectoryTableModel::DirectoryTableModel() m_file_icon = GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/file16.rgb", { 16, 16 }); m_symlink_icon = GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/link16.rgb", { 16, 16 }); m_socket_icon = GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/socket16.rgb", { 16, 16 }); + m_executable_icon = GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/executable16.rgb", { 16, 16 }); } DirectoryTableModel::~DirectoryTableModel() @@ -63,6 +64,8 @@ const GraphicsBitmap& DirectoryTableModel::icon_for(const Entry& entry) const return *m_symlink_icon; if (S_ISSOCK(entry.mode)) return *m_socket_icon; + if (entry.mode & S_IXUSR) + return *m_executable_icon; return *m_file_icon; } @@ -173,8 +176,18 @@ void DirectoryTableModel::open(const String& path) void DirectoryTableModel::activate(const GModelIndex& index) { auto& entry = this->entry(index.row()); + FileSystemPath path(String::format("%s/%s", m_path.characters(), entry.name.characters())); if (entry.is_directory()) { - FileSystemPath new_path(String::format("%s/%s", m_path.characters(), entry.name.characters())); - open(new_path.string()); + open(path.string()); + return; + } + if (entry.is_executable()) { + if (fork() == 0) { + int rc = execl(path.string().characters(), path.string().characters(), nullptr); + if (rc < 0) + perror("exec"); + ASSERT_NOT_REACHED(); + } + return; } } diff --git a/Applications/FileManager/DirectoryTableModel.h b/Applications/FileManager/DirectoryTableModel.h index 661517d953..f5d8e65ae7 100644 --- a/Applications/FileManager/DirectoryTableModel.h +++ b/Applications/FileManager/DirectoryTableModel.h @@ -40,6 +40,7 @@ private: uid_t gid { 0 }; ino_t inode { 0 }; bool is_directory() const { return S_ISDIR(mode); } + bool is_executable() const { return mode & S_IXUSR; } }; const Entry& entry(int index) const @@ -59,4 +60,5 @@ private: RetainPtr m_file_icon; RetainPtr m_symlink_icon; RetainPtr m_socket_icon; + RetainPtr m_executable_icon; }; diff --git a/Base/res/icons/executable16.png b/Base/res/icons/executable16.png new file mode 100644 index 0000000000..8de7113e14 Binary files /dev/null and b/Base/res/icons/executable16.png differ diff --git a/Base/res/icons/executable16.rgb b/Base/res/icons/executable16.rgb new file mode 100644 index 0000000000..d6232a6530 Binary files /dev/null and b/Base/res/icons/executable16.rgb differ