Skip to content

Instantly share code, notes, and snippets.

@jstorimer
Created September 16, 2012 04:23
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jstorimer/3730986 to your computer and use it in GitHub Desktop.
Save jstorimer/3730986 to your computer and use it in GitHub Desktop.
module Kernel
def system(*args)
rd, wr = IO.pipe
# Create a new subprocess that will just exec the requested program.
pid = fork do
# The sub-process closes its copy of the reading end of the pipe
# because it only needs to write.
rd.close
begin
exec(*args)
rescue SystemCallError
# In case of failure write a byte to the pipe to signal that an exception
# occurred and exit with an unsuccessful code.
wr.write('.')
exit 1
end
end
# The parent process closes its copy of the writing end of the pipe
# because it only needs to read.
wr.close
# Tell the parent to wait.
_, status = Process.waitpid2(pid)
# If the reading end of the pipe has no data then there was no exception
# and we fall back to the exit status code of the sub-process. Otherwise
# we return nil to denote the error case.
if rd.eof?
status.success?
else
nil
end
end
private :system
def `(str)
rd, wr = IO.pipe
# Create a new subprocess that will just exec the requested program.
pid = fork do
# The sub-process closes its copy of the reading end of the pipe
# because it only needs to write.
rd.close
# Anything that the exec'ed process would have written to $stdout will
# be written to the pipe instead.
$stdout.reopen(wr)
exec(str)
end
# The parent process closes its copy of the writing end of the pipe
# because it only needs to read.
wr.close
# The parent waits for the child to exit.
Process.waitpid(pid)
# The parent returns whatever it can read from the pipe.
rd.read
end
private :`
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment