[PATCH] xfree86: support multiple sysconfigdir paths

Aaron Plattner aplattner at nvidia.com
Thu Jul 10 16:04:40 PDT 2014


When the X server is compiled with --prefix set to something other than /usr,
then it ends up with a nonstandard sysconfigdir in its .pc file.  This causes
various other components to install their xorg.conf.d snippets there.

However, the X server first looks for /usr/share/X11/xorg.conf.d before looking
in sysconfigdir.  That means that if the system administrator installed anything
that created that path, the user's custom sysconfigdir is not searched.

Modify OpenConfigDir to scan for config files in all of the directories in
SYS_CONFIGDIRPATH, rather than only looking in the first one that exists.  Build
the search path string based on the directories it finds.

Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
---
An alternative would be to just drop the /usr/share/X11/%X hardcode and always
look only in %D/X11/%X.

 hw/xfree86/common/xf86Config.c | 14 +++++-----
 hw/xfree86/parser/scan.c       | 62 +++++++++++++++++++++++++++++++++++-------
 2 files changed, 59 insertions(+), 17 deletions(-)

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 481674de2955..49344ef8a471 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -2372,7 +2372,7 @@ xf86HandleConfigFile(Bool autoconfig)
     XF86ConfLayoutPtr layout;
 
     if (!autoconfig) {
-        char *filename, *dirname, *sysdirname;
+        char *filename, *dirname, *sysdirpath;
         const char *filesearch, *dirsearch;
         MessageType filefrom = X_DEFAULT;
         MessageType dirfrom = X_DEFAULT;
@@ -2392,7 +2392,7 @@ xf86HandleConfigFile(Bool autoconfig)
             dirfrom = X_CMDLINE;
 
         xf86initConfigFiles();
-        sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL,
+        sysdirpath = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL,
                                             PROJECTROOT);
         dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT);
         filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT);
@@ -2416,15 +2416,15 @@ xf86HandleConfigFile(Bool autoconfig)
                         "Unable to locate/open config directory: \"%s\"\n",
                         xf86ConfigDir);
         }
-        if (sysdirname)
-            xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n",
-                        sysdirname);
-        if (!filename && !dirname && !sysdirname)
+        if (sysdirpath)
+            xf86MsgVerb(X_DEFAULT, 0, "Using system config directory search "
+                        "path \"%s\"\n", sysdirpath);
+        if (!filename && !dirname && !sysdirpath)
             return CONFIG_NOFILE;
 
         free(filename);
         free(dirname);
-        free(sysdirname);
+        free(sysdirpath);
     }
 
     if ((xf86configptr = xf86readConfigFile()) == NULL) {
diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c
index a6c12957b5db..08784abb27d5 100644
--- a/hw/xfree86/parser/scan.c
+++ b/hw/xfree86/parser/scan.c
@@ -786,6 +786,7 @@ AddConfigDirFiles(const char *dirpath, struct dirent **list, int num)
     for (i = 0; i < num; i++) {
         char *path;
         FILE *file;
+        int j;
 
         if (numFiles >= CONFIG_MAX_FILES) {
             if (!warnOnce) {
@@ -797,6 +798,18 @@ AddConfigDirFiles(const char *dirpath, struct dirent **list, int num)
 
         path = malloc(PATH_MAX + 1);
         snprintf(path, PATH_MAX + 1, "%s/%s", dirpath, list[i]->d_name);
+
+        /*
+         * Check if this config file was already opened. This can happen if the
+         * same config directory is scanned twice.
+         */
+        for (j = 0; j < numFiles; j++) {
+            if (!strcmp(configFiles[j].path, path)) {
+                free(path);
+                return 0;
+            }
+        }
+
         file = fopen(path, "r");
         if (!file) {
             free(path);
@@ -812,23 +825,40 @@ AddConfigDirFiles(const char *dirpath, struct dirent **list, int num)
     return openedFile;
 }
 
+static char *
+reallocStrCat(char *str, const char *append)
+{
+    if (str) {
+        size_t newlen = strlen(str) + strlen(append) + 1;
+        char *newstr = realloc(str, newlen);
+
+        if (newstr) {
+            strcat(newstr, append);
+        }
+
+        return newstr;
+    } else {
+        return strdup(append);
+    }
+}
+
 /*
  * Given some searching parameters, locate and open the xorg config
- * directory. The directory does not need to contain config files.
+ * directories. The directories do not need to contain config files.
  */
 static char *
 OpenConfigDir(const char *path, const char *cmdline, const char *projroot,
               const char *confname)
 {
-    char *dirpath = NULL, *pathcopy;
+    char *searchpath = NULL, *pathcopy;
     const char *template;
-    Bool found = FALSE;
     int cmdlineUsed = 0;
 
     pathcopy = strdup(path);
-    for (template = strtok(pathcopy, ","); template && !found;
+    for (template = strtok(pathcopy, ","); template;
          template = strtok(NULL, ",")) {
         struct dirent **list = NULL;
+        char *dirpath;
         int num;
 
         dirpath = DoSubstitution(template, cmdline, projroot,
@@ -847,18 +877,30 @@ OpenConfigDir(const char *path, const char *cmdline, const char *projroot,
             list = NULL;
             num = 0;
         }
-        found = AddConfigDirFiles(dirpath, list, num);
-        if (!found) {
-            free(dirpath);
-            dirpath = NULL;
+        if (AddConfigDirFiles(dirpath, list, num)) {
+            /* append dirpath to the search path string */
+            char *newstr;
+
+            if (searchpath) {
+                newstr = reallocStrCat(searchpath, ",");
+                if (newstr) {
+                    searchpath = newstr;
+                }
+            }
+
+            newstr = reallocStrCat(searchpath, dirpath);
+            if (newstr)
+                searchpath = newstr;
+
         }
+        free(dirpath);
         while (num--)
             free(list[num]);
         free(list);
     }
 
     free(pathcopy);
-    return dirpath;
+    return searchpath;
 }
 
 /*
@@ -947,7 +989,7 @@ xf86openConfigDirFiles(const char *path, const char *cmdline,
     if (!projroot || !projroot[0])
         projroot = PROJECTROOT;
 
-    /* Search for the multiconf directory */
+    /* Search for the multiconf directories */
     return OpenConfigDir(path, cmdline, projroot, XCONFIGDIR);
 }
 
-- 
2.0.1



More information about the xorg-devel mailing list