1

Тема: Процедура Halt в Free Pascal

В описі процедури Halt для Free Pascal (https://www.freepascal.org/docs-html-3. … /halt.html) вказано тип для коду виходу як Longint. Але реально програма при зупинці повертає код виходу не більше ніж 255  :(
Чому так ?

Подякували: leofun011

2

Re: Процедура Halt в Free Pascal

Взагалі це залежить від ОС. Цілком можлива ситуація, коли програма повертає код, а ОС його не сприймає, і він відкидається.
Ну і розкажіть іще, як ви перевіряєте код виходу.

Подякували: Torbins, leofun012

3

Re: Процедура Halt в Free Pascal

https://en.wikipedia.org/wiki/Exit_status#POSIX
wait та waitpid беруть лише нижні 8 біт (в старих системах повертався char). waitid повертає 32 біти.
У Windows повертається 32 біти.

Подякували: Chemist-i, Torbins, leofun013

4

Re: Процедура Halt в Free Pascal

koala написав:

Взагалі це залежить від ОС. Цілком можлива ситуація, коли програма повертає код, а ОС його не сприймає, і він відкидається.
Ну і розкажіть іще, як ви перевіряєте код виходу.

ОС:  Linux Mint 19.1 Tessa 64-біт, ядро Linux 4.15.0-54-generic x86_64

program test;
var exitcode:longint;
BEGIN
 Write('Enter exit code: '); Readln(exitcode);
 Halt(exitcode);
END.

Перевіряю код виходу bash-скриптом:

#!/bin/bash
./test
echo $?

До 255 все співпадає. Якщо ввести число більше 255 -- результат завжди 255.
Не можу повірити, щоб у linux коди виходу були настільки ж "кастровані" як в MS-DOS ...

Подякували: leofun011

5

Re: Процедура Halt в Free Pascal

Ці коди мають використовуватися для повідомлення про помилку. Ваша програма має більш ніж 255 різних станів помилок? Додавайте логи тоді.
Є інші оболонки, які (за певних налаштувань) видають повний код. Але всі вже так звикли.

6

Re: Процедура Halt в Free Pascal

koala написав:

Ці коди мають використовуватися для повідомлення про помилку. Ваша програма має більш ніж 255 різних станів помилок? Додавайте логи тоді.
Є інші оболонки, які (за певних налаштувань) видають повний код. Але всі вже так звикли.

Код виходу не обов'язково може використовуватися при виникненні помилки. Згадайте MS-DOS (тоді часто писали програми, антивіруси, наприклад, які в залежності від результатів виконання повертали різний код, що можна було використати для подальшого запуску інших програм).
Особисто я планував використовувати коди виходу для подальшого використання в bash-скриптах. Чому більше 255 ? В залежності від результатів виконання програми (а може бути отримано декілька результатів одночасно) встановлювався окремий біт в кодові виходу (з "питомою вагою" 1,2,4,8,16 ... і т.д., відповідно при декількох результатах в сумі виходило число значно більше 255 якщо бітів більше 8 ). Далі в скриптах ці біти відсіювалися по масці (наприклад, "$exitcode & 32"), і якщо біт був встановлений -- запускався необхідний сторонній процес.
Судячи з усього код виходу не вдасться використати, тому в мене виникла інша думка -- передавати числовий результат виконання програми через змінну середовища. От тільки як її створити з програми pascal -- я не знаю (отримати можна, є функція - GetEnv).
Можливо Ви підкажете ? Або порекомендуєте інший спосіб передати результат виконання в іншу програму ?
Не зрозуміло, тільки, на біса в Free Pascal передбачено тип для коду завершення аж цілий longint ?

7 Востаннє редагувалося ReAl (29.07.2019 18:15:39)

Re: Процедура Halt в Free Pascal

Друкуйте в кінці роботи програми на вихід текстовий рядок з потрібним числом, потім у скрипті щось в дусі

haltcode=$(test)

Якщо програма друкує багато та ще й на вхід щось бере, то треба подумати.

printf("Nested comments is %s\n", */*/**/"*/"/*"/**/ == '*' ? "OFF" : "ON");
Подякували: bunyk, hadeix2

8

Re: Процедура Halt в Free Pascal

ReAl випередив. Можна друкувати JSON з полями які хочемо, і тоді отримувати доступ наприклад через jq:


RES=$(echo '{"a": 1, "b": 300}') # тут в дужках виклик вашої програми
A=$(echo $RES | jq '.a') # так можна окремі поля отримати
B=$(echo $RES | jq '.b')

echo $A, $B
Подякували: hadeix1

9 Востаннє редагувалося hadeix (29.07.2019 20:07:42)

Re: Процедура Halt в Free Pascal

ReAl написав:

Якщо програма друкує багато та ще й на вхід щось бере, то треба подумати.

Як варіант в інших випадках -- цікава пропозиція. Дякую !
Але ... програма (назвемо її CGI-процесор) будучи запущеною web-сервером (apache2) в ході роботи заповнює html-шаблон та виводить все в stdout, тому зайві "викиди" в stdout дещо зіпсують вигляд сторінки  *PARDON*.  І, боюся, якщо спробувати так як Ви пропонували:

haltcode=$(test)

Все що програма виводитиме в stdout попаде в haltcode, а не по призначенню.
Тому потрібно передати результат якось інакше. Наприклад, було б дуже гарно через змінну середовища, але поки що не знаю як її створити  для дочірніх процесів :(  От читати змінні середовища можна запросто.

10 Востаннє редагувалося hadeix (29.07.2019 21:25:24)

Re: Процедура Halt в Free Pascal

Тимчасово виплутався із ситуації слідуючим чином:
з програми створюю файл, назвемо його exitcodefile, куди записую код завершення програми, а в bash-скрипту читаю його вміст в змінну, яку потім аналізую як звичайно. Наприклад:

#!/bin/bash
read EXITCODE < exitcodefile
echo $EXITCODE

Все запрацювало так як хотілося, але можливо хтось підскаже кращий спосіб передачі результату виконання в інший процес.

Подякували: ReAl1

11 Востаннє редагувалося ReAl (29.07.2019 21:50:58)

Re: Процедура Halt в Free Pascal

(вже доїхав додому)

Ну тоді так (я не знаю, як то у паскалях).
p.c

#include <stdio.h>

int main()
{
    unsigned int n;
    printf("Input n=");
    scanf("%u", &n);
    printf("Ok, n=%u\n", n);
    printf("Lorem ipsum... You know...\n");

    fprintf(stderr, "%u\n", n);

    return 0;
}

t.sh

#
read haltcode
echo
echo t.sh receives haltcode=$haltcode

process substitution (між двома > пробіл)

$ ./p 2> >(./t.sh)
Input n=5
Ok, n=5
Lorem ipsum... You know...

t.sh receives haltcode=5

Тобто там вже з підпорядкованого скрипта можна щось зробити.

p.s. не бачив попереднього, бо відволікся, а тоді просто не дивлячись дописав і тицьнув ентер.

printf("Nested comments is %s\n", */*/**/"*/"/*"/**/ == '*' ? "OFF" : "ON");
Подякували: leofun01, hadeix2

12

Re: Процедура Halt в Free Pascal

Хоча... той підпорядкований скрипт теж може щось друкувати і куди воно полетить… Все одно тоді у файл писати.
Це треба шматок навколо рівнем вище, а тоді думати.

printf("Nested comments is %s\n", */*/**/"*/"/*"/**/ == '*' ? "OFF" : "ON");

13 Востаннє редагувалося hadeix (30.07.2019 00:12:55)

Re: Процедура Halt в Free Pascal

ReAl написав:

Хоча... той підпорядкований скрипт теж може щось друкувати і куди воно полетить… Все одно тоді у файл писати.
Це треба шматок навколо рівнем вище, а тоді думати.

Ви підкинули сішним прикладом іще одну ідею: вивести результат не в stdout чи файл, а в sdterr, а там перехопити цей вивід в змінну ...
Треба поекспериментувати.

14 Востаннє редагувалося koala (30.07.2019 00:53:45)

Re: Процедура Halt в Free Pascal

hadeix написав:

Код виходу не обов'язково може використовуватися при виникненні помилки.

Так. А імена файлів не обов'язково мають використовуватися для іменування, в них можна невеликі дані зберігати... АЛЕ НАЩО? Як олімпіадну задачу чи при значній нестачі ресурсів це ще можна зрозуміти; але для реальної роботи?

hadeix написав:

Згадайте MS-DOS (тоді часто писали програми, антивіруси, наприклад, які в залежності від результатів виконання повертали різний код, що можна було використати для подальшого запуску інших програм).

Так, ранні версії DOS дуже погано працювали зі змінними та пайпами (та й надалі не дуже), а дискети були ДУЖЕ повільні, тому й доводилося використовувати такі збочення.

hadeix написав:

Можливо Ви підкажете ? Або порекомендуєте інший спосіб передати результат виконання в іншу програму ?

OUTPUT="$(./test 123)"
echo ${OUTPUT}

де сирець test виглядає приблизно як

begin
  writeln(ParamStr(1));
end.
hadeix написав:

Не зрозуміло, тільки, на біса в Free Pascal передбачено тип для коду завершення аж цілий longint ?

Бо це bash ріже код помилки. Ви можете, ще раз, запитувати його через системний виклик waitid. Ну і навіть якби це була вада Linux, то все одно FPC багатоплатформовий.

Подякували: leofun011

15

Re: Процедура Halt в Free Pascal

koala написав:
OUTPUT="$(./test 123)"
echo ${OUTPUT}

де сирець test виглядає приблизно як

 begin
  writeln(ParamStr(1));
 end.

Я трішки вище пояснював що мені зовсім небажано виводити результат в stdout. Є думка вивести в stderr, а потім прочитати звідти.

16

Re: Процедура Halt в Free Pascal

Можете пояснити - якщо програма генерує сторінку, то що саме ви хочете передавати ще на виході? Яку інформацію?
stderr - не повірите - теж призначений для виведення інформації про помилки. У вас якась манія використовувати канали для інформації про помилки не за призначенням.

Подякували: leofun011

17

Re: Процедура Halt в Free Pascal

Ще питання. Програма має працювати через CGI, а ви її викликаєте з bash-скрипта. Ви точно певні, що знаєте, що робите?

18

Re: Процедура Halt в Free Pascal

hadeix
Окрім стандартних пайпів типу stdout та stderr можна ще й свої власні створювати. Правда я щось не в курсі, як там баш з ними дружить.
Але взагалі, CGI - то дуже тормозний АПІ, і краще використовувати щось інше.

19 Востаннє редагувалося hadeix (30.07.2019 17:13:48)

Re: Процедура Halt в Free Pascal

koala написав:

Ще питання. Програма має працювати через CGI, а ви її викликаєте з bash-скрипта. Ви точно певні, що знаєте, що робите?

Вона не обов'язково працює через CGI. Програма може виконувати багато функцій (в тому числі цілком пристойну авторизацію користувача), і може в одних випадках викликатися web-сервером безпосередньо з html через CGI, або ж із html може запускатися звичайний bash-скрипт (звісно, теж через CGI), в тілі якого в залежності від умов запускається дана програма для виконання інших функцій (наприклад, просто з ціллю формування web-сторінки по шаблону. Тобто читає html-шаблон, замінює там аліаси на потрібні значення та виводить результат в stdout).
Такий собі універсальний інструмент для простенького і легенького web-сервера  без зайвих "наворотів" що виконує специфічні задачі.
В перспективі планується розгорнути його на дешевому Raspberry Pi, тому в ресурсах є обмеження.
Я взагалі не маю досвіду у цій справі, тому пішов своїм шляхом, використовуючи ті знання що вже маю. Так виявилося швидше. Тим більше задачу практично вирішено (вже все працює). Тільки мені не подобається передача параметрів іншому процесу через файл.

20

Re: Процедура Halt в Free Pascal

Torbins написав:

hadeix
Окрім стандартних пайпів типу stdout та stderr можна ще й свої власні створювати. Правда я щось не в курсі, як там баш з ними дружить.
Але взагалі, CGI - то дуже тормозний АПІ, і краще використовувати щось інше.

Аж ніяк не заперечую. Але CGI дуже простий, його можна швидко освоїти. А для моїх задач його цілком достатньо.