Browse Source

Merge pull request #109383 from bruvzg/link_back_save

[Unix] Replace symlink target, not the link itself when using backup save mode.
Thaddeus Crews 3 weeks ago
parent
commit
bbafe862f5
3 changed files with 29 additions and 7 deletions
  1. 4 4
      drivers/unix/dir_access_unix.cpp
  2. 23 1
      drivers/unix/file_access_unix.cpp
  3. 2 2
      drivers/unix/os_unix.cpp

+ 4 - 4
drivers/unix/dir_access_unix.cpp

@@ -437,7 +437,7 @@ Error DirAccessUnix::remove(String p_path) {
 	}
 
 	struct stat flags = {};
-	if ((lstat(p_path.utf8().get_data(), &flags) != 0)) {
+	if (lstat(p_path.utf8().get_data(), &flags) != 0) {
 		return FAILED;
 	}
 
@@ -467,7 +467,7 @@ bool DirAccessUnix::is_link(String p_file) {
 	}
 
 	struct stat flags = {};
-	if ((lstat(p_file.utf8().get_data(), &flags) != 0)) {
+	if (lstat(p_file.utf8().get_data(), &flags) != 0) {
 		return false;
 	}
 
@@ -484,8 +484,8 @@ String DirAccessUnix::read_link(String p_file) {
 		p_file = p_file.left(-1);
 	}
 
-	char buf[256];
-	memset(buf, 0, 256);
+	char buf[PATH_MAX];
+	memset(buf, 0, PATH_MAX);
 	ssize_t len = readlink(p_file.utf8().get_data(), buf, sizeof(buf));
 	String link;
 	if (len > 0) {

+ 23 - 1
drivers/unix/file_access_unix.cpp

@@ -117,7 +117,29 @@ Error FileAccessUnix::open_internal(const String &p_path, int p_mode_flags) {
 #endif
 
 	if (is_backup_save_enabled() && (p_mode_flags == WRITE)) {
-		save_path = path;
+		// Set save path to the symlink target, not the link itself.
+		String link;
+		bool is_link = false;
+		{
+			CharString cs = path.utf8();
+			struct stat lst = {};
+			if (lstat(cs.get_data(), &lst) == 0) {
+				is_link = S_ISLNK(lst.st_mode);
+			}
+			if (is_link) {
+				char buf[PATH_MAX];
+				memset(buf, 0, PATH_MAX);
+				ssize_t len = readlink(cs.get_data(), buf, sizeof(buf));
+				if (len > 0) {
+					link.append_utf8(buf, len);
+				}
+				if (!link.is_absolute_path()) {
+					link = path.get_base_dir().path_join(link);
+				}
+			}
+		}
+		save_path = is_link ? link : path;
+
 		// Create a temporary file in the same directory as the target file.
 		path = path + "-XXXXXX";
 		CharString cs = path.utf8();

+ 2 - 2
drivers/unix/os_unix.cpp

@@ -1130,8 +1130,8 @@ String OS_Unix::get_user_data_dir(const String &p_user_dir) const {
 String OS_Unix::get_executable_path() const {
 #ifdef __linux__
 	//fix for running from a symlink
-	char buf[256];
-	memset(buf, 0, 256);
+	char buf[PATH_MAX];
+	memset(buf, 0, PATH_MAX);
 	ssize_t len = readlink("/proc/self/exe", buf, sizeof(buf));
 	String b;
 	if (len > 0) {