Redirect_stdout fails to restore ccall prints

There is probably something that I don’t understand with redirect_stdout but if I try using it and returning to the normal stdout it doesn’t work for ccall outputs. (using IJulia and Jupyter notebook with Julia Version 1.6.1)

using Random, RNGTest

rng = RNGTest.wrap(MersenneTwister(), UInt64);
logfile = open("testLog.txt","w")

redirect_stdout(logfile) do
    
    RNGTest.smallcrushTestU01(rng) # executes `ccall`  
end
close(logfile)

println("this prints normally")
RNGTest.smallcrushTestU01(rng)  #still outputs to logfile

Any help would be appreciated!

A smaller MWE, but the behaviour is the same, the putchar from C appears on stdout. Just so you know it is not related to the included modules

julia> logfile = open("testLog.txt","w")
IOStream(<file testLog.txt>)
julia> redirect_stdout(logfile) do
           ccall(:putchar, Cint, (Cint,), 'A')
       end
65
julia> close(logfile)

This indeed reproduces the same behaviour. However a second ccall(:putchar, Cint, (Cint,), 'A') at the end is missing to show how it fails to restore the ccall prints to stdout.

oh, yours is outputting ?

Mine doesn’t write anything to the log file

try flushing the cstdio as such

logfile = open("testLog.txt","w")
redirect_stdout(logfile) do
    ccall(:putchar, Cint, (Cint,), 'A')
    Base.Libc.flush_cstdio()
end
close(logfile)
ccall(:putchar, Cint, (Cint,), 'B')

Runing this, I get the string “AB” in the logfile

This looks like https://github.com/JuliaLang/julia/issues/31236

The solution given on that issue was to call Base.Libc.flush_cstdio() manually. I don’t see why this shouldn’t be done automatically by the redirecting function (here redirect_stdout)… maybe file an issue?

My issue is slightly different. I can redirect ccall to the file once but then I can’t get it to print to stdout again.
For example,

temp = stdout

logfile = open("testLog.txt","w")

redirect_stdout(logfile)
ccall(:putchar, Cint, (Cint,), 'A')
Base.Libc.flush_cstdio()


redirect_stdout(temp)
close(logfile)

ccall(:putchar, Cint, (Cint,), 'B')

Prints ‘AB’ in the log file which is weird since I closed the file and because the stdout has been redirected to the initial standard output

Ah sorry I misread what you wrote.

It seems this was fixed in 1.7, at least I cannot reproduce what you see with 1.7.1.

Indeed I just tried with 1.7 and it works like a charm. Also testing around, I found that the weird behaviour only happens on Jupyter Notebook. I’ve tried with Julia 1.4 and the same bug/behaviour happened.

I added this example to my Czoo module
https://github.com/lawless-m/Czoo.jl

PRs are very welcome