---
name: "Proc::SyncExec"
section: "3pm"
platform: "linux"
package: "libproc-syncexec-perl"
version: "1.01-4"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/Proc::SyncExec"
---

# Proc::SyncExec(3pm)

Spawn processes but report exec() errors

## NAME

Proc::SyncExec - Spawn processes but report exec() errors

## 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

This module contains functions for synchronized process spawning with full error return.  If the child's **exec()** call fails the reason for the failure is reported back to the parent.

These functions will **croak()** if they encounter an unexpected system error, such as a **pipe()** failure or a repeated **fork()** failure.

Nothing is exported by default.

- **fork\_retry** \[*max-retries* \[*sleep-between*\]\]

  This function runs **fork()** until it succeeds or until *max-retries* (default 5) attempts have been made, sleeping *sleep-between* seconds (default 5) between attempts.  If the last **fork()** fails **fork\_retry** **croak()**s.

- **sync\_exec** \[*code*\] *command*...

  This function is similar to a **fork()**/**exec()** sequence but with a few twists.

  **sync\_exec** does not return until after the **fork()**ed child has already performed its **exec()**.  The synchronization this provides is useful in some unusual circumstances.

  Normally the pid of the child process is returned.  However, if the child fails its **exec()** **sync\_exec** returns undef and sets $! to the reason for the child's **exec()** failure.

  Since the `@cmd` array is passed directly to Perl's **exec()** Perl might choose to invoke the command via the shell if `@cmd` contains only one element and it looks like it needs a shell to interpret it.  If this happens the return value of **sync\_exec** only indicates whether the **exec()** of the shell worked.

  The optional initial *code* argument must be a code reference.  If it is present it is run in the child just before **exec()** is called.  You can use this to set up redirections or whatever.  If *code* returns false no exec is performed, instead a failure is returned using the current $! value (or EINTR if $! is 0).

  If the **fork()** fails or if there is some other unexpected system error **sync\_exec** **croak()**s rather than returning.

- **sync\_fhpopen\_noshell** *fh* *type* *cmd* \[*arg*\]...

  This is a **popen()** but it never invokes the shell and it uses **sync\_exec()** under the covers.  See "sync\_exec".

  The *type* is either `'r'` to read from the process or `'w'` to write to it.

  The return value is the pid of the forked process.

- **sync\_popen\_noshell** *type* *cmd* *arg*...

  This is like **sync\_fhpopen\_noshell**, but you don't have to supply the filehandle.

  If called in an array context the return value is a list consisting of the filehandle and the PID of the child.  In a scalar context only the filehandle is returned.

- **sync\_open** *fh* \[*open-spec*\]

  This is like a Perl **open()** except that if a pipe is involved and the implied **exec()** fails **sync\_open()** fails with $! set appropriately.  See "sync\_exec".

  Like **sync\_exec**, **sync\_open** **croak()**s if there is an unexpected system error (such as a failed **pipe()**).

  Also like **sync\_exec**, if you use a command which Perl needs to use the shell to interpret you'll only know if the exec of the shell worked. Use **sync\_fhpopen\_noshell** or **sync\_exec** to be sure that this doesn't happen.

## AUTHOR

Roderick Schertler \<*roderick@argon.org*\>

## SEE ALSO

[**perl**(1)](/perl/1.md).
