diff --git a/winloop/handles/process.pyx b/winloop/handles/process.pyx index 2c8f7c2..127bfd7 100644 --- a/winloop/handles/process.pyx +++ b/winloop/handles/process.pyx @@ -386,9 +386,6 @@ DEF _CALL_PIPE_CONNECTION_LOST = 1 DEF _CALL_PROCESS_EXITED = 2 DEF _CALL_CONNECTION_LOST = 3 -cdef int WINDOWS_EXE_FROZEN = system.__IS_WINDOWS_EXE_FROZEN() - - @cython.no_gc_clear cdef class UVProcessTransport(UVProcess): @@ -445,11 +442,6 @@ cdef class UVProcessTransport(UVProcess): cdef _file_redirect_stdio(self, int fd): - if WINDOWS_EXE_FROZEN: - # SEE: https://github.com/Vizonex/Winloop/issues/126 - # use devnull instead... - return self._file_devnull() - fd = os_dup(fd) os_set_inheritable(fd, True) self._close_after_spawn(fd) @@ -502,6 +494,16 @@ cdef class UVProcessTransport(UVProcess): 'subprocess.STDOUT is supported only by stderr parameter') else: io[0] = self._file_redirect_stdio(_stdin) + + elif system.PLATFORM_IS_WINDOWS and system.__UVLOOP_STDIN_BAD: + + # When a stdio is in a gui-like state without a console. + # using a standard redirect is not a good idea. This at least + # is a better workaround that is a bit cleaner than doing what the + # python standard libary subprocess does with the _get_handles function + # on windows. SEE: https://github.com/Vizonex/Winloop/issues/126 + + io[0] = self._file_devnull() else: io[0] = self._file_redirect_stdio(0) @@ -530,6 +532,8 @@ cdef class UVProcessTransport(UVProcess): 'subprocess.STDOUT is supported only by stderr parameter') else: io[1] = self._file_redirect_stdio(_stdout) + elif system.PLATFORM_IS_WINDOWS and system.__UVLOOP_STDOUT_BAD: + io[1] = self._file_devnull() else: io[1] = self._file_redirect_stdio(1) @@ -555,6 +559,9 @@ cdef class UVProcessTransport(UVProcess): io[2] = self._file_devnull() else: io[2] = self._file_redirect_stdio(_stderr) + + elif system.PLATFORM_IS_WINDOWS and system.__UVLOOP_STDOUT_BAD: + io[2] = self._file_devnull() else: io[2] = self._file_redirect_stdio(2) diff --git a/winloop/includes/compat.h b/winloop/includes/compat.h index 47f77c2..effbc8d 100644 --- a/winloop/includes/compat.h +++ b/winloop/includes/compat.h @@ -183,36 +183,28 @@ void PyOS_AfterFork_Child() { /* There is a bug with CX-Freeze on windows when compiled * to an exe this tries to fix it by seeing if alternate * workarounds like DEVNULL need to be provided. - * SEE: https://github.com/Vizonex/Winloop/issues/126 */ + * SEE: https://github.com/Vizonex/Winloop/issues/126 + * There are several alternate workarounds to the problem but + * what were going to attempt to do here is see if stdin, stdout, or stderr + * are all mapped properly to 0, 1, 2. If these are -2 then the implementation + * seen in subprocess.py will need to be applied where a handle is open with one closed + * off... */ #ifdef _WIN32 -/* CPython version might be slower so will use our own, audits can be a costly thing, */ +#include + +/* if these show up as -2 console is deemed absent */ +#define __UVLOOP_STDIN_BAD (_fileno(stdin) == -2) +#define __UVLOOP_STDOUT_BAD (_fileno(stdout) == -2) +#define __UVLOOP_STDERR_BAD (_fileno(stderr) == -2) -static int _get_std_handle(DWORD std_handle){ - /* This might be a leak, IDK... CloseHandle just seems to crash it.*/ - HANDLE handle = GetStdHandle(std_handle); - if (handle == INVALID_HANDLE_VALUE){ - goto error; - } - /* We don't need this handle open we just want to know - if windows wants to play nice or not. executable vs not executable. */ - int windows_misbehaved = (handle == NULL) ? 1: 0; - /* if handle == 0 use DEVNULL as backup instead otherwise use the other method. */ - return windows_misbehaved; -error: - /* if handle == -1 throw an error */ - PyErr_SetFromWindowsErr(GetLastError()); - return -1; -} -/* Because these are macros it's very easy to make a workaround for unix. */ -#define __IS_WINDOWS_EXE_FROZEN() _get_std_handle(STD_INPUT_HANDLE) #else /* On Unix these are not needed, but we define it anyways so the compiler doesn't wind up throwing a fit about it */ - -#define __IS_WINDOWS_EXE_FROZEN() 0 /* NOPE */ - +#define __UVLOOP_STDIN_BAD 0 +#define __UVLOOP_STDOUT_BAD 0 +#define __UVLOOP_STDERR_BAD 0 #endif diff --git a/winloop/includes/system.pxd b/winloop/includes/system.pxd index 231f03d..d2421b1 100644 --- a/winloop/includes/system.pxd +++ b/winloop/includes/system.pxd @@ -65,7 +65,10 @@ cdef extern from "includes/compat.h" nogil: int epoll_ctl(int epfd, int op, int fd, epoll_event *event) object MakeUnixSockPyAddr(sockaddr_un *addr) - int __IS_WINDOWS_EXE_FROZEN() except -1 + # Checks if values are -2. This check only applies to windows. + int __UVLOOP_STDIN_BAD + int __UVLOOP_STDOUT_BAD + int __UVLOOP_STDERR_BAD cdef extern from "includes/fork_handler.h":