/* * 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> to avoid running any * <code>at_exit</code> functions. The parent process should * use <code>Process.wait</code> to collect the termination statuses * of its children or use <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. */ static VALUE rb_f_fork(obj) VALUE obj; { #if !defined(__human68k__) && !defined(_WIN32) && !defined(__MACOS__) && !defined(__EMX__) && !defined(__VMS) int pid; rb_secure(2); #ifndef __VMS fflush(stdout); fflush(stderr); #endif switch (pid = fork()) { case 0: #ifdef linux after_exec(); #endif rb_thread_atfork(); if (rb_block_given_p()) { int status; rb_protect(rb_yield, Qundef, &status); ruby_stop(status); } return Qnil; case -1: rb_sys_fail("fork(2)"); return Qnil; default: return INT2FIX(pid); } #else rb_notimplement(); #endif }