summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/perltex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-09-20 23:29:41 +0000
committerKarl Berry <karl@freefriends.org>2009-09-20 23:29:41 +0000
commit2c20e449c234f30eb26e3cbbd9cd48b281842a37 (patch)
tree60bd80b52ddd7f2e6250c5ab90e047ad455fa475 /Master/texmf-dist/source/latex/perltex
parentb209fd55656d0a2b7714c317d2a6656af4b1505e (diff)
perltex 1.9 (20sep09)
git-svn-id: svn://tug.org/texlive/trunk@15387 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/perltex')
-rw-r--r--Master/texmf-dist/source/latex/perltex/perltex.dtx319
1 files changed, 203 insertions, 116 deletions
diff --git a/Master/texmf-dist/source/latex/perltex/perltex.dtx b/Master/texmf-dist/source/latex/perltex/perltex.dtx
index 51d6ae342fa..ea9bee773ea 100644
--- a/Master/texmf-dist/source/latex/perltex/perltex.dtx
+++ b/Master/texmf-dist/source/latex/perltex/perltex.dtx
@@ -22,7 +22,7 @@
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{perltex}
%<*package>
- [2009/03/27 v1.8 LaTeX macros for use with PerlTeX]
+ [2009/09/13 v1.9 LaTeX macros for use with PerlTeX]
%</package>
%
%<*driver>
@@ -62,7 +62,7 @@
%</driver>
% \fi
%
-% \CheckSum{594}
+% \CheckSum{597}
%
% \CharacterTable
% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
@@ -130,6 +130,10 @@
% \newcommand{\XeTeX}{^^A ^^A Name of the typesetting system
% X\lower0.5ex\hbox{\kern-0.15em\reflectbox{E}}\kern-0.1667em\TeX^^A
% }
+% \newcommand{\signal}[1]{^^A ^^A Signal handler
+% \lowercase{\textsc{sig#1}}^^A
+% \index{SIG#1=\lowercase{\textsc{sig#1}}}^^A
+% }
%
% ^^A Typeset package options.
% \newcommand{\DescribeOption}[1]{^^A
@@ -141,9 +145,28 @@
% }
%
%
+% ^^A Define an environment just like macro but for Perl subroutines
+% \makeatletter
+% \newenvironment{perlsub}{^^A
+% \begingroup
+% \catcode`\_=11
+% \def\PrintMacroName##1{\strut\MacroFont\string##1\ }^^A
+% \def\SpecialIndex@##1##2{^^A
+% \@bsphack
+% \special@index{\string##1\actualchar
+% \string\verb\quotechar*\verbatimchar##1\verbatimchar##2}^^A
+% \@esphack
+% }^^A
+% \begin{macro}^^A
+% }{^^A
+% \end{macro}^^A
+% \endgroup
+% }
+% \makeatother
+%
% ^^A Define an environment just like macro but for Perl scalars or lists.
% \makeatletter
-% \newenvironment{perlmacro}[1]{^^A
+% \newenvironment{perlvar}{^^A
% \begingroup
% \catcode`\_=11
% \def\PrintMacroName##1{\strut\MacroFont\string##1\ }^^A
@@ -153,7 +176,7 @@
% \string\verb\quotechar*\verbatimchar\string##1\verbatimchar##2}^^A
% \@esphack
% }^^A
-% \begin{macro}{#1}^^A
+% \begin{macro}^^A
% }{^^A
% \end{macro}^^A
% \endgroup
@@ -753,7 +776,7 @@
% non-stop-word using the URL template. Contractions (words containing
% apostrophes) are ignored. Finally, |\dolinkwords| replaces the dummy
% sequences with the corresponding \LaTeX\ text and returns the result.
-%
+%
% The |linkwords| environment itself is defined using the |\NewEnviron|
% macro from the \pkgname{environ} package. With |\NewEnviron|'s help,
% |linkwords| accumulates its body into a |\BODY| macro and passes that
@@ -772,7 +795,7 @@
% a document that can compile even without \perlmac\ installed, replace
% the |\usepackage[optional]{perltex}| line with the following
% \LaTeX\ code:
-%
+%
% \begin{samepage}
% \begin{verbatim}
% \IfFileExists{perltex.sty}
@@ -835,7 +858,7 @@
# Replace LaTeX code in the text with placeholders.
$placeholder = "ABCxyz123";
- %substs;
+ %substs = ();
$replace = sub {$substs{$placeholder} = $_[0]; $placeholder++};
$text =~ s/\\(begin|end)\s+\{[a-z]+\}/$replace->($&)/gse;
$text =~ s/\\[a-z]+/$replace->($&)/gse;
@@ -1840,10 +1863,10 @@
% & & & & Delete & \topl \\
% & & & & Delete & \dfpl \\
% & Await & \ffpl & $\leftarrow$ & Touch & \ffpl \\
-% & Read & \frpl & & & \\
% & Touch & \topl & $\rightarrow$ & Await & \topl \\
% & & & & Delete & \ffpl \\
% & Await & \dfpl & $\leftarrow$ & Touch & \dfpl \\
+% & Read & \frpl & & & \\
% \cline{2-3}\cline{5-6}
% \end{tabular}
% \MakeShortVerb\|
@@ -1851,7 +1874,17 @@
% \label{fig:comm-protocol}
% \end{figure}
%
+% Although Figure~\ref{fig:comm-protocol} shows the read of
+% |\plmac@fromfile| as the final step of the protocol, the file's
+% contents are in fact valid as soon as \LaTeX{} detects that
+% |\plmac@fromflag| exists. Deferring the read to the end, however,
+% enables \PerlTeX{} to support recursive macro invocations.
+%
% \begin{macro}{\plmac@await@existence}
+% \changes{v1.9}{2009/09/13}{Put the
+% \texttt{\string\string\string\input\string\string\string\plmac@pipe}
+% within an \texttt{lrbox} environment to prevent a partial read from
+% introducing spurious text into the document}
% \begin{macro}{\ifplmac@file@exists}
% \begin{macro}{\plmac@file@existstrue}
% \begin{macro}{\plmac@file@existsfalse}
@@ -1863,12 +1896,13 @@
%
% As a performance optimization we |\input| a named pipe. This causes
% the |latex| process to relinquish the CPU until the |perltex| process
-% writes data (always just ``|\endinput|'') into the named pipe. On
-% systems that don't support persistent named pipes (e.g.,~Microsoft
-% Windows), |\plmac@pipe| is an ordinary file containing only
-% ``|\endinput|''. While reading that file is not guaranteed to
-% relinquish the CPU, it should not hurt the performance or correctness
-% of the communication protocol between \LaTeX\ and Perl.
+% writes data (always just a comment plus ``|\endinput|'') into the
+% named pipe. On systems that don't support persistent named pipes
+% (e.g.,~Microsoft Windows), |\plmac@pipe| is an ordinary file
+% containing only a comment plus ``|\endinput|''. While reading that
+% file is not guaranteed to relinquish the CPU, it should not hurt the
+% performance or correctness of the communication protocol between
+% \LaTeX\ and Perl.
% \changes{v1.5}{2007/10/13}{Modified to read from a named pipe before
% checking file existence}
% \begin{macrocode}
@@ -1876,7 +1910,9 @@
% \end{macrocode}
% \begin{macrocode}
\newcommand{\plmac@await@existence}[1]{%
- \input\plmac@pipe
+ \begin{lrbox}{\@tempboxa}%
+ \input\plmac@pipe
+ \end{lrbox}%
\loop
\IfFileExists{#1}%
{\plmac@file@existstrue}%
@@ -2077,6 +2113,8 @@
% help of \perlmac, as detailed in Section~\ref{sec:perlmacros}),
% \perltex{} executes it within a secure sandbox and transmits the
% resulting \LaTeX{} code back to the document.
+% \changes{v1.0a}{2003/08/21}{Made all \texttt{unlink} calls wait for the
+% file to actually disappear}
%
% \iffalse
%<*perltex>
@@ -2154,6 +2192,7 @@ use Pod::Usage;
use File::Basename;
use Fcntl;
use POSIX;
+use IO::Handle;
use warnings;
use strict;
% \end{macrocode}
@@ -2166,10 +2205,10 @@ use strict;
% variables.
%
% \paragraph{Variables corresponding to command-line arguments}
-% \begin{perlmacro}{$latexprog}
-% \begin{perlmacro}{$runsafely}
-% \begin{perlmacro}{@permittedops}
-% \begin{perlmacro}{$usepipe}
+% \begin{perlvar}{$latexprog}
+% \begin{perlvar}{$runsafely}
+% \begin{perlvar}{@permittedops}
+% \begin{perlvar}{$usepipe}
% |$latexprog| is the name of the \LaTeX{} executable
% (e.g.,~``|latex|''). If |$runsafely| is~|1| (the default), then the
% user's Perl code runs in a secure sandbox; if it's~|0|, then arbitrary
@@ -2185,21 +2224,21 @@ my $runsafely = 1;
my @permittedops;
my $usepipe = 1;
% \end{macrocode}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
%
% \paragraph{Filename variables}
-% \begin{perlmacro}{$progname}
-% \begin{perlmacro}{$jobname}
-% \begin{perlmacro}{$toperl}
-% \begin{perlmacro}{$fromperl}
-% \begin{perlmacro}{$toflag}
-% \begin{perlmacro}{$fromflag}
-% \begin{perlmacro}{$doneflag}
-% \begin{perlmacro}{$logfile}
-% \begin{perlmacro}{$pipe}
+% \begin{perlvar}{$progname}
+% \begin{perlvar}{$jobname}
+% \begin{perlvar}{$toperl}
+% \begin{perlvar}{$fromperl}
+% \begin{perlvar}{$toflag}
+% \begin{perlvar}{$fromflag}
+% \begin{perlvar}{$doneflag}
+% \begin{perlvar}{$logfile}
+% \begin{perlvar}{$pipe}
% |$progname| is the run-time name of the \perltex{} program.
% |$jobname| is the base name of the user's |.tex| file, which defaults
% to the \TeX{} default of |texput|. |$toperl| defines the filename
@@ -2225,23 +2264,23 @@ my $doneflag;
my $logfile;
my $pipe;
% \end{macrocode}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
%
% \paragraph{Other global variables}
-% \begin{perlmacro}{@latexcmdline}
-% \begin{perlmacro}{$styfile}
-% \begin{perlmacro}{@macroexpansions}
-% \begin{perlmacro}{$sandbox}
-% \begin{perlmacro}{$sandbox_eval}
-% \begin{perlmacro}{$latexpid}
+% \begin{perlvar}{@latexcmdline}
+% \begin{perlvar}{$styfile}
+% \begin{perlvar}{@macroexpansions}
+% \begin{perlvar}{$sandbox}
+% \begin{perlvar}{$sandbox_eval}
+% \begin{perlvar}{$latexpid}
% |@latexcmdline| is the command line to pass to the \LaTeX{}
% executable. |$styfile| is the string \noperlmac{} if \perltex{} is run
% with \texttt{--makesty}, otherwise undefined. |@macroexpansions| is a
@@ -2260,14 +2299,14 @@ my $sandbox = new Safe;
my $sandbox_eval;
my $latexpid;
% \end{macrocode}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
%
-% \begin{perlmacro}{$pipestring}
+% \begin{perlvar}{$pipestring}
% |$pipestring| is a constant string to write to the |$pipe| named pipe
% (or file) at each \LaTeX{} synchronization point. Its particular
% definition is really a bug workaround for \XeTeX\@. The current
@@ -2285,7 +2324,7 @@ my $latexpid;
% \begin{macrocode}
my $pipestring = "\%\%\%\%\% Generated by $progname\n\\endinput\n";
% \end{macrocode}
-% \end{perlmacro}
+% \end{perlvar}
%
% \subsubsection{Command-line conversion}
%
@@ -2322,8 +2361,8 @@ GetOptions("help" => sub {pod2usage(-verbose => 1)},
% \end{macrocode}
%
% \paragraph{Preparing a \LaTeX{} command line}
-% \begin{perlmacro}{$firstcmd}
-% \begin{perlmacro}{$option}
+% \begin{perlvar}{$firstcmd}
+% \begin{perlvar}{$option}
% We start by searching |@ARGV| for the first string that does not start
% with ``|-|'' or ``|\|''. This string, which represents a filename, is
% used to set |$jobname|.
@@ -2341,10 +2380,10 @@ for ($firstcmd=0; $firstcmd<=$#latexcmdline; $firstcmd++) {
}
push @latexcmdline, "" if $#latexcmdline==-1;
% \end{macrocode}
-% \end{perlmacro}
-% \end{perlmacro}
+% \end{perlvar}
+% \end{perlvar}
%
-% \begin{perlmacro}{$separator}
+% \begin{perlvar}{$separator}
% To avoid conflicts with the code and parameters passed to Perl from
% \LaTeX{} (see Figure~\vref{fig:tofile-define} and
% Figure~\vref{fig:tofile-use}) we define a separator string,
@@ -2355,7 +2394,7 @@ foreach (1 .. 20) {
$separator .= chr(ord("A") + rand(26));
}
% \end{macrocode}
-% \end{perlmacro}
+% \end{perlvar}
%
% Now that we have the name of the \LaTeX{} job (|$jobname|) we can
% assign |$toperl|, |$fromperl|, |$toflag|, |$fromflag|, |$doneflag|,
@@ -2388,6 +2427,81 @@ $latexcmdline[$firstcmd] =
$latexcmdline[$firstcmd];
% \end{macrocode}
%
+% \subsubsection{Increasing \PerlTeX's robustness}
+%
+% \changes{v1.9}{2009/09/13}{Introduced handlers for \textsc{sigalrm}
+% and \textsc{sigpipe} to make \perltex\ more robust to \texttt{latex}
+% exiting at an inopportune time}
+%
+% \perltex\ may hang if |latex| exits right before the final pipe
+% communication. We therefore define a simple \signal{ALRM} handler
+% that lets \perltex\ exit after a given length of time has
+% elapsed.\label{code:sigalrm}
+% \begin{macrocode}
+$SIG{"ALRM"} = sub {
+ undef $latexpid;
+ exit 0;
+};
+% \end{macrocode}
+%
+% To prevent Perl from aborting with a ``\texttt{Broken pipe}'' error
+% message if |latex| exits during the final pipe communication we tell
+% Perl to ignore \signal{PIPE} errors. |latex|'s exiting will be
+% caught via other means (the preceding \signal{ALRM} handler or the
+% following call to |waitpid|).
+% \begin{macrocode}
+$SIG{"PIPE"} = "IGNORE";
+% \end{macrocode}
+%
+% \begin{perlsub}{delete_files}
+% On some operating systems and some filesystems, deleting a file may
+% not cause the file to disappear immediately. Because
+% \PerlTeX\ synchronizes Perl and \LaTeX\ via the filesystem it is
+% critical that file deletions be performed when requested. We
+% therefore define a |delete_files| subroutine that waits until each
+% file named in the argument list is truly deleted.
+% \changes{v1.9}{2009/09/13}{Replaced all
+% \texttt{unlink}\dots\texttt{while~-e} statements with calls to a new
+% \texttt{delete\_files} subroutine}
+% \begin{macrocode}
+sub delete_files (@)
+{
+ foreach my $filename (@_) {
+ unlink $filename;
+ while (-e $filename) {
+ unlink $filename;
+ sleep 0;
+ }
+ }
+}
+% \end{macrocode}
+% \end{perlsub}
+%
+% \begin{perlsub}{awaitexists}
+% We define an |awaitexists| subroutine that waits for a given file to
+% exist. If |latex| exits while |awaitexists| is waiting, then
+% \perltex{} cleans up and exits, too.
+% \changes{v1.0a}{2003/08/06}{Bug fix: Added ``\texttt{undef
+% \$latexpid}'' to make the \texttt{END} block correctly return a
+% status code of~0 on success}
+% \changes{v1.9}{2009/09/13}{Hoisted \texttt{\$awaitexists} from the
+% main loop and made it a top-level subroutine}
+% \begin{macrocode}
+sub awaitexists ($)
+{
+ while (!-e $_[0]) {
+ sleep 0;
+ if (waitpid($latexpid, &WNOHANG)==-1) {
+ delete_files($toperl, $fromperl, $toflag,
+ $fromflag, $doneflag, $pipe);
+ undef $latexpid;
+ exit 0;
+ }
+ }
+}
+% \end{macrocode}
+% \end{perlsub}
+%
% \subsubsection{Launching \LaTeX}
%
% We start by deleting the |$toperl|, |$fromperl|, |$toflag|,
@@ -2399,17 +2513,8 @@ $latexcmdline[$firstcmd] =
% complete command line to pass to |latex| we need only |fork| a new
% process and have the child process overlay itself with |latex|.
% \perltex{} continues running as the parent.
-%
-% Note that here and elsewhere in \perltex, |unlink| is called
-% repeatedly until the file is actually deleted. This works around a
-% race condition that occurs in some filesystems in which file deletions
-% are executed somewhat lazily.
-% \changes{v1.0a}{2003/08/21}{Made all \texttt{unlink} calls wait for the
-% file to actually disappear}
% \begin{macrocode}
-foreach my $file ($toperl, $fromperl, $toflag, $fromflag, $doneflag, $pipe) {
- unlink $file while -e $file;
-}
+delete_files($toperl, $fromperl, $toflag, $fromflag, $doneflag, $pipe);
open (LOGFILE, ">$logfile") || die "open(\"$logfile\"): $!\n";
if (defined $styfile) {
open (STYFILE, ">$styfile") || die "open(\"$styfile\"): $!\n";
@@ -2418,6 +2523,7 @@ if (defined $styfile) {
% \begin{macrocode}
if (!$usepipe || !eval {mkfifo($pipe, 0600)}) {
sysopen PIPE, $pipe, O_WRONLY|O_CREAT, 0755;
+ autoflush PIPE 1;
print PIPE $pipestring;
close PIPE;
$usepipe = 0;
@@ -2467,38 +2573,14 @@ else {
while (1) {
% \end{macrocode}
%
-% \begin{perlmacro}{$awaitexists}
-% We define a local subroutine |$awaitexists| which waits for a given
-% file to exist. If |latex| exits while |$awaitexists| is waiting, then
-% \perltex{} cleans up and exits, too.
-% \changes{v1.0a}{2003/08/06}{Bug fix: Added ``\texttt{undef
-% \$latexpid}'' to make the \texttt{END} block correctly return a
-% status code of~0 on success}
-% \begin{macrocode}
- my $awaitexists = sub {
- while (!-e $_[0]) {
- sleep 0;
- if (waitpid($latexpid, &WNOHANG)==-1) {
- foreach my $file ($toperl, $fromperl, $toflag,
- $fromflag, $doneflag, $pipe) {
- unlink $file while -e $file;
- }
- undef $latexpid;
- exit 0;
- }
- }
- };
-% \end{macrocode}
-% \end{perlmacro}
-%
-% \begin{perlmacro}{$entirefile}
+% \begin{perlvar}{$entirefile}
% Wait for |$toflag| to exist. When it does, this implies that
% |$toperl| must exist as well. We read the entire contents of
% |$toperl| into the |$entirefile| variable and process it.
% Figures~\ref{fig:tofile-define} and~\ref{fig:tofile-use} illustrate
% the contents of |$toperl|.
% \begin{macrocode}
- $awaitexists->($toflag);
+ awaitexists($toflag);
my $entirefile;
{
local $/ = undef;
@@ -2507,11 +2589,11 @@ while (1) {
close TOPERL;
}
% \end{macrocode}
-% \end{perlmacro}
+% \end{perlvar}
%
-% \begin{perlmacro}{$optag}
-% \begin{perlmacro}{$macroname}
-% \begin{perlmacro}{@otherstuff}
+% \begin{perlvar}{$optag}
+% \begin{perlvar}{$macroname}
+% \begin{perlvar}{@otherstuff}
% We split the contents of |$entirefile| into an operation tag (either
% |DEF|, |USE|, or |RUN|), the macro name, and everything else
% (|@otherstuff|). If |$optag| is |DEF| then |@otherstuff| will contain
@@ -2522,9 +2604,9 @@ while (1) {
my ($optag, $macroname, @otherstuff) =
map {chomp; $_} split "$separator\n", $entirefile;
% \end{macrocode}
-% \end{perlmacro}
-% \end{perlmacro}
-% \end{perlmacro}
+% \end{perlvar}
+% \end{perlvar}
+% \end{perlvar}
%
% We clean up the macro name by deleting all leading non-letters,
% replacing all subsequent non-alphanumerics with ``|_|'', and
@@ -2549,7 +2631,7 @@ while (1) {
}
% \end{macrocode}
%
-% \begin{perlmacro}{$perlcode}
+% \begin{perlvar}{$perlcode}
% There are three possible values that can be assigned to |$perlcode|.
% If |$optag| is |DEF|, then |$perlcode| is made to contain a definition
% of the user's subroutine, named |$macroname|. If |$optag| is |USE|,
@@ -2623,7 +2705,7 @@ while (1) {
die "${progname}: Internal error -- unexpected operation tag \"$optag\"\n";
}
% \end{macrocode}
-% \end{perlmacro}
+% \end{perlvar}
%
% Log what we're about to evaluate.
% \begin{macrocode}
@@ -2631,8 +2713,8 @@ while (1) {
print LOGFILE $perlcode, "\n";
% \end{macrocode}
%
-% \begin{perlmacro}{$result}
-% \begin{perlmacro}{$msg}
+% \begin{perlvar}{$result}
+% \begin{perlvar}{$msg}
% We're now ready to execute the user's code using the |$sandbox_eval|
% function. If a warning occurs we write it as a Perl comment to the
% log file. If an error occurs (i.e.,~|$@| is defined) we replace the
@@ -2691,8 +2773,8 @@ while (1) {
}
push @macroexpansions, $result if defined $styfile && $optag eq "USE";
% \end{macrocode}
-% \end{perlmacro}
-% \end{perlmacro}
+% \end{perlvar}
+% \end{perlvar}
%
% Log the resulting \LaTeX{} code.
% \begin{macrocode}
@@ -2718,9 +2800,7 @@ while (1) {
close FROMPERL;
% \end{macrocode}
% \begin{macrocode}
- unlink $toflag while -e $toflag;
- unlink $toperl while -e $toperl;
- unlink $doneflag while -e $doneflag;
+ delete_files($toflag, $toperl, $doneflag);
% \end{macrocode}
% \begin{macrocode}
open (FROMFLAG, ">$fromflag") || die "open($fromflag): $!\n";
@@ -2728,6 +2808,7 @@ while (1) {
% \end{macrocode}
% \begin{macrocode}
if (open (PIPE, ">$pipe")) {
+ autoflush PIPE 1;
print PIPE $pipestring;
close PIPE;
}
@@ -2738,17 +2819,23 @@ while (1) {
% |$fromflag| already exists and race ahead, finding that |$fromperl|
% does not contain what it's supposed to.
% \begin{macrocode}
- $awaitexists->($toperl);
- unlink $fromflag while -e $fromflag;
+ awaitexists($toperl);
+ delete_files($fromflag);
open (DONEFLAG, ">$doneflag") || die "open($doneflag): $!\n";
close DONEFLAG;
% \end{macrocode}
-% Again, we awaken the |latex| process, which is blocked on |$pipe|.
+% Again, we awaken the |latex| process, which is blocked on |$pipe|. If
+% writing to the pipe takes more than one second we assume that |latex|
+% has exited and trigger the \signal{ALRM} handler
+% (page~\pageref{code:sigalrm}).
% \begin{macrocode}
+ alarm 1;
if (open (PIPE, ">$pipe")) {
+ autoflush PIPE 1;
print PIPE $pipestring;
close PIPE;
}
+ alarm 0;
}
% \end{macrocode}
%