Linux altında çalışan bir Julia programında, bir konsol penceresi yeniden boyutlandırıldığında özel bir eylem başlatmam gerekiyor. Peki Julia'da SIGWINCH (pencere yeniden boyutlandırma) sistem sinyalini nasıl kesebilir ve ona gerekli eylemi gerçekleştiren bir işlev ekleyebilir miyim?
Ada'da beyan etmek oldukça basittir:
protected Signalhandler is
procedure Handlewindowresizing;
pragma Attach_Handler (Handlewindowresizing, SIGWINCH);
end Signalhandler;
SCHEMER FİKİRİNE DAYALI ÇADIRLI ÇÖZÜM: SIGWINCH kesinti izlemesini yürüten bir C Kütüphanesi kullanmaya çalışıyorum.
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);
}
Derleme ve Kütüphane Hazırlığı
gcc -c -Duvar -fPIC myLibrary.c
gcc -shared -fPIC -o myLibrary.so myLibrary.o
Julia'da C Kütüphanesini kullanan program:
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
Julia programı düzgün çalışıyor, ancak terminal penceresi yeniden boyutlandırıldığında bir Segmentasyon hatası (çekirdek dökümü) yayınlanıyor ve program kod: 139 ile çıkarıldı.
Soru şu; bu segmentasyon hatası nereden geliyor? Derleme modelinden mi? Julia'nın C'nin sinyal izlemeyi yönettiği bellek bölümünde kod yürütülmesini kontrol etme hakkı yok mu?
Sig_handler'da println işleminin kaldırılması segmentasyon hatasını bastırır:
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