I have some code that uses ctypes to try to determine if the file pointed to by sys.stdout
is actually stdout
. I know that on any POSIX-compliant system, and even on Windows, it should be safe to assume this is true if sys.stdout.fileno() == 1
, so my question is not how to do this in general.
In my code (which is already using ctypes for something unrelated to my question) I carelessly had something like:
libc = ctypes.CDLL(ctypes.util.find_library('c'))
real_stdout = libc.fileno(ctypes.c_void_p.in_dll(libc, 'stdout'))
if sys.stdout.fileno() == real_stdout:
...
This works perfectly fine on Linux, so I didn't really think about it much. It looked nicer and more readable than hard-coding 1
as the file descriptor. But I found a few days later that my code wasn't working on OSX.
It turns outs OSX's libc doesn't export any symbol called 'stdout'. Instead its stdio.h has stdout defined as:
#define stdout __stdoutp
If I change my code to c_void_p.in_dll(libc, '__stdoutp')
my code works as expected, but of course that's OSX-only. Windows, it turns out, has a similar issue (at least if using MSVC).
I will probably just change my code to use 1
, but my question still stands, out of curiosity, if there's a cross-platform way to get the stdio
pointer (and likewise stdin
and stderr
) without assuming that it's using the POSIX-compliant descriptor?
fileno(stdout)
on any Posix platform, though there's a also a predefined macro for that value namedSTDOUT_FILENO
. – Ragsys.stdout
has been replaced the originalstdout
remains insys.__stdout__
(unless your code changes that too). See thatsys.__stdout__.fileno()
=>1
– Scheldsys.__stdout__.fileno()
can't be relied on either since it can just as easily be replaced. nos understood the question, but as I suspected there's no good answer really. – Fecit