Răsfoiți Sursa

Merge pull request #11160 from marcelofg55/drive_funcs_x11

Implemented DirAccess get_drive and get_drive_count for Linux
Rémi Verschelde 8 ani în urmă
părinte
comite
cc7c892bca
4 a modificat fișierele cu 106 adăugiri și 2 ștergeri
  1. 1 0
      .gitignore
  2. 12 0
      SConstruct
  3. 2 0
      drivers/unix/SCsub
  4. 91 2
      drivers/unix/dir_access_unix.cpp

+ 1 - 0
.gitignore

@@ -55,6 +55,7 @@ gmon.out
 .DS_Store
 
 # for projects that use SCons for building: http://http://www.scons.org/
+.sconf_temp
 .sconsign.dblite
 *.pyc
 

+ 12 - 0
SConstruct

@@ -290,7 +290,9 @@ if selected_platform in platform_list:
     if (env["warnings"] == 'yes'):
         print("WARNING: warnings=yes is deprecated; assuming warnings=all")
 
+    env.msvc = 0
     if (os.name == "nt" and os.getenv("VCINSTALLDIR") and (platform_arg == "windows" or platform_arg == "uwp")): # MSVC, needs to stand out of course
+        env.msvc = 1
         disable_nonessential_warnings = ['/wd4267', '/wd4244', '/wd4305', '/wd4800'] # Truncations, narrowing conversions...
         if (env["warnings"] == 'extra'):
             env.Append(CCFLAGS=['/Wall']) # Implies /W4
@@ -423,6 +425,16 @@ if selected_platform in platform_list:
     if (env['vsproj']) == "yes":
         methods.generate_vs_project(env, GetOption("num_jobs"))
 
+    # Check for the existence of headers
+    conf = Configure(env)
+    if ("check_c_headers" in env):
+        for header in env["check_c_headers"]:
+            if (conf.CheckCHeader(header[0])):
+                if (env.msvc):
+                    env.Append(CCFLAGS=['/D' + header[1]])
+                else:
+                    env.Append(CCFLAGS=['-D' + header[1]])
+
 else:
 
     print("No valid target platform selected.")

+ 2 - 0
drivers/unix/SCsub

@@ -14,4 +14,6 @@ f.close()
 
 env.add_source_files(env.drivers_sources, "*.cpp")
 
+env["check_c_headers"] = [ [ "mntent.h", "HAVE_MNTENT" ] ]
+
 Export('env')

+ 91 - 2
drivers/unix/dir_access_unix.cpp

@@ -35,10 +35,17 @@
 #include <sys/statvfs.h>
 #endif
 
+#include "core/list.h"
 #include "os/memory.h"
 #include "print_string.h"
 #include <errno.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_MNTENT
+#include <mntent.h>
+#endif
 
 DirAccess *DirAccessUnix::create_fs() {
 
@@ -176,13 +183,95 @@ void DirAccessUnix::list_dir_end() {
 	_cisdir = false;
 }
 
+#ifdef HAVE_MNTENT
+static bool _filter_drive(struct mntent *mnt) {
+	// Ignore devices that don't point to /dev
+	if (strncmp(mnt->mnt_fsname, "/dev", 4) != 0) {
+		return false;
+	}
+
+	// Accept devices mounted at /media, /mnt or /home
+	if (strncmp(mnt->mnt_dir, "/media", 6) == 0 ||
+			strncmp(mnt->mnt_dir, "/mnt", 4) == 0 ||
+			strncmp(mnt->mnt_dir, "/home", 5) == 0) {
+		return true;
+	}
+
+	// Ignore everything else
+	return false;
+}
+#endif
+
+static void _get_drives(List<String> *list) {
+
+#ifdef HAVE_MNTENT
+	// Check /etc/mtab for the list of mounted partitions
+	FILE *mtab = setmntent("/etc/mtab", "r");
+	if (mtab) {
+		struct mntent mnt;
+		char strings[4096];
+
+		while (getmntent_r(mtab, &mnt, strings, sizeof(strings))) {
+			if (mnt.mnt_dir != NULL && _filter_drive(&mnt)) {
+				// Avoid duplicates
+				if (!list->find(mnt.mnt_dir)) {
+					list->push_back(mnt.mnt_dir);
+				}
+			}
+		}
+
+		endmntent(mtab);
+	}
+#endif
+
+	// Add $HOME
+	const char *home = getenv("HOME");
+	if (home) {
+		// Only add if it's not a duplicate
+		if (!list->find(home)) {
+			list->push_back(home);
+		}
+
+		// Check $HOME/.config/gtk-3.0/bookmarks
+		char path[1024];
+		snprintf(path, 1024, "%s/.config/gtk-3.0/bookmarks", home);
+		FILE *fd = fopen(path, "r");
+		if (fd) {
+			char string[1024];
+			while (fgets(string, 1024, fd)) {
+				// 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();
+					if (!list->find(fpath)) {
+						list->push_back(fpath);
+					}
+				}
+			}
+
+			fclose(fd);
+		}
+	}
+
+	list->sort();
+}
+
 int DirAccessUnix::get_drive_count() {
 
-	return 0;
+	List<String> list;
+	_get_drives(&list);
+
+	return list.size();
 }
+
 String DirAccessUnix::get_drive(int p_drive) {
 
-	return "";
+	List<String> list;
+	_get_drives(&list);
+
+	ERR_FAIL_INDEX_V(p_drive, list.size(), "");
+
+	return list[p_drive];
 }
 
 Error DirAccessUnix::make_dir(String p_dir) {