While it's possible with system() to run command with custom filehandles instead of inheriting only STDIN/STDOUT/STDERR of current process, it has some limitations: - You can't use safe LIST form of system() and should execute your command using shell to have filehandle redirections like '2>&1' working. - You can't interact with running command using pipes. - If you need to give your non-STDIN/OUT/ERR filehandle or if you need to give more than 3 filehandles to command you should use fcntl() to modify close-on-exec flag and/or reopen your STDIN/OUT/ERR to needed filehandles. - User can't set timeout for command. There no way to setup alarm() for command. User can setup alarm() for his main process, but: 1) this isn't acceptable in module because user can already setup some alarm() before calling our module 2) this alarm() will interrupt system(), but not interrupt running command (and we can't kill it because we don't know it's pid) open() limitations: - open(), unlike system(), doesn't block SIGCHLD. This may be fine in user code, but in module this result in two problems if user has $SIG{CHLD} handler installed: 1) pid of process open()'ed in module will be delivered into user's SIGCHLD handler 2) $? status will not be available in module - open(), unlike system(), doesn't block SIGINT & SIGQUIT in main process so if you use open() instead of system() just to interact with executed command using pipe like: open(my $fh, 'some_foreground_command |') then both this command and your main process will receive these signals if user press Ctrl-C or Ctrl-\. - If command will exit while user print() into pipe SIGPIPE will kill main process if user don't block it. - All system() limitations also apply to open(), with only correction: you can interact with running command using pipe, but only single pipe - if you need more pipes then you should use IPC::Open3, IPC::Run or IPC::Run3. `command` (backticks) limitations: - No safe LIST form. - You can't interact with running command using pipes. - If you need to give your non-STDIN/OUT/ERR filehandle or if you need to give more than 3 filehandles to command you should use fcntl() to modify close-on-exec flag and/or reopen your STDIN/OUT/ERR to needed filehandles. - All open() limitations apply. IPC::Open3 limitations: - No signal handling at all, so all open() limitations about SIGCHLD, SIGINT, SIGQUIT and SIGPIPE apply. - No timeout. - Unable to use more than 3 filehandles. IPC::Run limitations: - No signal handling at all, so all open() limitations about SIGCHLD, SIGINT, SIGQUIT and SIGPIPE apply. IPC::Run3 limitations: - No signal handling at all, so all open() limitations about SIGCHLD, SIGINT, SIGQUIT and SIGPIPE apply. - You can't interact with running command using pipes. #### Limitations of other modules from reliability/security view: =over =item GPG - Doesn't handle SIGCHLD, SIGINT, SIGQUIT. - Hang on large files. - Parse unreliable STDOUT instead of reliable --status-fd. =item Crypt::GPG - Doesn't handle SIGINT, SIGQUIT. - Incorrectly handle SIGCHLD. =item GnuPG - Doesn't handle SIGCHLD, SIGINT, SIGQUIT. - Use deprecated shared memory interface. - Use temporary files to store sensitive information. =item GnuPG::Interface - Doesn't handle SIGCHLD, SIGINT, SIGQUIT. =back