qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

cutils: Provide strchrnul

strchrnul is a GNU extension and thus unavailable on a number of targets.
In the review for a commit removing strchrnul from 9p, I was asked to
create a qemu_strchrnul helper to factor out this functionality.
Do so, and use it in a number of other places in the code base that inlined
the replacement pattern in a place where strchrnul could be used.

Signed-off-by: Keno Fischer <keno@juliacomputing.com>
Acked-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Greg Kurz <groug@kaod.org>

authored by

Keno Fischer and committed by
Greg Kurz
5c99fa37 609ef9f4

+51 -20
+18
configure
··· 4794 4794 fi 4795 4795 4796 4796 ########################################## 4797 + # check if we have strchrnul 4798 + 4799 + strchrnul=no 4800 + cat > $TMPC << EOF 4801 + #include <string.h> 4802 + int main(void); 4803 + // Use a haystack that the compiler shouldn't be able to constant fold 4804 + char *haystack = (char*)&main; 4805 + int main(void) { return strchrnul(haystack, 'x') != &haystack[6]; } 4806 + EOF 4807 + if compile_prog "" "" ; then 4808 + strchrnul=yes 4809 + fi 4810 + 4811 + ########################################## 4797 4812 # check if trace backend exists 4798 4813 4799 4814 $python "$source_path/scripts/tracetool.py" "--backends=$trace_backends" --check-backends > /dev/null 2> /dev/null ··· 6275 6290 fi 6276 6291 if test "$sem_timedwait" = "yes" ; then 6277 6292 echo "CONFIG_SEM_TIMEDWAIT=y" >> $config_host_mak 6293 + fi 6294 + if test "$strchrnul" = "yes" ; then 6295 + echo "HAVE_STRCHRNUL=y" >> $config_host_mak 6278 6296 fi 6279 6297 if test "$byteswap_h" = "yes" ; then 6280 6298 echo "CONFIG_BYTESWAP_H=y" >> $config_host_mak
+4 -4
hmp.c
··· 2140 2140 int has_hold_time = qdict_haskey(qdict, "hold-time"); 2141 2141 int hold_time = qdict_get_try_int(qdict, "hold-time", -1); 2142 2142 Error *err = NULL; 2143 - char *separator; 2143 + const char *separator; 2144 2144 int keyname_len; 2145 2145 2146 2146 while (1) { 2147 - separator = strchr(keys, '-'); 2148 - keyname_len = separator ? separator - keys : strlen(keys); 2147 + separator = qemu_strchrnul(keys, '-'); 2148 + keyname_len = separator - keys; 2149 2149 2150 2150 /* Be compatible with old interface, convert user inputted "<" */ 2151 2151 if (keys[0] == '<' && keyname_len == 1) { ··· 2182 2182 keylist->value->u.qcode.data = idx; 2183 2183 } 2184 2184 2185 - if (!separator) { 2185 + if (!*separator) { 2186 2186 break; 2187 2187 } 2188 2188 keys = separator + 1;
+1 -1
hw/9pfs/9p-local.c
··· 65 65 assert(*path != '/'); 66 66 67 67 head = g_strdup(path); 68 - c = strchrnul(path, '/'); 68 + c = qemu_strchrnul(path, '/'); 69 69 if (*c) { 70 70 /* Intermediate path element */ 71 71 head[c - path] = 0;
+8
include/qemu/cutils.h
··· 122 122 * Returns: the pointer originally in @input. 123 123 */ 124 124 char *qemu_strsep(char **input, const char *delim); 125 + #ifdef HAVE_STRCHRNUL 126 + static inline const char *qemu_strchrnul(const char *s, int c) 127 + { 128 + return strchrnul(s, c); 129 + } 130 + #else 131 + const char *qemu_strchrnul(const char *s, int c); 132 + #endif 125 133 time_t mktimegm(struct tm *tm); 126 134 int qemu_fdatasync(int fd); 127 135 int fcntl_setfl(int fd, int flag);
+2 -6
monitor.c
··· 820 820 p = list; 821 821 for(;;) { 822 822 pstart = p; 823 - p = strchr(p, '|'); 824 - if (!p) 825 - p = pstart + strlen(pstart); 823 + p = qemu_strchrnul(p, '|'); 826 824 if ((p - pstart) == len && !memcmp(pstart, name, len)) 827 825 return 1; 828 826 if (*p == '\0') ··· 3489 3487 p = list; 3490 3488 for(;;) { 3491 3489 pstart = p; 3492 - p = strchr(p, '|'); 3493 - if (!p) 3494 - p = pstart + strlen(pstart); 3490 + p = qemu_strchrnul(p, '|'); 3495 3491 len = p - pstart; 3496 3492 if (len > sizeof(cmd) - 2) 3497 3493 len = sizeof(cmd) - 2;
+15
util/cutils.c
··· 545 545 } 546 546 547 547 /** 548 + * Searches for the first occurrence of 'c' in 's', and returns a pointer 549 + * to the trailing null byte if none was found. 550 + */ 551 + #ifndef HAVE_STRCHRNUL 552 + const char *qemu_strchrnul(const char *s, int c) 553 + { 554 + const char *e = strchr(s, c); 555 + if (!e) { 556 + e = s + strlen(s); 557 + } 558 + return e; 559 + } 560 + #endif 561 + 562 + /** 548 563 * parse_uint: 549 564 * 550 565 * @s: String to parse
+1 -5
util/qemu-option.c
··· 77 77 78 78 *value = NULL; 79 79 while (1) { 80 - offset = strchr(p, ','); 81 - if (!offset) { 82 - offset = p + strlen(p); 83 - } 84 - 80 + offset = qemu_strchrnul(p, ','); 85 81 length = offset - p; 86 82 if (*offset != '\0' && *(offset + 1) == ',') { 87 83 length++;
+2 -4
util/uri.c
··· 52 52 */ 53 53 54 54 #include "qemu/osdep.h" 55 + #include "qemu/cutils.h" 55 56 56 57 #include "qemu/uri.h" 57 58 ··· 2266 2267 /* Find the next separator, or end of the string. */ 2267 2268 end = strchr(query, '&'); 2268 2269 if (!end) { 2269 - end = strchr(query, ';'); 2270 - } 2271 - if (!end) { 2272 - end = query + strlen(query); 2270 + end = qemu_strchrnul(query, ';'); 2273 2271 } 2274 2272 2275 2273 /* Find the first '=' character between here and end. */