Filter::Util::Exec#

📦 std

Source filters that run the source through a command: the text after the use line goes to the command’s standard input, and the compiler reads what the command writes.

Synopsis#

use Filter::exec qw(tr a-z A-Z);    # the command and its arguments
use Filter::sh 'tr a-z A-Z';        # a command line for sh -c
use Filter::cpp;                    # the C preprocessor
use Filter::m4;                     # m4

How it works#

Filter::Util::Exec::filter_add($module, $command, @args), which those four modules call from their import, forks and runs the command with a pipe on each side and installs a source filter. Each time the compiler wants more source, the filter writes the next lines of the file into the command’s input and reads what it has written back; when the file ends it closes the command’s input, and when the command’s output ends the filter removes itself. A command that cannot be run dies “execvp failed for command ‘NAME’: REASON”.

This is a native implementation of Exec.xs of Filter 1.65 (its Unix branch); its Filter/Util/Exec.pm is used unchanged, and so are the Filter::exec, Filter::sh, Filter::cpp and Filter::m4 built on it.

Differences from upstream#

Two, each where perl 5.44 with Exec.xs crashes or loses the program (t/81-xs-native/Filter/150-or-better.t):

  • filter_add while nothing is being compiled installs nothing and runs no command; perl5 segfaults.

  • A command that stops reading before the end of the source (head -n 1 on a file longer than the pipe holds) is read to the end of its output. perl5 dies of SIGPIPE without a word; with SIGPIPE ignored, it mostly drops what the command wrote and compiles an empty program.

Functions#

Source filters#

filter_add#

Run a command as a coprocess and filter the rest of the source through it.