In a Julia program which run under Linux, I need to launch a dedicated action when a console window is resized. So how in Julia, can I intercept the system signal SIGWINCH (window resizing) and attach to it a function which performs the required action ?
In Ada it is rather straightforward to declare it :
protected Signalhandler is
procedure Handlewindowresizing;
pragma Attach_Handler (Handlewindowresizing, SIGWINCH);
end Signalhandler;
TENTATIVE SOLUTION BASED ON IDEA OF SCHEMER : I try to use a C Library which conducts the SIGWINCH interruption monitoring.
myLibrary.h
void Winresize (void Sig_Handler());
myLibrary.c
#include "myLibrary.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void Winresize(void sig_handler (void)) {
signal(SIGWINCH, sig_handler);
}
Compilation & Library preparation
gcc -c -Wall -fPIC myLibrary.c
gcc -shared -fPIC -o myLibrary.so myLibrary.o
Program in Julia which uses the C-Library :
function getc1()
ret = ccall(:jl_tty_set_mode, Int32, (Ptr{Cvoid},Int32), stdin.handle, true)
ret == 0 || error("unable to switch to raw mode")
c = read(stdin, UInt8)
ccall(:jl_tty_set_mode, Int32, (Ptr{Cvoid},Int32), stdin.handle, false)
c
end
function traitement() println(displaysize(stdout)); end
Mon_traitement_c = @cfunction(traitement, Cvoid, ())
ccall((:Winresize, "/home/Emile/programmation/Julia/myLibrary.so"), Cvoid, (Ptr{Cvoid},), Mon_traitement_c)
while true
println(getc1())
end
The Julia program run properly but when the terminal window is resized a Segmentation fault (core dumped) is issued and program is said exited with code: 139.
So the question is where does this segmentation fault come from ? From the compilation model ? Julia has not the right to control code execution in the memory part where C manages the signal monitoring ?
Removing println operation in Sig_handler suppress the segmentation fault :
curr_size = displaysize(stdout)
new_size = curr_size
function traitement() global new_size ; new_size = displaysize(stdout); return end
Mon_traitement_c = @cfunction(traitement, Cvoid, ())
ccall((:Winresize, "/home/Emile/programmation/Julia/myLibrary.so"), Cvoid, (Ptr{Cvoid},), Mon_traitement_c)
while true
global curr_size, new_size
if new_size != curr_size
curr_size = new_size
println(curr_size)
end
sleep(0.1)
end
Since no one has answered this question so far, one possible workaround could be asynchronously monitoring the size of the terminal in some time intervals.
function monitor_term(func)
@async begin
curr_size = displaysize(stdout)
while (true)
sleep(0.1)
new_size = displaysize(stdout)
if new_size != curr_size
curr_size = new_size
func()
end
end
end
end
And now sample usage:
julia> monitor_term(() -> print("BOO!"))
Task (runnable) @0x0000000013071710
As long as the terminal is alive, any change to its size will print BOO!
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With