Пролог: process_create не работает внутри http_handler - PullRequest
0 голосов
/ 03 февраля 2020

Я пытаюсь изменить свой веб-сайт, чтобы пользователи могли вызывать определенную программу, над которой я работаю. Когда я использую process_create/3 в Прологе «нормально», т.е. из REPL, то все работает нормально. Однако, когда я пытаюсь вызвать его изнутри обработчика HTTP, все возвращает некоторый ненулевой код выхода (ls дает мне 2, pwd и echo дает мне 1, и т. Д. c.). Ниже приведена полная, простая программа, которая демонстрирует это:

:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_unix_daemon)).

:- use_module(library(process)).

:- initialization(start_server, main).

:- http_handler(root('run'), try_run, []).

start_server :-
    try_run(_),
    http_daemon([port(8080), user(root)]).

try_run(_Request) :-
    format('Content-type: text/plain~n~n', []),
    setup_call_cleanup(
        process_create(path(echo), ['hello world'], [process(PID)]),
        true,
        process_wait(PID, Code)),
    format('exited with: ~w~n', [Code]).

Очевидно, что запуск под root не идеален, но я хотел убедиться, что не было ошибок разрешения или чего-либо еще.

Выше мы видим, что если мы просто запустим запуск сервера, вызов try_run/1 будет работать внутри start_server/0.

roei@roei-main:~$ swipl --version
SWI-Prolog version 8.0.3 for x86_64-linux
roei@roei-main:~/Prolog/website$ sudo swipl t.pl
Content-type: text/plain

hello world
exited with: exit(0)

Но если я попытаюсь сделать запрос:

roei@roei-main:~/Prolog/website$ curl -X POST localhost:8080/run
exited with: exit(1)

Я использую Ubuntu 18.04.

1 Ответ

0 голосов
/ 03 февраля 2020

Похоже, проблема в том, что то, что process_create/3 использует в качестве выходного потока по умолчанию, не может быть записано по какой-либо причине. Но если я изменю его на:

try_run(_Request) :-
    format('Content-type: text/plain~n~n', []),
    setup_call_cleanup(
        process_create(path(echo), ['hello world'], [process(PID), stdout(pipe(Stream))]),
        true,
        process_wait(PID, Code)),
    current_output(Out),
    copy_stream_data(Stream, Out),
    format('exited with: ~w~n', [Code]).

, т. Е. Вручную настроив выходной поток, он будет работать.

...