diff --git a/uvloop/handles/process.pyx b/uvloop/handles/process.pyx index 3aad40af..84611971 100644 --- a/uvloop/handles/process.pyx +++ b/uvloop/handles/process.pyx @@ -496,6 +496,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 library 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) @@ -524,6 +534,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) @@ -549,6 +561,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) @@ -561,6 +576,7 @@ cdef class UVProcessTransport(UVProcess): else: iocnt.flags = uv.UV_IGNORE + cdef _call_connection_made(self, waiter): try: # we're always called in the right context, so just call the user's diff --git a/uvloop/includes/compat.h b/uvloop/includes/compat.h index d42a8f11..f5d8a89c 100644 --- a/uvloop/includes/compat.h +++ b/uvloop/includes/compat.h @@ -179,3 +179,29 @@ void PyOS_AfterFork_Child() { #endif +/* 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 + * 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 +#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) + + +#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 __UVLOOP_STDIN_BAD 0 +#define __UVLOOP_STDOUT_BAD 0 +#define __UVLOOP_STDERR_BAD 0 +#endif diff --git a/uvloop/includes/python.pxd b/uvloop/includes/python.pxd index 94007e53..77f7f15b 100644 --- a/uvloop/includes/python.pxd +++ b/uvloop/includes/python.pxd @@ -29,3 +29,4 @@ cdef extern from "includes/compat.h": void PyOS_AfterFork_Child() void _Py_RestoreSignals() + diff --git a/uvloop/includes/system.pxd b/uvloop/includes/system.pxd index a424a711..a80606b0 100644 --- a/uvloop/includes/system.pxd +++ b/uvloop/includes/system.pxd @@ -65,6 +65,11 @@ cdef extern from "includes/compat.h" nogil: int epoll_ctl(int epfd, int op, int fd, epoll_event *event) object MakeUnixSockPyAddr(sockaddr_un *addr) + # 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":