|
8 | 8 | #include <stdio.h> |
9 | 9 | #include <stdint.h> |
10 | 10 | #include <string.h> |
| 11 | +#include <regex.h> |
11 | 12 | #include <errno.h> |
12 | 13 | #include <err.h> |
13 | 14 |
|
@@ -36,30 +37,89 @@ struct visit_data { |
36 | 37 | char *outbuf; |
37 | 38 | }; |
38 | 39 |
|
39 | | -static int in_list(const char *list, const char delim, const char *value) |
| 40 | +static int in_envvar(const char *envname, const char *filename, const char *value) |
40 | 41 | { |
41 | | - const char *s, *e, *p; |
| 42 | + const char *s, *e, *p, *list, *sep, *file_regex, *word; |
| 43 | + size_t sz, file_regex_sz, word_sz, buf_sz; |
| 44 | + char *buf, *new; |
| 45 | + int ret; |
42 | 46 |
|
43 | | - if (!list) |
| 47 | + int regex_err; |
| 48 | + regex_t regex = { 0 }; |
| 49 | + |
| 50 | + if (!(list = getenv(envname))) |
44 | 51 | return 0; |
45 | 52 |
|
| 53 | + ret = 0; |
| 54 | + |
| 55 | + buf = NULL; |
| 56 | + buf_sz = 0; |
| 57 | + |
46 | 58 | s = p = list; |
47 | 59 | e = s + strlen(s); |
48 | 60 |
|
49 | | - while (p < e) { |
50 | | - p = strchr(s, delim); |
51 | | - if (!p) |
| 61 | + for (; p < e; s = p + 1) { |
| 62 | + if (!(p = strchr(s, ','))) |
52 | 63 | p = e + 1; |
53 | | - if (!strncmp(s, value, (size_t)(p - s))) |
54 | | - return 1; |
55 | | - s = p + 1; |
| 64 | + |
| 65 | + sz = (size_t) (p - s); |
| 66 | + |
| 67 | + if ((sep = memchr(s, ':', sz)) != NULL) { |
| 68 | + file_regex = s; |
| 69 | + file_regex_sz = (size_t) (sep - file_regex); |
| 70 | + |
| 71 | + word = sep + 1; |
| 72 | + word_sz = sz - file_regex_sz - 1; |
| 73 | + } else { |
| 74 | + file_regex = NULL; |
| 75 | + file_regex_sz = 0; |
| 76 | + |
| 77 | + word = s; |
| 78 | + word_sz = sz; |
| 79 | + } |
| 80 | + |
| 81 | + if (file_regex) { |
| 82 | + // Release the previous regex if any. |
| 83 | + regfree(®ex); |
| 84 | + |
| 85 | + // Add place for null-byte. |
| 86 | + file_regex_sz += 1; |
| 87 | + |
| 88 | + if (buf_sz < file_regex_sz) { |
| 89 | + buf_sz = file_regex_sz * 2; |
| 90 | + |
| 91 | + if (!(new = realloc(buf, buf_sz))) { |
| 92 | + warn("realloc"); |
| 93 | + break; |
| 94 | + } |
| 95 | + buf = new; |
| 96 | + } |
| 97 | + |
| 98 | + strlcpy(buf, file_regex, file_regex_sz); |
| 99 | + |
| 100 | + if ((regex_err = regcomp(®ex, buf, REG_NOSUB | REG_EXTENDED)) != 0) { |
| 101 | + char errbuf[BUFSIZ]; |
| 102 | + |
| 103 | + regerror(regex_err, ®ex, errbuf, sizeof(errbuf)); |
| 104 | + |
| 105 | + warnx("in_envvar: bad regex: %s", errbuf); |
| 106 | + continue; |
| 107 | + } |
| 108 | + |
| 109 | + if (regexec(®ex, filename, 0, NULL, 0) == REG_NOMATCH) |
| 110 | + continue; |
| 111 | + } |
| 112 | + |
| 113 | + if (!strncmp(word, value, word_sz)) { |
| 114 | + ret = 1; |
| 115 | + break; |
| 116 | + } |
56 | 117 | } |
57 | | - return 0; |
58 | | -} |
59 | 118 |
|
60 | | -static int in_envvar(const char *envname, const char *value) |
61 | | -{ |
62 | | - return in_list(getenv(envname), ',', value); |
| 119 | + regfree(®ex); |
| 120 | + free(buf); |
| 121 | + |
| 122 | + return ret; |
63 | 123 | } |
64 | 124 |
|
65 | 125 | static pid_t waitpid_retry(pid_t pid, int *wstatus, int options) |
@@ -230,8 +290,8 @@ static int visit_userfunc(json_object *jso, int flags, json_object *, |
230 | 290 | if (!elf_metadata.priority) |
231 | 291 | elf_metadata.priority = "recommended"; |
232 | 292 |
|
233 | | - if (in_envvar("IGNORE_PUT_DLOPEN_FEATURE", elf_metadata.feature) || |
234 | | - in_envvar("IGNORE_PUT_DLOPEN_PRIORITY", elf_metadata.priority)) |
| 293 | + if (in_envvar("IGNORE_PUT_DLOPEN_FEATURE", data->filename, elf_metadata.feature) || |
| 294 | + in_envvar("IGNORE_PUT_DLOPEN_PRIORITY", data->filename, elf_metadata.priority)) |
235 | 295 | return JSON_C_VISIT_RETURN_SKIP; |
236 | 296 |
|
237 | 297 | soname = xcalloc(array_len, sizeof(char *)); |
|
0 commit comments