Use XDG basedir spec on Linux

Open
#76 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Stale
Tech stack
cpp, java

Research direction

Start with java/zylib/src/main/java/com/google/security/zynamics/zylib/system/SystemHelpers.java and util/process.cc, then compare the proposed paths with the XDG Base Directory Specification. Review the existing comments to resolve the remaining behavior details, and update both implementations consistently once the Linux data and common-directory behavior is agreed.

Written by the indexing model from the issue text.

Description

enhancement

https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html

Why: we already use the equivalents on other platforms (Application Support, AppData, etc.) on other platforms. This behavior could be aligned on Linux. seealso: https://xdgbasedirectoryspecification.com/

Code below is attached to explain the new logic and I will make a PR once we finalize the behavior details. See the comments for further discussion.

Details

diff --git a/java/zylib/src/main/java/com/google/security/zynamics/zylib/system/SystemHelpers.java b/java/zylib/src/main/java/com/google/security/zynamics/zylib/system/SystemHelpers.java
index aa8754b9..eddf021c 100644
--- a/java/zylib/src/main/java/com/google/security/zynamics/zylib/system/SystemHelpers.java
+++ b/java/zylib/src/main/java/com/google/security/zynamics/zylib/system/SystemHelpers.java
@@ -38,7 +38,7 @@ public final class SystemHelpers {
       // Win32 function.
       result = System.getenv("ProgramData");
     } else if (isRunningLinux()) {
-      result = "/etc/opt";
+      result = "/etc/xdg";
     } else if (isRunningMacOSX()) {
       result = "/Library/Application Support";
     } else {
@@ -76,9 +76,15 @@ public final class SystemHelpers {
       // function.
       result = System.getenv("APPDATA");
     } else {
-      result = System.getProperty("user.home");
-      if (isRunningMacOSX()) {
-        result += "/Library/Application Support";
+      result = System.getenv("XDG_DATA_HOME");
+      if (result == null || !result.startsWith("/")) {
+        result = System.getProperty("user.home");
+        if (isRunningLinux()) {
+            result += "/.local/share";
+        }
+        if (isRunningMacOSX()) { // Since there isn't a standard way to get this path on macOS (at least I'm not aware of), should we also put this codepath in here?
+          result += "/Library/Application Support";
+        }
       }
     }
     return FileUtils.ensureTrailingSlash(result);
@@ -93,7 +99,7 @@ public final class SystemHelpers {
    */
   public static String getApplicationDataDirectory(final String product) {
     return getApplicationDataDirectory()
-        + (isRunningLinux() ? "." + product.toLowerCase() : product)
+        + (isRunningLinux() ? product.toLowerCase() : product)
         + File.separator;
   }
 
diff --git a/util/process.cc b/util/process.cc
index 6fdeb42..bc46b04 100644
--- a/util/process.cc
+++ b/util/process.cc
@@ -241,15 +241,25 @@ absl::StatusOr<std::string> GetOrCreateAppDataDirectory(
     absl::string_view product_name) {
   std::string path;
 #ifndef _WIN32
-  const char* home_dir = getenv("HOME");
-  if (!home_dir) {
-    return absl::NotFoundError("Home directory not set");
+  std::string data_home;
+  const char* data_home_env = getenv("XDG_DATA_HOME");
+  if (data_home_env && data_home_env[0] == '/') {
+    data_home = data_home_env;
+  } else {
+    const char* home_dir = getenv("HOME");
+    if (!home_dir) {
+      return absl::NotFoundError("Home directory not set");
+    }
+#ifdef __APPLE__
+    data_home = JoinPath(home_dir, "Library", "Application Support");
+#else
+    data_home = JoinPath(home_dir, ".local", "share");
+#endif  // __APPLE__
   }
 #ifdef __APPLE__
-  path = JoinPath(home_dir, "Library", "Application Support", product_name);
+  path = JoinPath(data_home, product_name);
 #else
-  path = JoinPath(home_dir,
-                  absl::StrCat(".", absl::AsciiStrToLower(product_name)));
+  path = JoinPath(data_home, absl::AsciiStrToLower(product_name));
 #endif  // __APPLE__
 #else
   char buffer[MAX_PATH] = {0};
@@ -270,7 +280,7 @@ absl::StatusOr<std::string> GetCommonAppDataDirectory(
 #ifdef __APPLE__
   path = JoinPath("/Library", "Application Support", product_name);
 #else
-  path = JoinPath("/etc/opt/", absl::AsciiStrToLower(product_name));
+  path = JoinPath("/etc", "xdg", absl::AsciiStrToLower(product_name));
 #endif  // __APPLE__
 #else
   char buffer[MAX_PATH] = {0};

Dominant language
Java
Stars
3.2k
Forks
240
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from google/bindiff

All issues in google/bindiff

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.