Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Выйти из консольного приложения Linux правильно  [new]
cptngrb
Member

Откуда:
Сообщений: 157
В начале было слово)
В начале было так

begin
try 
Writeln('началось...');
    StartService;
    Writeln('Для остановки приложения нажмите <Enter>...');
    Readln;
    StopService;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
end;


Запускалось приложение, запускались потоки, ждали в консоли Enter, завершали потоки.
Потом задача усложнилась и мне стало нужно проверять пару параметров (если вдруг аварийное завершение работы)

try
    Writeln('началось');
    StartService;
    Writeln('Для остановки приложения нажмите <Ctrl+C>...'); //<Enter>
//    Readln;
    while (err_1 = 0) and (err_2 = 0) and (ERR_3 = 0) do
    begin
      sleep(1000);
    end;
    StopService;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;


Подскажите, есть readConsoleInput - можно отслеживать для Windows, а как быть для Linux?
24 апр 18, 15:18    [21364862]     Ответить | Цитировать Сообщить модератору
 Re: Выйти из консольного приложения Linux правильно  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 45257

cptngrb
Подскажите, есть readConsoleInput - можно отслеживать для Windows, а как быть для Linux?

sigaction(SIGTERM, &act, NULL); (* software termination signal from kill *)
sigaction(SIGINT, &act, NULL); (* Ctrl-C pressed *)

Posted via ActualForum NNTP Server 1.5

24 апр 18, 15:41    [21364981]     Ответить | Цитировать Сообщить модератору
 Re: Выйти из консольного приложения Linux правильно  [new]
rashid.abzalov
Member

Откуда:
Сообщений: 61
Dimitry Sibiryakov,

Если в Delphi (не знаю как в fpc), то номер может не выйти, т.к. в System.Internal.ExcUtils.pas уже назначен обработчик SignalDispatcher для сигналов на которых строится механика RTL для отлова и обработки hardware-ошибок.

Возможно стоит посмотреть в сторону pthread_sigmask(SIG_BLOCK, ... и sigwait.
24 апр 18, 17:51    [21365536]     Ответить | Цитировать Сообщить модератору
 Re: Выйти из консольного приложения Linux правильно  [new]
cptngrb
Member

Откуда:
Сообщений: 157
немного покопался, почитал. получается что-то типа такого, но сигнал не ловиться

uses Posix.Signal;

procedure SignalHandler(SigNum: Integer); cdecl;
begin
  WriteLn('SigNum (', SigNum, ') arrived.');
  case SigNum of
    SIGTERM, SIGINT: APP_EXIT:= 1;
  else
    WriteLn('SigNum (', SigNum, ') not handled.');
  end;
  Signal(SigNum, @SignalHandler); // catch the signal again
end;

begin
 
  try
    Writeln('началось...');
    StartService;
    Writeln('Для остановки приложения нажмите <Ctrl+C>...');
//    Readln;
    while (err_1 = 0) and (err_2 = 0) and (ERR_3 = 0) do
    begin
      Signal(SIGINT, @SignalHandler);
      sleep(1000);
    end;
    StopService;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.


нашел еще вариант, тоже не ловиться

procedure SignalSet(aProc : TSignalHandler);
var
  smask: sigset_t;
  act: sigaction_t;
begin
  sigemptyset(smask);
  sigaddset(smask,SIGINT);
  sigaddset(smask,SIGTERM);
  act._u.sa_handler := aProc;
  act.sa_mask := smask;
  act.sa_flags := 0;

  sigaction(SIGINT, @act, nil);
  sigaction(SIGTERM, @act, nil);
end;
25 апр 18, 08:14    [21366564]     Ответить | Цитировать Сообщить модератору
 Re: Выйти из консольного приложения Linux правильно  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2612
cptngrb,

У себя ловлю сигналы так:

procedure DoSig(signal: longint; info: psiginfo; context: psigcontext); cdecl;
 begin
  case signal of
   //SIGHUP : bHup := true;
   SIGTERM: Prg.Terminate;
   SIGSTOP: Prg.Terminate;
  end;
 end;

 function SignalSet: longint;
 var
  smask: TSigset;
  act: sigactionrec;
 begin
  Result := 0;
  (* Signal mask setting *)
  FpsigEmptySet(smask);
  FpSigAddSet(smask, SIGSTOP);
  FpSigAddSet(smask, SIGTERM);
  act.sa_handler := SigactionHandler(@DoSig);
  act.sa_mask  := smask;
  act.sa_flags := 0;
  (* Signal exit function registered *)
  if FPSigaction(SIGSTOP, @act, nil) <> 0 then
   Result := fpgeterrno;
  if FPSigaction(SIGTERM, @act, nil) <> 0 then
   Result := fpgeterrno;
 end;
25 апр 18, 18:05    [21368830]     Ответить | Цитировать Сообщить модератору
 Re: Выйти из консольного приложения Linux правильно  [new]
cptngrb
Member

Откуда:
Сообщений: 157
makhaon, а что такое psiginfo, psigcontext?
А это
FpsigEmptySet(smask);
  FpSigAddSet(smask, SIGSTOP);
  FpSigAddSet(smask, SIGTERM);
  act.sa_handler := SigactionHandler(@DoSig);
  act.sa_mask  := smask;
  act.sa_flags := 0;


тоже самое как

 sigemptyset(smask);
  sigaddset(smask,SIGINT);
  sigaddset(smask,SIGTERM);
  act._u.sa_handler := aProc;
  act.sa_mask := smask;
  act.sa_flags := 0;


только процедур нет FpsigEmptySet, FpSigAddSet.
может модуль какой не подключил или это не Delphi (в моем случае Tokyo 10.2)?
26 апр 18, 08:19    [21369842]     Ответить | Цитировать Сообщить модератору
 Re: Выйти из консольного приложения Linux правильно  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2612
cptngrb,

FPC
26 апр 18, 15:56    [21371387]     Ответить | Цитировать Сообщить модератору
 Re: Выйти из консольного приложения Linux правильно  [new]
cptngrb
Member

Откуда:
Сообщений: 157
Добрались руки до теста..
Сигнал SIGTERM ловиться если завершить процесс через диспетчер задач, а вот сигнал SIGINT не ловиться, если в консоле нажать <Ctrl-C>.
А мне более важно ловить SIGINT. Причем консоль закрывается, а процесс остается.
Объясните, как так?

P/S Линукс для меня шайтанОС
6 июл 18, 11:56    [21548965]     Ответить | Цитировать Сообщить модератору
 Re: Выйти из консольного приложения Linux правильно  [new]
cptngrb
Member

Откуда:
Сообщений: 157
SIGTSTP ловить из диспетчера задач, а из консоли нет ((
короче из консоли ничего не ловиться, может другие сигналы?
6 июл 18, 12:04    [21548999]     Ответить | Цитировать Сообщить модератору
 Re: Выйти из консольного приложения Linux правильно  [new]
rashid.abzalov
Member

Откуда:
Сообщений: 61
cptngrb,

Если SIGINT ловишь под отладчиком, то там баг - RSP-18540. Без отладчика все ловится нормально.
6 июл 18, 19:37    [21550683]     Ответить | Цитировать Сообщить модератору
 Re: Выйти из консольного приложения Linux правильно  [new]
cptngrb
Member

Откуда:
Сообщений: 157
rashid.abzalov, точно. Спасибо. Действительно под отладчиком не срабатывает, а если запускать отдельно, то все хорошо.
9 июл 18, 09:41    [21555072]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить