From cc7c310aa1e2b6dec894efa01faac1231e0ee4bd Mon Sep 17 00:00:00 2001 From: Cthulhu-throwaway <96153783+Cthulhu-throwaway@users.noreply.github.com> Date: Sat, 23 Jul 2022 23:26:50 -0300 Subject: [PATCH] (Netplay) Refactor fork arguments (#14208) --- network/netplay/netplay.h | 20 ++++++++--- network/netplay/netplay_frontend.c | 43 ++++++++++++++++++----- tasks/task_netplay_find_content.c | 55 ++++++++++++++++++------------ 3 files changed, 83 insertions(+), 35 deletions(-) diff --git a/network/netplay/netplay.h b/network/netplay/netplay.h index 9a2dd3cdeb..0e83b3b3ef 100644 --- a/network/netplay/netplay.h +++ b/network/netplay/netplay.h @@ -36,6 +36,10 @@ #include "../natt.h" +#ifndef HAVE_DYNAMIC +#define NETPLAY_FORK_MAX_ARGS 64 +#endif + #define NETPLAY_NICK_LEN 32 #define NETPLAY_HOST_STR_LEN 32 #define NETPLAY_HOST_LONGSTR_LEN 256 @@ -59,8 +63,8 @@ enum rarch_netplay_ctl_state RARCH_NETPLAY_CTL_ENABLE_CLIENT, RARCH_NETPLAY_CTL_DISABLE, #ifndef HAVE_DYNAMIC + RARCH_NETPLAY_CTL_ADD_FORK_ARG, RARCH_NETPLAY_CTL_GET_FORK_ARGS, - RARCH_NETPLAY_CTL_SET_FORK_ARGS, RARCH_NETPLAY_CTL_CLEAR_FORK_ARGS, #endif RARCH_NETPLAY_CTL_REFRESH_CLIENT_INFO, @@ -162,6 +166,14 @@ typedef struct mitm_server enum msg_hash_enums description; } mitm_server_t; +#ifndef HAVE_DYNAMIC +struct netplay_fork_args +{ + size_t size; + char args[PATH_MAX_LENGTH]; +}; +#endif + struct netplay_room { struct netplay_room *next; @@ -230,6 +242,9 @@ struct netplay_chat_buffer typedef struct { +#ifndef HAVE_DYNAMIC + struct netplay_fork_args fork_args; +#endif /* NAT traversal info (if NAT traversal is used and serving) */ struct nat_traversal_data nat_traversal_request; #ifdef HAVE_NETPLAYDISCOVERY @@ -254,9 +269,6 @@ typedef struct unsigned server_port_deferred; char server_address_deferred[256]; char server_session_deferred[32]; -#ifndef HAVE_DYNAMIC - char netplay_fork_args[PATH_MAX_LENGTH]; -#endif bool netplay_client_deferred; /* Only used before init_netplay */ bool netplay_enabled; diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index c4cee25c32..34d9bb57ef 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -8988,24 +8988,49 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data) break; #ifndef HAVE_DYNAMIC - case RARCH_NETPLAY_CTL_GET_FORK_ARGS: - if (data && !string_is_empty(net_st->netplay_fork_args)) - strlcpy((char*)data, net_st->netplay_fork_args, - sizeof(net_st->netplay_fork_args)); + case RARCH_NETPLAY_CTL_ADD_FORK_ARG: + if (data && net_st->fork_args.size < sizeof(net_st->fork_args.args)) + { + size_t new_size = strlcpy( + net_st->fork_args.args + net_st->fork_args.size, + (const char*)data, + sizeof(net_st->fork_args.args) - net_st->fork_args.size); + new_size += 1; /* NULL terminator */ + new_size += net_st->fork_args.size; + if (new_size > sizeof(net_st->fork_args.args)) + { + ret = false; + break; + } + net_st->fork_args.size = new_size; + } else ret = false; break; - case RARCH_NETPLAY_CTL_SET_FORK_ARGS: - if (data) - strlcpy(net_st->netplay_fork_args, (const char*)data, - sizeof(net_st->netplay_fork_args)); + case RARCH_NETPLAY_CTL_GET_FORK_ARGS: + if (data && net_st->fork_args.size) + { + size_t offset = 0; + char *args = net_st->fork_args.args; + size_t args_sz = net_st->fork_args.size; + char **args_cur = (char**)data; + char **args_end = &args_cur[NETPLAY_FORK_MAX_ARGS - 1]; + for (; offset < args_sz && args_cur != args_end; args_cur++) + { + *args_cur = args + offset; + offset += strlen(*args_cur) + 1; + } + /* Ensure that the final entry is NULL. */ + *args_cur = NULL; + } else ret = false; break; case RARCH_NETPLAY_CTL_CLEAR_FORK_ARGS: - *net_st->netplay_fork_args = '\0'; + net_st->fork_args.size = 0; + *net_st->fork_args.args = '\0'; break; #endif diff --git a/tasks/task_netplay_find_content.c b/tasks/task_netplay_find_content.c index 985e07bd4d..e29ff23a93 100644 --- a/tasks/task_netplay_find_content.c +++ b/tasks/task_netplay_find_content.c @@ -451,31 +451,29 @@ finished: } #ifndef HAVE_DYNAMIC -static void static_load(const char *core, const char *subsystem, +static bool static_load(const char *core, const char *subsystem, const void *content, const char *hostname) { - char buf[512]; - char args[PATH_MAX_LENGTH]; - - path_set(RARCH_PATH_CORE, core); - +#define ARG(arg) (void*)(arg) netplay_driver_ctl(RARCH_NETPLAY_CTL_CLEAR_FORK_ARGS, NULL); if (string_is_empty(hostname)) { - strlcpy(args, "-H", sizeof(args)); + if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_ADD_FORK_ARG, ARG("-H"))) + goto failure; } else { - strlcpy(args, "-C ", sizeof(args)); - strlcat(args, hostname, sizeof(args)); + if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_ADD_FORK_ARG, ARG("-C")) || + !netplay_driver_ctl(RARCH_NETPLAY_CTL_ADD_FORK_ARG, ARG(hostname))) + goto failure; } if (!string_is_empty(subsystem)) { - snprintf(buf, sizeof(buf), "\"%s\"", subsystem); - strlcat(args, " --subsystem ", sizeof(args)); - strlcat(args, buf, sizeof(args)); + if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_ADD_FORK_ARG, ARG("--subsystem")) || + !netplay_driver_ctl(RARCH_NETPLAY_CTL_ADD_FORK_ARG, ARG(subsystem))) + goto failure; if (content) { @@ -485,21 +483,35 @@ static void static_load(const char *core, const char *subsystem, for (i = 0; i < subsystem_content->size; i++) { - snprintf(buf, sizeof(buf), " \"%s\"", - subsystem_content->elems[i].data); - strlcat(args, buf, sizeof(args)); + if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_ADD_FORK_ARG, + ARG(subsystem_content->elems[i].data))) + goto failure; } } } else if (content) { - snprintf(buf, sizeof(buf), " \"%s\"", (const char*)content); - strlcat(args, buf, sizeof(args)); + if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_ADD_FORK_ARG, ARG(content))) + goto failure; } - netplay_driver_ctl(RARCH_NETPLAY_CTL_SET_FORK_ARGS, args); - frontend_driver_set_fork(FRONTEND_FORK_CORE_WITH_ARGS); + if (!frontend_driver_set_fork(FRONTEND_FORK_CORE_WITH_ARGS)) + goto failure; + + path_set(RARCH_PATH_CORE, core); + retroarch_ctl(RARCH_CTL_SET_SHUTDOWN, NULL); + + return true; + +failure: + RARCH_ERR("[Lobby] Failed to fork RetroArch for netplay.\n"); + + netplay_driver_ctl(RARCH_NETPLAY_CTL_CLEAR_FORK_ARGS, NULL); + + return false; + +#undef ARG } #endif @@ -677,10 +689,9 @@ static void task_netplay_crc_scan_callback(retro_task_t *task, content_set_subsystem_by_name(data->current.subsystem); } #else - static_load(data->core, data->current.subsystem, NULL, - data->hostname); + if (static_load(data->core, data->current.subsystem, NULL, + data->hostname)) #endif - runloop_msg_queue_push( msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED), 1, 480, true, NULL,