Skip to content

Commit 8f0f94a

Browse files
committed
add better workaround system for processes when there is no console.
1 parent 4b95827 commit 8f0f94a

3 files changed

Lines changed: 34 additions & 32 deletions

File tree

winloop/handles/process.pyx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -386,9 +386,6 @@ DEF _CALL_PIPE_CONNECTION_LOST = 1
386386
DEF _CALL_PROCESS_EXITED = 2
387387
DEF _CALL_CONNECTION_LOST = 3
388388

389-
cdef int WINDOWS_EXE_FROZEN = system.__IS_WINDOWS_EXE_FROZEN()
390-
391-
392389

393390
@cython.no_gc_clear
394391
cdef class UVProcessTransport(UVProcess):
@@ -445,11 +442,6 @@ cdef class UVProcessTransport(UVProcess):
445442

446443

447444
cdef _file_redirect_stdio(self, int fd):
448-
if WINDOWS_EXE_FROZEN:
449-
# SEE: https://github.com/Vizonex/Winloop/issues/126
450-
# use devnull instead...
451-
return self._file_devnull()
452-
453445
fd = os_dup(fd)
454446
os_set_inheritable(fd, True)
455447
self._close_after_spawn(fd)
@@ -502,6 +494,16 @@ cdef class UVProcessTransport(UVProcess):
502494
'subprocess.STDOUT is supported only by stderr parameter')
503495
else:
504496
io[0] = self._file_redirect_stdio(_stdin)
497+
498+
elif system.PLATFORM_IS_WINDOWS and system.__UVLOOP_STDIN_BAD:
499+
500+
# When a stdio is in a gui-like state without a console.
501+
# using a standard redirect is not a good idea. This at least
502+
# is a better workaround that is a bit cleaner than doing what the
503+
# python standard libary subprocess does with the _get_handles function
504+
# on windows. SEE: https://github.com/Vizonex/Winloop/issues/126
505+
506+
io[0] = self._file_devnull()
505507
else:
506508
io[0] = self._file_redirect_stdio(0)
507509

@@ -530,6 +532,8 @@ cdef class UVProcessTransport(UVProcess):
530532
'subprocess.STDOUT is supported only by stderr parameter')
531533
else:
532534
io[1] = self._file_redirect_stdio(_stdout)
535+
elif system.PLATFORM_IS_WINDOWS and system.__UVLOOP_STDOUT_BAD:
536+
io[1] = self._file_devnull()
533537
else:
534538
io[1] = self._file_redirect_stdio(1)
535539

@@ -555,6 +559,9 @@ cdef class UVProcessTransport(UVProcess):
555559
io[2] = self._file_devnull()
556560
else:
557561
io[2] = self._file_redirect_stdio(_stderr)
562+
563+
elif system.PLATFORM_IS_WINDOWS and system.__UVLOOP_STDOUT_BAD:
564+
io[2] = self._file_devnull()
558565
else:
559566
io[2] = self._file_redirect_stdio(2)
560567

winloop/includes/compat.h

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -183,36 +183,28 @@ void PyOS_AfterFork_Child() {
183183
/* There is a bug with CX-Freeze on windows when compiled
184184
* to an exe this tries to fix it by seeing if alternate
185185
* workarounds like DEVNULL need to be provided.
186-
* SEE: https://github.com/Vizonex/Winloop/issues/126 */
186+
* SEE: https://github.com/Vizonex/Winloop/issues/126
187+
* There are several alternate workarounds to the problem but
188+
* what were going to attempt to do here is see if stdin, stdout, or stderr
189+
* are all mapped properly to 0, 1, 2. If these are -2 then the implementation
190+
* seen in subprocess.py will need to be applied where a handle is open with one closed
191+
* off... */
187192

188193
#ifdef _WIN32
189-
/* CPython version might be slower so will use our own, audits can be a costly thing, */
194+
#include <stdio.h>
195+
196+
/* if these show up as -2 console is deemed absent */
197+
#define __UVLOOP_STDIN_BAD (_fileno(stdin) == -2)
198+
#define __UVLOOP_STDOUT_BAD (_fileno(stdout) == -2)
199+
#define __UVLOOP_STDERR_BAD (_fileno(stderr) == -2)
190200

191-
static int _get_std_handle(DWORD std_handle){
192-
/* This might be a leak, IDK... CloseHandle just seems to crash it.*/
193-
HANDLE handle = GetStdHandle(std_handle);
194-
if (handle == INVALID_HANDLE_VALUE){
195-
goto error;
196-
}
197-
/* We don't need this handle open we just want to know
198-
if windows wants to play nice or not. executable vs not executable. */
199-
int windows_misbehaved = (handle == NULL) ? 1: 0;
200-
/* if handle == 0 use DEVNULL as backup instead otherwise use the other method. */
201-
return windows_misbehaved;
202-
error:
203-
/* if handle == -1 throw an error */
204-
PyErr_SetFromWindowsErr(GetLastError());
205-
return -1;
206-
}
207201

208-
/* Because these are macros it's very easy to make a workaround for unix. */
209-
#define __IS_WINDOWS_EXE_FROZEN() _get_std_handle(STD_INPUT_HANDLE)
210202
#else
211203
/* On Unix these are not needed, but we define it anyways so the
212204
compiler doesn't wind up throwing a fit about it */
213-
214-
#define __IS_WINDOWS_EXE_FROZEN() 0 /* NOPE */
215-
205+
#define __UVLOOP_STDIN_BAD 0
206+
#define __UVLOOP_STDOUT_BAD 0
207+
#define __UVLOOP_STDERR_BAD 0
216208
#endif
217209

218210

winloop/includes/system.pxd

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ cdef extern from "includes/compat.h" nogil:
6565
int epoll_ctl(int epfd, int op, int fd, epoll_event *event)
6666
object MakeUnixSockPyAddr(sockaddr_un *addr)
6767

68-
int __IS_WINDOWS_EXE_FROZEN() except -1
68+
# Checks if values are -2. This check only applies to windows.
69+
int __UVLOOP_STDIN_BAD
70+
int __UVLOOP_STDOUT_BAD
71+
int __UVLOOP_STDERR_BAD
6972

7073
cdef extern from "includes/fork_handler.h":
7174

0 commit comments

Comments
 (0)