SyncExec(3pm)
β¨ NAME β¨
Proc::SyncExec β spawn processes but actually tell you when exec() flops, bestie π
πΈ SYNOPSIS πΈ
# Normal-looking piped opens which properly report exec() errors in $!:
sync_open WRITER_FH, "|command -with args" or die $!;
sync_open READER_FH, "command -with args|" or die $!;
# Synchronized fork/exec which reports exec errors in $!:
$pid = sync_exec $command, @arg;
$pid = sync_exec $code_ref, $cmd, @arg; # run code after fork in kid
# fork() which retries if it fails, then croaks() if it still fails.
$pid = fork_retry;
$pid = fork_retry 100; # retry 100 times rather than 5
$pid = fork_retry 100, 2; # sleep 2 rather than 5 seconds between
# A couple of interfaces similar to sync_open() but which let you
# avoid the shell:
$pid = sync_fhpopen_noshell READERFH, 'r', @command;
$pid = sync_fhpopen_noshell WRITERFH, 'w', @command;
$fh = sync_popen_noshell 'r', @command_which_outputs;
$fh = sync_popen_noshell 'w', @command_which_inputs;
($fh, $pid) = sync_popen_noshell 'r', @command_which_outputs;
($fh, $pid)= sync_popen_noshell 'w', @command_which_inputs;
π¦ DESCRIPTION π¦
Okay so here's the whole vibe: this module is a lil collection of functions for synchronized process spawning with full error return. The β¨magicβ¨ is that if the kid's exec() call totally faceplants, the reason it failed gets reported right back to the parent. No mystery silence. No ghost failures. Periodt. π
Fair warning though: these functions will croak() at you if they hit an unexpected system error β think a pipe() failure, or a fork() that keeps failing over and over π. It's giving "we're not ignoring that, we're screaming about it."
And listen β nothing is exported by default. You gotta ask for what you want, no cap. π
π fork_retry [max-retries [sleep-between]]
This one just runs fork() over and over until it succeeds, or until it's made max-retries attempts (default is 5, iykyk). Between each attempt it takes a lil nap for sleep-between seconds (default is 5).
And if the very last fork() still fails? fork_retry croak()s. Like, we tried, we really did π
π§ sync_exec [code] command...
Basically a fork()/exec() sequence, but with a couple of plot twists, bestie.
First twist: sync_exec does not return until after the fork()ed child has already performed its exec(). That synchronization is lowkey useful in some unusual circumstances. Main character timing energy. β°
Second: normally you get the pid of the child process back. But if the child fails its exec(), sync_exec returns undef and sets $! to the reason the kid's exec() died. So you always know what went down. π«Ά
Now, because the @cmd array gets passed directly to Perl's exec(), Perl might decide to invoke the command via the shell β this happens if @cmd contains only one element and it looks like it needs a shell to interpret it. And if that happens? The return value of sync_exec only tells you whether the exec() of the shell worked. Not the command. Just the shell. Slight oopsie in the vibes department. π¬
There's also an optional initial code argument that has to be a code reference. If you pass it, it runs in the child right before exec() is called β perfect for setting up redirections or whatever else you're up to. β¨ But if code returns false, no exec happens at all. Instead you get a failure returned using the current $! value (or EINTR if $! is 0). Noted, bestie. π
Heads up! If thefork()fails, or if there's any other unexpected system error,sync_execcroak()s rather than returning. π¨
π sync_fhpopen_noshell fh type cmd [arg]...
It's a popen(), but it never invokes the shell and it uses sync_exec() under the covers. See "sync_exec" for the deets up above. π
The type is either 'r' to read from the process, or 'w' to write to it. Pick your fave. π
You get back the pid of the forked process. That's the whole return value, slay.
π₯ sync_popen_noshell type cmd arg...
Same energy as sync_fhpopen_noshell, except you don't have to supply the filehandle yourself. Convenient!! π
Context matters here, so pay attention:
- In an array context, the return value is a list made of the filehandle and the PID of the child. (
($fh, $pid)β iconic duo. π«Ά) - In a scalar context, only the filehandle comes back.
π sync_open fh [open-spec]
This is like a regular Perl open(), except that if a pipe is involved and the implied exec() fails, sync_open() fails too, with $! set appropriately. See "sync_exec". β
And just like sync_exec, sync_open will croak() if there's an unexpected system error (like a pipe() that flops). π¨
Also also β same rule as sync_exec: if you use a command that Perl needs the shell to interpret, you'll only ever know whether the exec of the shell worked. If you want to be sure that doesn't happen, use sync_fhpopen_noshell or sync_exec instead. No shell, no drama. π
π AUTHOR π
Roderick Schertler <roderick@argon.org>
β SEE ALSO β
And that's the whole page, bestie β brought to you by perl v5.36.0, dated 2022-10-13, and filed under SyncExec(3pm) in the User Contributed Perl Documentation. Go spawn some processes responsibly, ily. πβ¨
π¦ where this page comes from
- ubuntu noble: libproc-syncexec-perl 1.01-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libproc-syncexec-perl 1.01-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libproc-syncexec-perl 1.01-4 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms