diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index c7033a26..0c1289bc 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -275,10 +275,6 @@ scrcpy(struct scrcpy_options *options) { atexit(SDL_Quit); - if (!server_init(&s->server)) { - return false; - } - bool ret = false; bool server_started = false; @@ -313,7 +309,12 @@ scrcpy(struct scrcpy_options *options) { .force_adb_forward = options->force_adb_forward, .power_off_on_close = options->power_off_on_close, }; - if (!server_start(&s->server, ¶ms)) { + + if (!server_init(&s->server, ¶ms)) { + return false; + } + + if (!server_start(&s->server)) { goto end; } @@ -339,7 +340,7 @@ scrcpy(struct scrcpy_options *options) { } if (options->display && options->control) { - if (!file_handler_init(&s->file_handler, s->server.serial, + if (!file_handler_init(&s->file_handler, options->serial, options->push_target)) { goto end; } diff --git a/app/src/server.c b/app/src/server.c index 1c1c783a..4ebdc845 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -61,6 +61,44 @@ get_server_path(void) { return server_path; } +static void +server_params_destroy(struct server_params *params) { + // The server stores a copy of the params provided by the user + free((char *) params->serial); + free((char *) params->crop); + free((char *) params->codec_options); + free((char *) params->encoder_name); +} + +static bool +server_params_copy(struct server_params *dst, const struct server_params *src) { + *dst = *src; + + // The params reference user-allocated memory, so we must copy them to + // handle them from another thread + +#define COPY(FIELD) \ + dst->FIELD = NULL; \ + if (src->FIELD) { \ + dst->FIELD = strdup(src->FIELD); \ + if (!dst->FIELD) { \ + goto error; \ + } \ + } + + COPY(serial); + COPY(crop); + COPY(codec_options); + COPY(encoder_name); +#undef COPY + + return true; + +error: + server_params_destroy(dst); + return false; +} + static bool push_server(const char *serial) { char *server_path = get_server_path(); @@ -103,10 +141,11 @@ disable_tunnel_forward(const char *serial, uint16_t local_port) { static bool disable_tunnel(struct server *server) { + const char *serial = server->params.serial; if (server->tunnel_forward) { - return disable_tunnel_forward(server->serial, server->local_port); + return disable_tunnel_forward(serial, server->local_port); } - return disable_tunnel_reverse(server->serial); + return disable_tunnel_reverse(serial); } static bool @@ -118,9 +157,10 @@ listen_on_port(sc_socket socket, uint16_t port) { static bool enable_tunnel_reverse_any_port(struct server *server, struct sc_port_range port_range) { + const char *serial = server->params.serial; uint16_t port = port_range.first; for (;;) { - if (!enable_tunnel_reverse(server->serial, port)) { + if (!enable_tunnel_reverse(serial, port)) { // the command itself failed, it will fail on any port return false; } @@ -145,7 +185,7 @@ enable_tunnel_reverse_any_port(struct server *server, } // failure, disable tunnel and try another port - if (!disable_tunnel_reverse(server->serial)) { + if (!disable_tunnel_reverse(serial)) { LOGW("Could not remove reverse tunnel on port %" PRIu16, port); } @@ -171,9 +211,11 @@ static bool enable_tunnel_forward_any_port(struct server *server, struct sc_port_range port_range) { server->tunnel_forward = true; + + const char *serial = server->params.serial; uint16_t port = port_range.first; for (;;) { - if (enable_tunnel_forward(server->serial, port)) { + if (enable_tunnel_forward(serial, port)) { // success server->local_port = port; return true; @@ -235,6 +277,8 @@ log_level_to_server_string(enum sc_log_level level) { static process_t execute_server(struct server *server, const struct server_params *params) { + const char *serial = server->params.serial; + char max_size_string[6]; char bit_rate_string[11]; char max_fps_string[6]; @@ -292,7 +336,7 @@ execute_server(struct server *server, const struct server_params *params) { // Port: 5005 // Then click on "Debug" #endif - return adb_execute(server->serial, cmd, ARRAY_LEN(cmd)); + return adb_execute(serial, cmd, ARRAY_LEN(cmd)); } static sc_socket @@ -336,18 +380,25 @@ connect_to_server(uint16_t port, uint32_t attempts, uint32_t delay) { } bool -server_init(struct server *server) { - server->serial = NULL; +server_init(struct server *server, const struct server_params *params) { + bool ok = server_params_copy(&server->params, params); + if (!ok) { + LOGE("Could not copy server params"); + return false; + } + server->process = PROCESS_NONE; - bool ok = sc_mutex_init(&server->mutex); + ok = sc_mutex_init(&server->mutex); if (!ok) { + server_params_destroy(&server->params); return false; } ok = sc_cond_init(&server->process_terminated_cond); if (!ok) { sc_mutex_destroy(&server->mutex); + server_params_destroy(&server->params); return false; } @@ -387,13 +438,8 @@ run_wait_server(void *data) { } bool -server_start(struct server *server, const struct server_params *params) { - if (params->serial) { - server->serial = strdup(params->serial); - if (!server->serial) { - return false; - } - } +server_start(struct server *server) { + const struct server_params *params = &server->params; if (!push_server(params->serial)) { /* server->serial will be freed on server_destroy() */ @@ -576,7 +622,8 @@ server_destroy(struct server *server) { LOGW("Could not close control socket"); } } - free(server->serial); + + server_params_destroy(&server->params); sc_cond_destroy(&server->process_terminated_cond); sc_mutex_destroy(&server->mutex); } diff --git a/app/src/server.h b/app/src/server.h index 821c1dc3..a427c9fc 100644 --- a/app/src/server.h +++ b/app/src/server.h @@ -34,7 +34,9 @@ struct server_params { }; struct server { - char *serial; + // The internal allocated strings are copies owned by the server + struct server_params params; + process_t process; sc_thread wait_server_thread; @@ -50,13 +52,13 @@ struct server { bool tunnel_forward; // use "adb forward" instead of "adb reverse" }; -// init default values +// init the server with the given params bool -server_init(struct server *server); +server_init(struct server *server, const struct server_params *params); // push, enable tunnel et start the server bool -server_start(struct server *server, const struct server_params *params); +server_start(struct server *server); #define DEVICE_NAME_FIELD_LENGTH 64 // block until the communication with the server is established