Em um programa Julia executado no Linux, preciso iniciar uma ação dedicada quando uma janela do console é redimensionada. Então, como em Julia, posso interceptar o sinal do sistema SIGWINCH (redimensionamento de janela) e anexar a ele uma função que executa a ação necessária?
Em Ada, é bastante simples declará-lo:
protected Signalhandler is
procedure Handlewindowresizing;
pragma Attach_Handler (Handlewindowresizing, SIGWINCH);
end Signalhandler;
SOLUÇÃO TENTATIVA BASEADA NA IDÉIA DO ESQUEMA: Tento usar uma biblioteca C que conduz o monitoramento de interrupção do 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);
}
Compilação e preparação da biblioteca
gcc -c -Wall -fPIC myLibrary.c
gcc -shared -fPIC -o myLibrary.so myLibrary.o
Programa em Julia que usa a 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
O programa Julia é executado corretamente, mas quando a janela do terminal é redimensionada, uma falha de segmentação (núcleo despejado) é emitida e o programa é encerrado com o código: 139.
Portanto, a questão é de onde vem essa falha de segmentação? Do modelo de compilação? Julia não tem o direito de controlar a execução do código na parte da memória em que C gerencia o monitoramento do sinal?
A remoção da operação println no Sig_handler suprime a falha de segmentação:
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
Respostas:
Como ninguém respondeu a essa pergunta até agora, uma solução possível poderia ser o monitoramento assíncrono do tamanho do terminal em alguns intervalos de tempo.
E agora experimente o uso:
Enquanto o terminal estiver ativo, qualquer alteração em seu tamanho será impressa
BOO!
.fonte
Sim, é de fato uma solução alternativa que dificilmente é o que se espera de um novo idioma cheio de promessas ... mas, por falta de sapinhos, podemos realmente comer melros (sorriso).
Mas se Julia não planejou ser capaz de levar em conta os sinais do sistema do mundo Unix / Linux, talvez seja possível fazê-lo usando uma biblioteca C como a que o access.h acessa.
Teríamos que definir uma função julia fazendo o que é esperado quando o sinal do sistema é recebido. Torne-o utilizável em C como Sig_handler e chame de julia o sinal de instrução C (SIGWINCH, Sig_handler);
Não estou familiarizado o suficiente com julia para escrever o código exato. Mas essa é a ideia ...
fonte
ccal
) e depois quiser transformá-lo em um pacote Julia padrão, eu posso ajudar com o empacotamento.