В программе Julia, работающей под Linux, мне нужно запустить специальное действие при изменении размера окна консоли. Итак, как в Джулии я могу перехватить системный сигнал SIGWINCH (изменение размера окна) и добавить к нему функцию, которая выполняет требуемое действие?
В Аде объявить это довольно просто:
protected Signalhandler is
procedure Handlewindowresizing;
pragma Attach_Handler (Handlewindowresizing, SIGWINCH);
end Signalhandler;
ТЕНТАТИВНОЕ РЕШЕНИЕ НА ОСНОВЕ ИДЕИ ШЕМЕРА: Я пытаюсь использовать библиотеку C, которая проводит мониторинг прерываний 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);
}
Компиляция и подготовка библиотеки
gcc -c -Wall -fPIC myLibrary.c
gcc -shared -fPIC -o myLibrary.so myLibrary.o
Программа на Юлии, которая использует C-библиотеку:
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 работает правильно, но когда размер окна терминала изменяется, выдается ошибка сегментации (сбрасывается ядро) и программа выходит из программы с кодом: 139.
Таким образом, вопрос в том, откуда возникает эта ошибка сегментации? Из модели компиляции? Джулия не имеет права контролировать выполнение кода в той части памяти, где C управляет мониторингом сигналов?
Удаление операции println в Sig_handler подавляет ошибку сегментации:
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
Ответы:
Поскольку до сих пор никто не ответил на этот вопрос, одним из возможных обходных путей может быть асинхронный мониторинг размера терминала через некоторые промежутки времени.
А теперь пример использования:
Пока терминал активен, любое изменение его размера будет печататься
BOO!
.источник
Да, это действительно запасное решение, которого вряд ли можно ожидать от нового языка, полного обещаний ... но из-за отсутствия дроздов мы можем есть черных дроздов (улыбается).
Но если Джулия не планировала принимать во внимание системные сигналы мира Unix / Linux, это можно было бы сделать с помощью библиотеки C, подобной той, к которой обращается signal.h.
Мы должны были бы определить функцию julia, делающую то, что ожидается, когда системный сигнал получен. Сделайте его пригодным для использования в C как Sig_handler и вызовите от julia сигнал оператора C (SIGWINCH, Sig_handler);
Я недостаточно знаком с Юлией, чтобы написать точный код. Но это идея ...
источник
ccal
) и захотите позже превратить его в стандартный пакет Джулии, я могу помочь с его упаковкой.