summaryrefslogtreecommitdiffstats
path: root/drivers/unix/dir_access_unix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/unix/dir_access_unix.cpp')
-rw-r--r--drivers/unix/dir_access_unix.cpp137
1 files changed, 112 insertions, 25 deletions
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index eda929850c..af47173b41 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -71,7 +71,7 @@ Error DirAccessUnix::list_dir_begin() {
bool DirAccessUnix::file_exists(String p_file) {
GLOBAL_LOCK_FUNCTION
- if (p_file.is_rel_path()) {
+ if (p_file.is_relative_path()) {
p_file = current_dir.plus_file(p_file);
}
@@ -90,7 +90,7 @@ bool DirAccessUnix::file_exists(String p_file) {
bool DirAccessUnix::dir_exists(String p_dir) {
GLOBAL_LOCK_FUNCTION
- if (p_dir.is_rel_path()) {
+ if (p_dir.is_relative_path()) {
p_dir = get_current_dir().plus_file(p_dir);
}
@@ -102,8 +102,30 @@ bool DirAccessUnix::dir_exists(String p_dir) {
return (success && S_ISDIR(flags.st_mode));
}
+bool DirAccessUnix::is_readable(String p_dir) {
+ GLOBAL_LOCK_FUNCTION
+
+ if (p_dir.is_relative_path()) {
+ p_dir = get_current_dir().plus_file(p_dir);
+ }
+
+ p_dir = fix_path(p_dir);
+ return (access(p_dir.utf8().get_data(), R_OK) == 0);
+}
+
+bool DirAccessUnix::is_writable(String p_dir) {
+ GLOBAL_LOCK_FUNCTION
+
+ if (p_dir.is_relative_path()) {
+ p_dir = get_current_dir().plus_file(p_dir);
+ }
+
+ p_dir = fix_path(p_dir);
+ return (access(p_dir.utf8().get_data(), W_OK) == 0);
+}
+
uint64_t DirAccessUnix::get_modified_time(String p_file) {
- if (p_file.is_rel_path()) {
+ if (p_file.is_relative_path()) {
p_file = current_dir.plus_file(p_file);
}
@@ -116,9 +138,9 @@ uint64_t DirAccessUnix::get_modified_time(String p_file) {
return flags.st_mtime;
} else {
ERR_FAIL_V(0);
- };
+ }
return 0;
-};
+}
String DirAccessUnix::get_next() {
if (!dir_stream) {
@@ -194,6 +216,8 @@ static bool _filter_drive(struct mntent *mnt) {
#endif
static void _get_drives(List<String> *list) {
+ list->push_back("/");
+
#if defined(HAVE_MNTENT) && defined(X11_ENABLED)
// Check /etc/mtab for the list of mounted partitions
FILE *mtab = setmntent("/etc/mtab", "r");
@@ -204,8 +228,9 @@ static void _get_drives(List<String> *list) {
while (getmntent_r(mtab, &mnt, strings, sizeof(strings))) {
if (mnt.mnt_dir != nullptr && _filter_drive(&mnt)) {
// Avoid duplicates
- if (!list->find(mnt.mnt_dir)) {
- list->push_back(mnt.mnt_dir);
+ String name = String::utf8(mnt.mnt_dir);
+ if (!list->find(name)) {
+ list->push_back(name);
}
}
}
@@ -218,8 +243,9 @@ static void _get_drives(List<String> *list) {
const char *home = getenv("HOME");
if (home) {
// Only add if it's not a duplicate
- if (!list->find(home)) {
- list->push_back(home);
+ String home_name = String::utf8(home);
+ if (!list->find(home_name)) {
+ list->push_back(home_name);
}
// Check $HOME/.config/gtk-3.0/bookmarks
@@ -232,7 +258,7 @@ static void _get_drives(List<String> *list) {
// Parse only file:// links
if (strncmp(string, "file://", 7) == 0) {
// Strip any unwanted edges on the strings and push_back if it's not a duplicate
- String fpath = String(string + 7).strip_edges().split_spaces()[0].uri_decode();
+ String fpath = String::utf8(string + 7).strip_edges().split_spaces()[0].uri_decode();
if (!list->find(fpath)) {
list->push_back(fpath);
}
@@ -262,6 +288,20 @@ String DirAccessUnix::get_drive(int p_drive) {
return list[p_drive];
}
+int DirAccessUnix::get_current_drive() {
+ int drive = 0;
+ int max_length = -1;
+ const String path = get_current_dir().to_lower();
+ for (int i = 0; i < get_drive_count(); i++) {
+ const String d = get_drive(i).to_lower();
+ if (max_length < d.length() && path.begins_with(d)) {
+ max_length = d.length();
+ drive = i;
+ }
+ }
+ return drive;
+}
+
bool DirAccessUnix::drives_are_shortcuts() {
return true;
}
@@ -269,7 +309,7 @@ bool DirAccessUnix::drives_are_shortcuts() {
Error DirAccessUnix::make_dir(String p_dir) {
GLOBAL_LOCK_FUNCTION
- if (p_dir.is_rel_path()) {
+ if (p_dir.is_relative_path()) {
p_dir = get_current_dir().plus_file(p_dir);
}
@@ -280,11 +320,11 @@ Error DirAccessUnix::make_dir(String p_dir) {
if (success) {
return OK;
- };
+ }
if (err == EEXIST) {
return ERR_ALREADY_EXISTS;
- };
+ }
return ERR_CANT_CREATE;
}
@@ -304,7 +344,7 @@ Error DirAccessUnix::change_dir(String p_dir) {
// try_dir is the directory we are trying to change into
String try_dir = "";
- if (p_dir.is_rel_path()) {
+ if (p_dir.is_relative_path()) {
String next_dir = current_dir.plus_file(p_dir);
next_dir = next_dir.simplify_path();
try_dir = next_dir;
@@ -318,7 +358,7 @@ Error DirAccessUnix::change_dir(String p_dir) {
}
String base = _get_root_path();
- if (base != String() && !try_dir.begins_with(base)) {
+ if (!base.is_empty() && !try_dir.begins_with(base)) {
ERR_FAIL_COND_V(getcwd(real_current_dir_name, 2048) == nullptr, ERR_BUG);
String new_dir;
new_dir.parse_utf8(real_current_dir_name);
@@ -336,7 +376,7 @@ Error DirAccessUnix::change_dir(String p_dir) {
String DirAccessUnix::get_current_dir(bool p_include_drive) {
String base = _get_root_path();
- if (base != "") {
+ if (!base.is_empty()) {
String bd = current_dir.replace_first(base, "");
if (bd.begins_with("/")) {
return _get_root_string() + bd.substr(1, bd.length());
@@ -348,13 +388,13 @@ String DirAccessUnix::get_current_dir(bool p_include_drive) {
}
Error DirAccessUnix::rename(String p_path, String p_new_path) {
- if (p_path.is_rel_path()) {
+ if (p_path.is_relative_path()) {
p_path = get_current_dir().plus_file(p_path);
}
p_path = fix_path(p_path);
- if (p_new_path.is_rel_path()) {
+ if (p_new_path.is_relative_path()) {
p_new_path = get_current_dir().plus_file(p_new_path);
}
@@ -364,7 +404,7 @@ Error DirAccessUnix::rename(String p_path, String p_new_path) {
}
Error DirAccessUnix::remove(String p_path) {
- if (p_path.is_rel_path()) {
+ if (p_path.is_relative_path()) {
p_path = get_current_dir().plus_file(p_path);
}
@@ -382,19 +422,66 @@ Error DirAccessUnix::remove(String p_path) {
}
}
-size_t DirAccessUnix::get_space_left() {
+bool DirAccessUnix::is_link(String p_file) {
+ if (p_file.is_relative_path()) {
+ p_file = get_current_dir().plus_file(p_file);
+ }
+
+ p_file = fix_path(p_file);
+
+ struct stat flags;
+ if ((lstat(p_file.utf8().get_data(), &flags) != 0)) {
+ return FAILED;
+ }
+
+ return S_ISLNK(flags.st_mode);
+}
+
+String DirAccessUnix::read_link(String p_file) {
+ if (p_file.is_relative_path()) {
+ p_file = get_current_dir().plus_file(p_file);
+ }
+
+ p_file = fix_path(p_file);
+
+ char buf[256];
+ memset(buf, 0, 256);
+ ssize_t len = readlink(p_file.utf8().get_data(), buf, sizeof(buf));
+ String link;
+ if (len > 0) {
+ link.parse_utf8(buf, len);
+ }
+ return link;
+}
+
+Error DirAccessUnix::create_link(String p_source, String p_target) {
+ if (p_target.is_relative_path()) {
+ p_target = get_current_dir().plus_file(p_target);
+ }
+
+ p_source = fix_path(p_source);
+ p_target = fix_path(p_target);
+
+ if (symlink(p_source.utf8().get_data(), p_target.utf8().get_data()) == 0) {
+ return OK;
+ } else {
+ return FAILED;
+ }
+}
+
+uint64_t DirAccessUnix::get_space_left() {
#ifndef NO_STATVFS
struct statvfs vfs;
if (statvfs(current_dir.utf8().get_data(), &vfs) != 0) {
return 0;
- };
+ }
- return vfs.f_bfree * vfs.f_bsize;
+ return (uint64_t)vfs.f_bavail * (uint64_t)vfs.f_frsize;
#else
// FIXME: Implement this.
return 0;
#endif
-};
+}
String DirAccessUnix::get_filesystem_type() const {
return ""; //TODO this should be implemented