summaryrefslogtreecommitdiff
path: root/lib/mesa/src/util/xmlconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mesa/src/util/xmlconfig.c')
-rw-r--r--lib/mesa/src/util/xmlconfig.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/lib/mesa/src/util/xmlconfig.c b/lib/mesa/src/util/xmlconfig.c
index dde6e5fa0..a824f2f1a 100644
--- a/lib/mesa/src/util/xmlconfig.c
+++ b/lib/mesa/src/util/xmlconfig.c
@@ -15,11 +15,11 @@
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
+ *
*/
/**
* \file xmlconfig.c
@@ -272,7 +272,7 @@ findOption(const driOptionCache *cache, const char *name)
/* this is just the starting point of the linear search for the option */
for (i = 0; i < size; ++i, hash = (hash+1) & mask) {
/* if we hit an empty entry then the option is not defined (yet) */
- if (cache->info[hash].name == 0)
+ if (cache->info[hash].name == NULL)
break;
else if (!strcmp(name, cache->info[hash].name))
break;
@@ -320,7 +320,7 @@ driParseOptionInfo(driOptionCache *info,
/* Make the hash table big enough to fit more than the maximum number of
* config options we've ever seen in a driver.
*/
- info->tableSize = 6;
+ info->tableSize = 7;
info->info = calloc((size_t)1 << info->tableSize, sizeof(driOptionInfo));
info->values = calloc((size_t)1 << info->tableSize, sizeof(driOptionValue));
if (info->info == NULL || info->values == NULL) {
@@ -681,6 +681,7 @@ parseAppAttr(struct OptConfData *data, const char **attr)
uint32_t i;
const char *exec = NULL;
const char *sha1 = NULL;
+ const char *exec_regexp = NULL;
const char *application_name_match = NULL;
const char *application_versions = NULL;
driOptionInfo version_range = {
@@ -690,6 +691,7 @@ parseAppAttr(struct OptConfData *data, const char **attr)
for (i = 0; attr[i]; i += 2) {
if (!strcmp(attr[i], "name")) /* not needed here */;
else if (!strcmp(attr[i], "executable")) exec = attr[i+1];
+ else if (!strcmp(attr[i], "executable_regexp")) exec_regexp = attr[i+1];
else if (!strcmp(attr[i], "sha1")) sha1 = attr[i+1];
else if (!strcmp(attr[i], "application_name_match"))
application_name_match = attr[i+1];
@@ -699,6 +701,15 @@ parseAppAttr(struct OptConfData *data, const char **attr)
}
if (exec && strcmp(exec, data->execName)) {
data->ignoringApp = data->inApp;
+ } else if (exec_regexp) {
+ regex_t re;
+
+ if (regcomp(&re, exec_regexp, REG_EXTENDED|REG_NOSUB) == 0) {
+ if (regexec(&re, data->execName, 0, NULL, 0) == REG_NOMATCH)
+ data->ignoringApp = data->inApp;
+ regfree(&re);
+ } else
+ XML_WARNING("Invalid executable_regexp=\"%s\".", exec_regexp);
} else if (sha1) {
/* SHA1_DIGEST_STRING_LENGTH includes terminating null byte */
if (strlen(sha1) != (SHA1_DIGEST_STRING_LENGTH - 1)) {
@@ -998,7 +1009,10 @@ scandir_filter(const struct dirent *ent)
(!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)))
return 0;
#else
- if (ent->d_type != DT_REG && ent->d_type != DT_LNK)
+ /* Allow through unknown file types for filesystems that don't support d_type
+ * The full filepath isn't available here to stat the file
+ */
+ if (ent->d_type != DT_REG && ent->d_type != DT_LNK && ent->d_type != DT_UNKNOWN)
return 0;
#endif
@@ -1022,10 +1036,26 @@ parseConfigDir(struct OptConfData *data, const char *dirname)
for (i = 0; i < count; i++) {
char filename[PATH_MAX];
+#ifdef DT_REG
+ unsigned char d_type = entries[i]->d_type;
+#endif
snprintf(filename, PATH_MAX, "%s/%s", dirname, entries[i]->d_name);
free(entries[i]);
+#ifdef DT_REG
+ /* In the case of unknown d_type, ensure it is a regular file
+ * This can be accomplished with stat on the full filepath
+ */
+ if (d_type == DT_UNKNOWN) {
+ struct stat st;
+ if (stat(filename, &st) != 0 ||
+ !S_ISREG(st.st_mode)) {
+ continue;
+ }
+ }
+#endif
+
parseOneConfigFile(data, filename);
}