diff --git a/audio/jack.c b/audio/jack.c index 893a0cb42c..348b448f2f 100644 --- a/audio/jack.c +++ b/audio/jack.c @@ -85,10 +85,11 @@ static int parse_ports(char **dest_ports, const char **jports) { int parsed = 0; - const char *con = strtok(g_settings.audio.device, ","); + char *save; + const char *con = strtok_r(g_settings.audio.device, ",", &save); if (con) dest_ports[parsed++] = strdup(con); - con = strtok(NULL, ","); + con = strtok_r(NULL, ",", &save); if (con) dest_ports[parsed++] = strdup(con); diff --git a/cheats.c b/cheats.c index 16bb79f04e..1e918e39b0 100644 --- a/cheats.c +++ b/cheats.c @@ -18,6 +18,7 @@ #include "dynamic.h" #include "general.h" #include "compat/strl.h" +#include "compat/posix_string.h" #ifdef HAVE_CONFIG_H #include "config.h" @@ -165,14 +166,15 @@ static void cheat_manager_load_config(cheat_manager_t *handle, const char *path, return; } - const char *num = strtok(str, ";"); + char *save; + const char *num = strtok_r(str, ";", &save); while (num) { unsigned index = strtoul(num, NULL, 0); if (index < handle->size) handle->cheats[index].state = true; - num = strtok(NULL, ";"); + num = strtok_r(NULL, ";", &save); } free(str); diff --git a/compat/compat.c b/compat/compat.c index 5f3920e597..0562416864 100644 --- a/compat/compat.c +++ b/compat/compat.c @@ -239,6 +239,7 @@ size_t strlcat(char *dest, const char *source, size_t size) #undef strcasecmp #undef strdup #undef isblank +#undef strtok_r #include #include #include @@ -278,5 +279,36 @@ int isblank_rarch__(int c) return (c == ' ') || (c == '\t'); } +char *strtok_r_rarch__(char *str, const char *delim, char **saveptr) +{ + if (!saveptr || !delim) + return NULL; + + if (str) + *saveptr = str; + + char *first = NULL; + + do + { + first = *saveptr; + while (*first && strchr(delim, *first)) + *first++ = '\0'; + + if (*first == '\0') + return NULL; + + char *ptr = first + 1; + + while (*ptr && !strchr(delim, *ptr)) + ptr++; + + *saveptr = ptr + (*ptr ? 1 : 0); + *ptr = '\0'; + } while (strlen(first) == 0); + + return first; +} + #endif diff --git a/compat/posix_string.h b/compat/posix_string.h index ebf854d326..23f5026aef 100644 --- a/compat/posix_string.h +++ b/compat/posix_string.h @@ -23,12 +23,17 @@ extern "C" { #endif #undef strcasecmp +#undef strdup +#undef isblank +#undef strtok_r #define strcasecmp(a, b) strcasecmp_rarch__(a, b) #define strdup(orig) strdup_rarch__(orig) #define isblank(c) isblank_rarch__(c) +#define strtok_r(str, delim, saveptr) strtok_r_rarch__(str, delim, saveptr) int strcasecmp(const char *a, const char *b); char *strdup(const char *orig); int isblank(int c); +char *strtok_r(char *str, const char *delim, char **saveptr); #ifdef __cplusplus } diff --git a/conf/config_file.c b/conf/config_file.c index a981f4d398..90eb1d2c0d 100644 --- a/conf/config_file.c +++ b/conf/config_file.c @@ -110,11 +110,13 @@ static char *extract_value(char *line, bool is_value) while (isspace(*line)) line++; + char *save; + // We have a full string. Read until next ". if (*line == '"') { line++; - char *tok = strtok(line, "\""); + char *tok = strtok_r(line, "\"", &save); if (!tok) return NULL; return strdup(tok); @@ -123,7 +125,7 @@ static char *extract_value(char *line, bool is_value) return NULL; else // We don't have that... Read till next space. { - char *tok = strtok(line, " \n\t\f\r\v"); + char *tok = strtok_r(line, " \n\t\f\r\v", &save); if (tok) return strdup(tok); else diff --git a/dynamic.c b/dynamic.c index c0d857b48a..cd48846e72 100644 --- a/dynamic.c +++ b/dynamic.c @@ -16,6 +16,7 @@ #include "dynamic.h" #include "general.h" #include "compat/strl.h" +#include "compat/posix_string.h" #include #ifdef RARCH_CONSOLE @@ -367,8 +368,11 @@ static void set_environment(void) // Assume SNES as defaults. static void set_environment_defaults(void) { + char *save; + // Split up environment variables beforehand. - if (g_extern.system.environment_split && strtok(g_extern.system.environment_split, ";")) - while (strtok(NULL, ";")); + if (g_extern.system.environment_split && + strtok_r(g_extern.system.environment_split, ";", &save)) + while (strtok_r(NULL, ";", &save)); } diff --git a/file_path.c b/file_path.c index 451f906712..2752f3c84f 100644 --- a/file_path.c +++ b/file_path.c @@ -104,6 +104,7 @@ static struct string_list *string_split(const char *str, const char *delim) { char *copy = NULL; const char *tmp = NULL; + struct string_list *list = string_list_new(); if (!list) goto error; @@ -112,7 +113,8 @@ static struct string_list *string_split(const char *str, const char *delim) if (!copy) goto error; - tmp = strtok(copy, delim); + char *save; + tmp = strtok_r(copy, delim, &save); while (tmp) { union string_list_elem_attr attr; @@ -121,7 +123,7 @@ static struct string_list *string_split(const char *str, const char *delim) if (!string_list_append(list, tmp, attr)) goto error; - tmp = strtok(NULL, delim); + tmp = strtok_r(NULL, delim, &save); } free(copy); diff --git a/gfx/py_state/py_state.c b/gfx/py_state/py_state.c index b76e3a7199..15f982d519 100644 --- a/gfx/py_state/py_state.c +++ b/gfx/py_state/py_state.c @@ -208,7 +208,8 @@ static char *align_program(const char *program) if (!new_prog) return NULL; - char *line = dupe_newline(strtok(prog, "\n")); + char *save; + char *line = dupe_newline(strtok_r(prog, "\n", &save)); if (!line) { free(prog); @@ -227,7 +228,7 @@ static char *align_program(const char *program) strlcat(new_prog, line + skip_len, prog_size); free(line); - line = dupe_newline(strtok(NULL, "\n")); + line = dupe_newline(strtok_r(NULL, "\n", &save)); } free(prog); diff --git a/gfx/shader_cg.c b/gfx/shader_cg.c index 73a2a82a03..e41bf117a9 100644 --- a/gfx/shader_cg.c +++ b/gfx/shader_cg.c @@ -500,7 +500,8 @@ static bool load_textures(const char *dir_path, config_file_t *conf) if (!config_get_string(conf, "textures", &textures)) // No textures here ... return true; - const char *id = strtok(textures, ";");; + char *save; + const char *id = strtok_r(textures, ";", &save); while (id && lut_textures_num < MAX_TEXTURES) { char path[PATH_MAX]; @@ -546,7 +547,7 @@ static bool load_textures(const char *dir_path, config_file_t *conf) load_texture_data(&lut_textures[lut_textures_num], &img, smooth); lut_textures_num++; - id = strtok(NULL, ";"); + id = strtok_r(NULL, ";", &save); } end: @@ -573,7 +574,8 @@ static bool load_imports(const char *dir_path, config_file_t *conf) char *script_class = NULL; #endif - const char *id = strtok(imports, ";"); + char *save; + const char *id = strtok_r(imports, ";", &save); while (id && info_cnt < MAX_VARIABLES) { char semantic_buf[64]; @@ -692,7 +694,7 @@ static bool load_imports(const char *dir_path, config_file_t *conf) info_cnt++; free(semantic); - id = strtok(NULL, ";"); + id = strtok_r(NULL, ";", &save); } tracker_info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); diff --git a/network_cmd.c b/network_cmd.c index 91ef85aabf..0ea6955f07 100644 --- a/network_cmd.c +++ b/network_cmd.c @@ -153,11 +153,12 @@ static void parse_sub_msg(network_cmd_t *handle, const char *tok) static void parse_msg(network_cmd_t *handle, char *buf) { - const char *tok = strtok(buf, "\n"); + char *save; + const char *tok = strtok_r(buf, "\n", &save); while (tok) { parse_sub_msg(handle, tok); - tok = strtok(NULL, "\n"); + tok = strtok_r(NULL, "\n", &save); } } @@ -283,11 +284,12 @@ bool network_cmd_send(const char *cmd_) const char *port_ = NULL; uint16_t port = DEFAULT_NETWORK_CMD_PORT; - cmd = strtok(command, ":"); + char *save; + cmd = strtok_r(command, ":", &save); if (cmd) - host = strtok(NULL, ":"); + host = strtok_r(NULL, ":", &save); if (host) - port_ = strtok(NULL, ":"); + port_ = strtok_r(NULL, ":", &save); if (!host) {