
Security News
/Research
Popular node-ipc npm Package Infected with Credential Stealer
Socket detected malicious node-ipc versions with obfuscated stealer/backdoor behavior in a developing npm supply chain attack.
progeny
Advanced tools
Spawn child processes with simple string based standard input/output/error stream handling in an easy-to-use interface.
The Progeny::Command class includes logic for executing child processes and
reading/writing from their standard input, output, and error streams. It's
designed to take all input in a single string and provides all output as single
strings and is therefore not well-suited to streaming large quantities of data
in and out of commands. That said, it has some benefits:
select(2)) - handles all pipe hang
cases due to exceeding PIPE_BUF limits on one or more streams.Process.spawn behind
the scenes so it's widely supported and consistently getting performance
updates.Progeny::Command takes the standard Process::spawn
arguments when
instantiated, and runs the process to completion after writing all input and
reading all output:
require 'progeny'
child = Progeny::Command.new('git', '--help')
Retrieve process output written to stdout / stderr, or inspect the process's exit status:
child.out
# => "usage: git [--version] [--exec-path[=GIT_EXEC_PATH]]\n ..."
child.err
# => ""
child.status
# => #<Process::Status: pid=80718,exited(0)>
Use the :input option to write data on the new process's stdin immediately
after spawning:
child = Progeny::Command.new('bc', :input => '40 + 2')
child.out
# => "42\n"
Additional options can be used to specify the maximum output size (:max) and
time of execution (:timeout) before the child process is aborted. See the
Progeny::Command docs for more info.
Progeny::Command spawns the process immediately when instantiated.
As a result, if it is interrupted by an exception (either from reaching the
maximum output size, the time limit, or another factor), it is not possible to
access the out or err results because the constructor did not complete.
If you want to get the out and err data that was available when the process
was interrupted, use the Progeny::Command alternate form to create the child
without immediately spawning the process. Call exec! to run the command at a
place where you can catch any exceptions:
child = Progeny::Command.build('git', 'log', :max => 100)
begin
child.exec!
rescue Progeny::MaximumOutputExceeded
# limit was reached
end
child.out
# => "commit fa54abe139fd045bf6dc1cc259c0f4c06a9285bb\n..."
Please note that when the MaximumOutputExceeded exception is raised, the
actual combined out and err data may be a bit longer than the :max
value due to internal buffering.
This gem is a fork of the
posix-spawn gem. Originally,
posix-spawn was developed as a higher-performance alternative to Ruby's
built-in Process.spawn method. It achieved this by utilizing the
posix_spawn()
system call, which resulted in significant performance improvements, as
demonstrated in the benchmarks below.
However, the performance advantage of posix-spawn diminished with the release
of Ruby 2.2. In this version, Ruby transitioned from using the fork() system
call to vfork(), which
creates a new process without copying the parent process's page tables, leading
to enhanced performance.
The following benchmarks illustrate the performance comparison:
posix-spawn creation (Ruby used fork + exec):

Source: posix-spawn README

Source: Generated with the script in this gist on a Debian 11 (bullseye) x86_64 machine.
For that reason, we decided to delete all of the custom spawn implementations
in the original gem: POSIX::Spawn#spawn, POSIX::Spawn#popen4,
Kernel#system, and Kernel#`.
However, we didn't want to completely remove our use of posix-spawn because
we really enjoy the interface provided by POSIX::Spawn::Child. That's how
progeny came to be. It maintains all of the functionality provided by
POSIX::Spawn::Child under a new namespace: Progeny::Command.
posix-spawn to progenyPOSIX::Spawn as a Mixin.
Progeny does not include a Mixin so if you're including POSIX::Spawn in any
classes like so:require 'posix/spawn'
class YourSpawnerClass
include POSIX::Spawn
# [...]
end
You will need to remove the include statements and replace any use of #spawn
with Ruby's native Process.spawn and #popen4 with Progeny::Command.spawn_with_pipes
- require 'posix/spawn'
class YourSpawnerClass
- include POSIX::Spawn
def speak(message)
- pid = spawn('echo', message)
+ pid = Process.spawn('echo', message)
Process::waitpid(pid)
end
def calculate(expression)
- pid, in, out, err = popen4('bc')
+ pid, in, out, err = Progeny::Command.spawn_with_pipes('bc')
in.write(expression)
in.close
out.read
ensure
[in, out, err].each { |io| io.close if !io.closed? }
Process::waitpid(pid)
$?
end
end
- gem 'posix-spawn'
+ gem 'progeny'
POSIX::Spawn::Child with Progeny::Command and any POSIX::Spawn exceptions with Progenyclass GitDiff
def compare(from_sha, to_sha)
- child = POSIX::Spawn::Child.new("git", "diff #{from_sha}..#{to_sha}")
+ child = Progeny::Command.new("git", "diff #{from_sha}..#{to_sha}")
child.out
end
def compare_to_remote_head
- child = POSIX::Spawn::Child.build('git', 'diff origin/main HEAD')
+ child = Progeny::Command.build('git', 'diff origin/main HEAD')
begin
child.exec!
- rescue POSIX::Spawn::MaximumOutputExceeded
+ rescue Progeny::MaximumOutputExceeded
# limit was reached
end
child.out
end
end
bundle install and make sure your tests are passing. If you encounter any
issues feel free to open an issue or a PR.FAQs
Unknown package
We found that progeny demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
/Research
Socket detected malicious node-ipc versions with obfuscated stealer/backdoor behavior in a developing npm supply chain attack.

Security News
TeamPCP and BreachForums are promoting a Shai-Hulud supply chain attack contest with a $1,000 prize for the biggest package compromise.

Security News
Packagist urges PHP projects to update Composer after a GitHub token format change exposed some GitHub Actions tokens in CI logs.