1/* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: J.Wielemaker@vu.nl 5 WWW: http://www.swi-prolog.org 6 Copyright (c) 2000-2022, University of Amsterdam 7 VU University Amsterdam 8 SWI-Prolog Solutions b.v. 9 All rights reserved. 10 11 Redistribution and use in source and binary forms, with or without 12 modification, are permitted provided that the following conditions 13 are met: 14 15 1. Redistributions of source code must retain the above copyright 16 notice, this list of conditions and the following disclaimer. 17 18 2. Redistributions in binary form must reproduce the above copyright 19 notice, this list of conditions and the following disclaimer in 20 the documentation and/or other materials provided with the 21 distribution. 22 23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 POSSIBILITY OF SUCH DAMAGE. 35*/ 36 37:- module(unix, 38 [ fork/1, % -'client'|pid 39 exec/1, % +Command(...Args...) 40 fork_exec/1, % +Command(...Args...) 41 wait/2, % -Pid, -Reason 42 kill/2, % +Pid. +Signal 43 pipe/2, % +Read, +Write 44 dup/2, % +From, +To 45 detach_IO/0, 46 detach_IO/1, % +Stream 47 environ/1 % -[Name=Value] 48 ]).
64:- use_foreign_library(foreign(unix)).
Unix fork()
is the only way to create new processes and fork/1
is a simple direct interface to it.
88fork(Pid) :-
89 fork_warn_threads,
90 fork_(Pid).
96fork_warn_threads :- 97 set_prolog_gc_thread(stop), 98 findall(T, other_thread(T), Others), 99 ( Others == [] 100 -> true 101 ; throw(error(permission_error(fork, process, main), 102 context(_, running_threads(Others)))) 103 ). 104 105other_thread(T) :- 106 thread_self(Me), 107 thread_property(T, status(Status)), 108 T \== Me, 109 ( Status == running 110 -> true 111 ; print_message(warning, fork(join(T, Status))), 112 thread_join(T, _), 113 fail 114 ).
fork_exec(Command) :- ( fork(child) -> exec(Command) ; true ).
130fork_exec(Command) :-
131 ( fork_(child)
132 -> exec(Command)
133 ; true
134 ).
execvp()
. Here are some
examples:
exec(ls('-l'))
exec('/bin/ls'('-l', '/home/jan'))
Unix exec()
is the only way to start an executable file
executing. It is commonly used together with fork/1. For example
to start netscape on an URL in the background, do:
run_netscape(URL) :- ( fork(child), exec(netscape(URL)) ; true ).
Using this code, netscape remains part of the process-group of the invoking Prolog process and Prolog does not wait for netscape to terminate. The predicate wait/2 allows waiting for a child, while detach_IO/0 disconnects the child as a deamon process.
exited(ExitCode)
if the child with pid Pid was terminated by
calling exit()
(Prolog halt/1). ExitCode is the return status.
Status is unified with signaled(Signal)
if the child died due to
a software interrupt (see kill/2). Signal contains the signal
number. Finally, if the process suspended execution due to a
signal, Status is unified with stopped(Signal)
.SIG
prefix and mapping to lowercase. E.g. int
is the same as
SIGINT
in C. The meaning of the signal numbers can be found in
the Unix manual.:- use_module(library(unix)). fork_demo(Result) :- pipe(Read, Write), fork(Pid), ( Pid == child -> close(Read), format(Write, '~q.~n', [hello(world)]), flush_output(Write), halt ; close(Write), read(Read, Result), close(Read) ).
dup2()
, copying the underlying filedescriptor
and thus making both streams point to the same underlying
object. This is normally used together with fork/1 and pipe/2 to
talk to an external program that is designed to communicate
using standard I/O.
Both FromStream and ToStream either refer to a Prolog stream or
an integer descriptor number to refer directly to OS
descriptors. See also demo/pipe.pl
in the source-distribution of
this package.
user_input
, user_output
and
user_error
are closed if they are connected to a terminal
(see tty
property in stream_property/2). Input streams are
rebound to a dummy stream that returns EOF. Output streams are
reboud to forward their output to Stream.setsid()
if
provided or using ioctl()
TIOCNOTTY
on /dev/tty
.To ignore all output, it may be rebound to a null stream. For example:
..., open_null_stream(Out), detach_IO(Out).
The detach_IO/1 should be called only once per process. Subsequent calls silently succeed without any side effects.
/tmp/pl-out.<pid>
. Output is line buffered (see
set_stream/2).
270detach_IO :- 271 current_prolog_flag(pid, Pid), 272 atom_concat('/tmp/pl-out.', Pid, TmpFile), 273 open(TmpFile, write, Out, [alias(daemon_output)]), 274 set_stream(Out, buffer(line)), 275 detach_IO(Out). 276 277:- if(current_predicate(prctl/1)). 278:- export(prctl/1).
291:- endif. 292 293:- if(current_predicate(sysconf/1)). 294:- export(sysconf/1).
sysconf(1)
for details. Conf is
a term Config(Value), where Value is always an integer. Config
is the sysconf()
name after removing =_SC_= and conversion to
lowercase. Currently support the following configuration info:
arg_max
, child_max
, clk_tck
, open_max
, pagesize
,
phys_pages
, avphys_pages
, nprocessors_conf
and
nprocessors_onln
. Note that not all values may be supported on
all operating systems.307:- endif. 308 309 /******************************* 310 * MESSAGES * 311 *******************************/ 312 313:- multifile 314 prolog:message//1. 315 316prologmessage(fork(join(T, Status))) --> 317 [ 'Fork: joining thead ~p (status: ~p)'-[T, Status] ]
Unix specific operations
The library(unix) library provides the commonly used Unix primitives to deal with process management. These primitives are useful for many tasks, including server management, parallel computation, exploiting and controlling other processes, etc.
The predicates in this library are modelled closely after their native Unix counterparts.