Compare commits

...

3 commits

Author SHA1 Message Date
Romain Vimont 020b3510ae Inherit handles only if necessary on Windows
Refs #2779 <https://github.com/Genymobile/scrcpy/issues/2779>
2021-11-14 19:57:47 +01:00
Romain Vimont dcf9887f56 Mark sockets as non-inheritable on Windows
To be able to communicate with a child process via stdin, stdout and
stderr, the CreateProcess() parameter bInheritHandles must be set to
TRUE. But this causes *all* handles to be inherited, including sockets.

One possibility could be to use an extended API to set extra attributes
on process creation:
 - <https://stackoverflow.com/a/28185363/1987178>
 - <https://devblogs.microsoft.com/oldnewthing/20111216-00/?p=8873>

But it seems that this API is not available on MinGW (it does not
compile).

As an alternative, explicitly mark all sockets as non-inheritable.

Fixes #2779 <https://github.com/Genymobile/scrcpy/issues/2779>
2021-11-14 19:57:37 +01:00
Romain Vimont 6a27062f48 Stop connection attempts if interrupted
If the interruptor is interrupted, every network call will fail, but the
retry-on-error mechanism must also be stopped.
2021-11-14 15:40:59 +01:00
3 changed files with 32 additions and 3 deletions

View file

@ -234,6 +234,12 @@ connect_to_server(struct sc_server *server, uint32_t attempts, sc_tick delay) {
net_close(socket);
}
if (sc_intr_is_interrupted(&server->intr)) {
// Stop immediately
break;
}
if (attempts) {
sc_mutex_lock(&server->mutex);
sc_tick deadline = sc_tick_now() + delay;

View file

@ -26,6 +26,8 @@ sc_process_execute_p(const char *const argv[], HANDLE *handle,
HANDLE *pin, HANDLE *pout, HANDLE *perr) {
enum sc_process_result ret = SC_PROCESS_ERROR_GENERIC;
bool inherit_handles = pin || pout || perr;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
@ -69,7 +71,7 @@ sc_process_execute_p(const char *const argv[], HANDLE *handle,
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
if (pin || pout || perr) {
if (inherit_handles) {
si.dwFlags = STARTF_USESTDHANDLES;
if (pin) {
si.hStdInput = stdin_read_handle;
@ -95,8 +97,8 @@ sc_process_execute_p(const char *const argv[], HANDLE *handle,
goto error_close_stderr;
}
if (!CreateProcessW(NULL, wide, NULL, NULL, TRUE, 0, NULL, NULL, &si,
&pi)) {
if (!CreateProcessW(NULL, wide, NULL, NULL, inherit_handles, 0, NULL, NULL,
&si, &pi)) {
free(wide);
*handle = NULL;

View file

@ -96,6 +96,27 @@ net_perror(const char *s) {
sc_socket
net_socket(void) {
sc_raw_socket raw_sock = socket(AF_INET, SOCK_STREAM, 0);
#ifdef _WIN32
/* To be able to communicate with a child process via stdin, stdout and
* stderr, the CreateProcess() parameter bInheritHandles must be set to
* TRUE. But this causes *all* handles to be inherited, including sockets.
*
* One possibility could be to use an extended API to set extra attributes
* on process creation:
* - <https://stackoverflow.com/a/28185363/1987178>
* - <https://devblogs.microsoft.com/oldnewthing/20111216-00/?p=8873>
* But it seems that this API is not available on MinGW (it does not
* compile).
*
* As an alternative, explicitly mark all sockets as non-inheritable.
*/
if (!SetHandleInformation((HANDLE) raw_sock, HANDLE_FLAG_INHERIT, 0)) {
closesocket(raw_sock);
return SC_SOCKET_NONE;
}
#endif
sc_socket sock = wrap(raw_sock);
if (sock == SC_SOCKET_NONE) {
net_perror("socket");