module system/posix/pipe-abstractions
imports
system/posix/file
system/posix/process
strategies
// connecting and/or disconnecting parts of a pipe
// close both file descriptors constituting a pipe
close-pipe =
where(
?Pipe(fd1, fd2)
; <close> fd1
; <close> fd2
)
// connect the input side (fd1) of the pipe to stdin
stdin-from-pipe =
where(
?Pipe(fd1, fd2)
; <dup2> (fd1, <STDIN_FILENO>)
; <close> fd2
)
// create a file that is connected to input side (fd1) of the pipe
file-from-pipe :
Pipe(fd1, fd2) -> file
where <fdopen> (fd1, "r") => file
; <close> fd2
// connect the output side (fd2) of the pipe to stdout
stdout-to-pipe =
where(
?Pipe(fd1, fd2)
; <dup2> (fd2, <STDOUT_FILENO>)
; <close> fd1
)
// create a file that is connected to output side (fd2) of the pipe
file-to-pipe :
Pipe(fd1, fd2) -> file
where <fdopen> (fd2, "w") => file
; <close> fd1
write-term-to-text-pipe =
where(
?(p, t)
; <file-to-pipe> p => outfile
; <fprint> (outfile, [t])
; <fclose> outfile
)
read-term-from-pipe :
p -> t
where <file-from-pipe> p => file
; <ReadFromFile> file => t
; <fclose> file
strategies
// Programs that interact with pipes
// execute prog and write the current term to its stdin
write-to-prog(prog, args) =
where(
where(pipe => p)
; fork(<stdin-from-pipe> p
; <execvp> (<prog>, <args>))
; ?(pid, t)
; <write-term-to-text-pipe> (p, t)
; <waitpid> pid
; (exited + signaled + stopped)
)
write-to-prog'(prog, args) =
where(
?t
; pipe => p
; fork
; (?0 // child
; <stdin-from-pipe> p
; <execvp> (<prog>, <args>)
<+ ?pid // parent
; <write-term-to-text-pipe> (p, t)
; <waitpid> pid
; (exited + signaled + stopped))
)
// execute prog and read the term on its stdout
read-from-prog(prog, args) =
where(pipe => p)
; fork(<stdout-to-pipe> p; <execvp> (<prog>, <args>))
; ?(pid, _)
; <read-term-from-pipe> p => t
; where(<waitpid> pid
; (exited + signaled + stopped))
read-from-prog'(prog, args) =
where(
pipe => p
; fork
; (?0 // child
; <stdout-to-pipe> p
; <execvp> (<prog>, <args>)
<+ ?pid // parent
; <read-term-from-pipe> p
; where( <waitpid> pid
; (exited + signaled + stopped)))
)
strategies
// managing pipelines of filter programs
setup-filter-pipe =
pipe => p; !(p, [], p)
// prog produces input for the pipe p
pipe-source(prog, args) :
(p, pids) -> pids
where fork
; (?0; <stdout-to-pipe> p; <execvp> (<prog>, <args>)
<+ ?pid)
// prog consumes the output from pipe p
pipe-sink(prog, args) :
(p0, pids, p1) -> (p0, [pid | pids])
where fork(<stdin-from-pipe> p1; <execvp> (<prog>, <args>)) => (pid, _)
close-filter-pipe(s) :
(p-in, pids, p-out) -> (p-in, [pid | pids])
where <s> p-out => pid
exec-filter-pipe(s) :
(p-in, pids) -> ()
where <s> p-in => pid
; <map(waitpid; (exited + signaled + stopped))> [pid | pids]
spawn-filter-with-prog(prog, args) :
(p0, pids, p-in) -> (p0, [pid | pids], p-out)
where debug(<concat-strings> ["spawn-filter-with ", <prog>, ": "])
; pipe => p-out
; fork(<stdin-from-pipe> p-in
; <stdout-to-pipe> p-out
; <execvp> (<prog>, <args>)) => (pid, _)
//; <close-pipe> p-in
/*
file-to-file-filter(!infile, !outfile) :
(p-in, pids, p-out) ->
where <fopen> infile
pipe-comm(prog, args, cont) :
?fd;
*/