[WIP] add support to spawn new processes
This commit is contained in:
@@ -82,6 +82,9 @@ must_be_(octet_chars, Cs) :-
|
||||
; true
|
||||
).
|
||||
must_be_(list, Term) :- check_(error:ilist, list, Term).
|
||||
must_be_(list(Elem), Term) :-
|
||||
must_be_(list, Term),
|
||||
check_all(Elem, Term).
|
||||
must_be_(type, Term) :- check_(error:type, type, Term).
|
||||
must_be_(boolean, Term) :- check_(error:boolean, boolean, Term).
|
||||
must_be_(pair, Term) :- check_(error:pair, pair, Term).
|
||||
@@ -96,10 +99,12 @@ must_be_(term, Term) :-
|
||||
% We cannot use maplist(must_be(character), Cs), because library(lists)
|
||||
% uses library(error), so importing it would create a cyclic dependency.
|
||||
|
||||
all_characters([]).
|
||||
all_characters([C|Cs]) :-
|
||||
must_be(character, C),
|
||||
all_characters(Cs).
|
||||
check_all(_, []).
|
||||
check_all(Type, [Head| Tail]) :-
|
||||
must_be(Type, Head),
|
||||
check_all(Type, Tail).
|
||||
|
||||
all_characters(Cs) :- check_all(character, Cs).
|
||||
|
||||
check_(Pred, Type, Term) :-
|
||||
( var(Term) -> instantiation_error(must_be/2)
|
||||
@@ -141,6 +146,7 @@ type(octet_character).
|
||||
type(octet_chars).
|
||||
type(chars).
|
||||
type(list).
|
||||
type(list(Type)) :- type(Type).
|
||||
type(var).
|
||||
type(boolean).
|
||||
type(term).
|
||||
|
||||
52
src/lib/process.pl
Normal file
52
src/lib/process.pl
Normal file
@@ -0,0 +1,52 @@
|
||||
:- module(process, [process_create/3]).
|
||||
|
||||
:- use_module(library(error)).
|
||||
:- use_module(library(iso_ext)).
|
||||
:- use_module(library(lists), [append/3, member/2]).
|
||||
|
||||
process_create(Exe, Args, Options) :-
|
||||
must_be(chars, Exe),
|
||||
must_be(list(chars), Args),
|
||||
must_be(list, Options),
|
||||
check_option(Sin, find_stdio(Sin, stdin, Options), valid_stdio, [std], Stdin),
|
||||
check_option(Sout, find_stdio(Sout, stdout, Options), valid_stdio, [std], Stdout),
|
||||
check_option(Serr, find_stdio(Serr, stderr, Options), valid_stdio, [std], Stderr),
|
||||
check_option(Envs, find_env(Envs, Options), valid_env, [environment, []], EnvVars),
|
||||
check_option(P, member(process(P), Options), valid_pid, _, Pid),
|
||||
check_option(C, member(cwd(C), Options), valid_cwd, _, Cwd),
|
||||
'$process_create'(Exe, Args, Stdin, Stdout, Stderr, EnvVars, Cwd, Pid).
|
||||
|
||||
|
||||
check_option(Template, Goal, Pred, Default, Choice) :-
|
||||
findall(Template, Goal, Solutions),
|
||||
check_option_(Solutions, Pred, Default, Choice).
|
||||
|
||||
check_option_([] , Pred , Default , Default ) :- call(Pred, Default).
|
||||
check_option_([Choice] , Pred , _ , Choice ) :- call(Pred, Choice).
|
||||
check_option_([X1,X2|Xs], _ , _ , _ ) :- throw(error(duplicate_option, process_create/3, [X1, X2 | Xs])).
|
||||
|
||||
find_stdio([std], Kind, Options ) :- Elem =.. [Kind, std], member(Elem, Options).
|
||||
find_stdio([null], Kind, Options ) :- Elem =.. [Kind, null], member(Elem, Options).
|
||||
find_stdio([pipe, Stream], Kind, Options) :- Elem =.. [Kind, pipe(Stream)], member(Elem, Options).
|
||||
find_stdio([file, Path], Kind, Options ) :- Elem =.. [Kind, file(Path)], member(Elem, Options).
|
||||
|
||||
valid_stdio([std]).
|
||||
valid_stdio([null]).
|
||||
valid_stdio([pipe, Stream]) :- must_be(var, Stream).
|
||||
valid_stdio([file, Path]) :- must_be(chars, Path).
|
||||
|
||||
find_env([env, E], Options) :- member(env(E), Options).
|
||||
find_env([environment, E], Options) :- member(environment(E), Options).
|
||||
|
||||
valid_cwd(Cwd) :- must_be(chars, Cwd).
|
||||
|
||||
valid_env([env, E]) :- valid_env_(E).
|
||||
valid_env([environment, E]) :- valid_env_(E).
|
||||
|
||||
valid_env_([]).
|
||||
valid_env_([N=V|Es]) :-
|
||||
must_be(chars, N),
|
||||
must_be(chars, V),
|
||||
valid_env_(Es).
|
||||
|
||||
valid_pid(Pid) :- must_be(var, Pid).
|
||||
Reference in New Issue
Block a user