Creates a subprocess. If a block is specified, that block is run in the
subprocess, and the subprocess terminates with a status of zero. Otherwise,
the fork call returns twice, once
in the parent, returning the process ID of the child, and once in the
child, returning nil. The child process can exit using Kernel.exit! to avoid
running any at_exit functions.
The parent process should use Process.wait to collect the
termination statuses of its children or use Process.detach to register
disinterest in their status; otherwise, the operating system may accumulate zombie processes.

The thread calling fork is the only thread
in the created child process. fork
doesn’t copy other threads.

/*
* call-seq:
* Kernel.fork [{ block }] => fixnum or nil
* Process.fork [{ block }] => fixnum or nil
*
* Creates a subprocess. If a block is specified, that block is run
* in the subprocess, and the subprocess terminates with a status of
* zero. Otherwise, the +fork+ call returns twice, once in
* the parent, returning the process ID of the child, and once in
* the child, returning _nil_. The child process can exit using
* <code>Kernel.exit!</code>toavoidrunningany*<code>at_exit</code> functions. The parent process should
* use <code>Process.wait</code>tocollecttheterminationstatuses*ofitschildrenoruse<code>Process.detach</code> to register
* disinterest in their status; otherwise, the operating system
* may accumulate zombie processes.
*
* The thread calling fork is the only thread in the created child process.
* fork doesn't copy other threads.
*/staticVALUErb_f_fork(obj)VALUEobj;{#if !defined(__human68k__) && !defined(_WIN32) && !defined(__MACOS__) && !defined(__EMX__) && !defined(__VMS)intpid;rb_secure(2);#ifndef __VMSfflush(stdout);fflush(stderr);#endifswitch(pid=fork()){case0:#ifdef linuxafter_exec();#endifrb_thread_atfork();if(rb_block_given_p()){intstatus;rb_protect(rb_yield,Qundef,&status);ruby_stop(status);}returnQnil;case-1:rb_sys_fail("fork(2)");returnQnil;default:returnINT2FIX(pid);}#elserb_notimplement();#endif}