summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Applications/FileManager/PropertiesWindow.cpp5
-rw-r--r--Userland/Libraries/LibCore/File.cpp20
-rw-r--r--Userland/Libraries/LibCore/File.h2
-rw-r--r--Userland/Libraries/LibGUI/FileIconProvider.cpp6
-rw-r--r--Userland/Libraries/LibGUI/FileSystemModel.cpp6
-rw-r--r--Userland/Services/LaunchServer/Launcher.cpp6
-rw-r--r--Userland/Utilities/ls.cpp6
-rw-r--r--Userland/Utilities/readlink.cpp6
8 files changed, 36 insertions, 21 deletions
diff --git a/Userland/Applications/FileManager/PropertiesWindow.cpp b/Userland/Applications/FileManager/PropertiesWindow.cpp
index ac83c0986f..45a6012f10 100644
--- a/Userland/Applications/FileManager/PropertiesWindow.cpp
+++ b/Userland/Applications/FileManager/PropertiesWindow.cpp
@@ -95,10 +95,11 @@ PropertiesWindow::PropertiesWindow(String const& path, bool disable_rename, Wind
};
if (S_ISLNK(m_mode)) {
- auto link_destination = Core::File::read_link(path);
- if (link_destination.is_null()) {
+ auto link_destination_or_error = Core::File::read_link(path);
+ if (link_destination_or_error.is_error()) {
perror("readlink");
} else {
+ auto link_destination = link_destination_or_error.release_value();
auto link_location = general_tab.find_descendant_of_type_named<GUI::LinkLabel>("link_location");
link_location->set_text(link_destination);
link_location->on_click = [link_destination] {
diff --git a/Userland/Libraries/LibCore/File.cpp b/Userland/Libraries/LibCore/File.cpp
index 9ae04bc028..811a50dd44 100644
--- a/Userland/Libraries/LibCore/File.cpp
+++ b/Userland/Libraries/LibCore/File.cpp
@@ -247,28 +247,28 @@ String File::absolute_path(String const& path)
#ifdef __serenity__
-String File::read_link(String const& link_path)
+ErrorOr<String> File::read_link(String const& link_path)
{
// First, try using a 64-byte buffer, that ought to be enough for anybody.
char small_buffer[64];
int rc = serenity_readlink(link_path.characters(), link_path.length(), small_buffer, sizeof(small_buffer));
if (rc < 0)
- return {};
+ return Error::from_errno(errno);
size_t size = rc;
// If the call was successful, the syscall (unlike the LibC wrapper)
// returns the full size of the link. Let's see if our small buffer
// was enough to read the whole link.
if (size <= sizeof(small_buffer))
- return { small_buffer, size };
+ return String { small_buffer, size };
// Nope, but at least now we know the right size.
char* large_buffer_ptr;
auto large_buffer = StringImpl::create_uninitialized(size, large_buffer_ptr);
rc = serenity_readlink(link_path.characters(), link_path.length(), large_buffer_ptr, size);
if (rc < 0)
- return {};
+ return Error::from_errno(errno);
size_t new_size = rc;
if (new_size == size)
@@ -277,31 +277,31 @@ String File::read_link(String const& link_path)
// If we're here, the symlink has changed while we were looking at it.
// If it became shorter, our buffer is valid, we just have to trim it a bit.
if (new_size < size)
- return { large_buffer_ptr, new_size };
+ return String { large_buffer_ptr, new_size };
// Otherwise, here's not much we can do, unless we want to loop endlessly
// in this case. Let's leave it up to the caller whether to loop.
errno = EAGAIN;
- return {};
+ return Error::from_errno(errno);
}
#else
// This is a sad version for other systems. It has to always make a copy of the
// link path, and to always make two syscalls to get the right size first.
-String File::read_link(String const& link_path)
+ErrorOr<String> File::read_link(String const& link_path)
{
struct stat statbuf = {};
int rc = lstat(link_path.characters(), &statbuf);
if (rc < 0)
- return {};
+ return Error::from_errno(errno);
char* buffer_ptr;
auto buffer = StringImpl::create_uninitialized(statbuf.st_size, buffer_ptr);
if (readlink(link_path.characters(), buffer_ptr, statbuf.st_size) < 0)
- return {};
+ return Error::from_errno(errno);
// (See above.)
if (rc == statbuf.st_size)
return { *buffer };
- return { buffer_ptr, (size_t)rc };
+ return String { buffer_ptr, (size_t)rc };
}
#endif
diff --git a/Userland/Libraries/LibCore/File.h b/Userland/Libraries/LibCore/File.h
index 146a3ae239..43fe19ebfc 100644
--- a/Userland/Libraries/LibCore/File.h
+++ b/Userland/Libraries/LibCore/File.h
@@ -76,7 +76,7 @@ public:
static ErrorOr<void, CopyError> copy_file_or_directory(String const& dst_path, String const& src_path, RecursionMode = RecursionMode::Allowed, LinkMode = LinkMode::Disallowed, AddDuplicateFileMarker = AddDuplicateFileMarker::Yes, PreserveMode = PreserveMode::Nothing);
static String real_path_for(String const& filename);
- static String read_link(String const& link_path);
+ static ErrorOr<String> read_link(String const& link_path);
static ErrorOr<void> link_file(String const& dst_path, String const& src_path);
struct RemoveError : public Error {
diff --git a/Userland/Libraries/LibGUI/FileIconProvider.cpp b/Userland/Libraries/LibGUI/FileIconProvider.cpp
index 27c4b4fa03..821af95491 100644
--- a/Userland/Libraries/LibGUI/FileIconProvider.cpp
+++ b/Userland/Libraries/LibGUI/FileIconProvider.cpp
@@ -232,7 +232,11 @@ Icon FileIconProvider::icon_for_path(const String& path, mode_t mode)
return s_directory_icon;
}
if (S_ISLNK(mode)) {
- auto raw_symlink_target = Core::File::read_link(path);
+ auto raw_symlink_target_or_error = Core::File::read_link(path);
+ if (raw_symlink_target_or_error.is_error())
+ return s_symlink_icon;
+
+ auto raw_symlink_target = raw_symlink_target_or_error.release_value();
if (raw_symlink_target.is_null())
return s_symlink_icon;
diff --git a/Userland/Libraries/LibGUI/FileSystemModel.cpp b/Userland/Libraries/LibGUI/FileSystemModel.cpp
index 1bf7fbcc04..f4f9cfe364 100644
--- a/Userland/Libraries/LibGUI/FileSystemModel.cpp
+++ b/Userland/Libraries/LibGUI/FileSystemModel.cpp
@@ -61,7 +61,11 @@ bool FileSystemModel::Node::fetch_data(String const& full_path, bool is_root)
mtime = st.st_mtime;
if (S_ISLNK(mode)) {
- symlink_target = Core::File::read_link(full_path);
+ auto sym_link_target_or_error = Core::File::read_link(full_path);
+ if (sym_link_target_or_error.is_error())
+ perror("readlink");
+
+ symlink_target = sym_link_target_or_error.release_value();
if (symlink_target.is_null())
perror("readlink");
}
diff --git a/Userland/Services/LaunchServer/Launcher.cpp b/Userland/Services/LaunchServer/Launcher.cpp
index 09fa6d496b..a7bedbb473 100644
--- a/Userland/Services/LaunchServer/Launcher.cpp
+++ b/Userland/Services/LaunchServer/Launcher.cpp
@@ -271,7 +271,11 @@ void Launcher::for_each_handler_for_path(const String& path, Function<bool(const
return;
if (S_ISLNK(st.st_mode)) {
- auto link_target = LexicalPath { Core::File::read_link(path) };
+ auto link_target_or_error = Core::File::read_link(path);
+ if (link_target_or_error.is_error())
+ perror("read_link");
+
+ auto link_target = LexicalPath { link_target_or_error.release_value() };
LexicalPath absolute_link_target = link_target.is_absolute() ? link_target : LexicalPath::join(LexicalPath::dirname(path), link_target.string());
auto real_path = Core::File::real_path_for(absolute_link_target.string());
return for_each_handler_for_path(real_path, [&](const auto& handler) -> bool {
diff --git a/Userland/Utilities/ls.cpp b/Userland/Utilities/ls.cpp
index 30fa3a9a96..be1b551cb5 100644
--- a/Userland/Utilities/ls.cpp
+++ b/Userland/Utilities/ls.cpp
@@ -275,11 +275,11 @@ static size_t print_name(const struct stat& st, const String& name, const char*
}
if (S_ISLNK(st.st_mode)) {
if (path_for_link_resolution) {
- auto link_destination = Core::File::read_link(path_for_link_resolution);
- if (link_destination.is_null()) {
+ auto link_destination_or_error = Core::File::read_link(path_for_link_resolution);
+ if (link_destination_or_error.is_error()) {
perror("readlink");
} else {
- nprinted += printf(" -> ") + print_escaped(link_destination.characters());
+ nprinted += printf(" -> ") + print_escaped(link_destination_or_error.value().characters());
}
} else {
if (flag_classify)
diff --git a/Userland/Utilities/readlink.cpp b/Userland/Utilities/readlink.cpp
index 318e31ac1a..53c7a25d2d 100644
--- a/Userland/Utilities/readlink.cpp
+++ b/Userland/Utilities/readlink.cpp
@@ -25,11 +25,13 @@ int main(int argc, char** argv)
args_parser.parse(argc, argv);
for (const char* path : paths) {
- auto destination = Core::File::read_link(path);
- if (destination.is_null()) {
+ auto destination_or_error = Core::File::read_link(path);
+ if (destination_or_error.is_error()) {
perror(path);
return 1;
}
+
+ auto destination = destination_or_error.release_value();
out("{}", destination);
if (!no_newline)
outln();