Dans un programme Julia qui s'exécute sous Linux, je dois lancer une action dédiée lorsqu'une fenêtre de console est redimensionnée. Alors comment, dans Julia, puis-je intercepter le signal système SIGWINCH (redimensionnement de la fenêtre) et y attacher une fonction qui effectue l'action requise?
En Ada, il est assez simple de le déclarer:
protected Signalhandler is
procedure Handlewindowresizing;
pragma Attach_Handler (Handlewindowresizing, SIGWINCH);
end Signalhandler;
SOLUTION TENTATIVE BASÉE SUR L'IDÉE DE SCHEMER: J'essaie d'utiliser une bibliothèque C qui effectue la surveillance des interruptions SIGWINCH.
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 et préparation de la bibliothèque
gcc -c -Wall -fPIC myLibrary.c
gcc -shared -fPIC -o myLibrary.so myLibrary.o
Programme en Julia qui utilise la 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
Le programme Julia fonctionne correctement mais lorsque la fenêtre du terminal est redimensionnée, un défaut de segmentation (core dumped) est émis et le programme est dit quitté avec le code: 139.
La question est donc d'où vient ce défaut de segmentation? Du modèle de compilation? Julia n'a pas le droit de contrôler l'exécution du code dans la partie mémoire où C gère la surveillance du signal?
La suppression de l'opération println dans Sig_handler supprime l'erreur de segmentation:
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