module Process - RDoc Documentation (original) (raw)

Module Process represents a process in the underlying operating system. Its methods support management of the current process and its child processes.

Process Creation

Each of the following methods executes a given command in a new process or subshell, or multiple commands in new processes and/or subshells. The choice of process or subshell depends on the form of the command; see Argument command_line or exe_path.

In addition:

Execution Environment

Optional leading argument env is a hash of name/value pairs, where each name is a string and each value is a string or nil; each name/value pair is added to ENV in the new process.

Process.spawn( 'ruby -e "p ENV["Foo"]"') Process.spawn({'Foo' => '0'}, 'ruby -e "p ENV["Foo"]"')

Output:

"0"

The effect is usually similar to that of calling ENV#update with argument env, where each named environment variable is created or updated (if the value is non-nil), or deleted (if the value is nil).

However, some modifications to the calling process may remain if the new process fails. For example, hard resource limits are not restored.

Argument command_line or exe_path

The required string argument is one of the following:

Argument command_line

String argument command_line is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:

system('if true; then echo "Foo"; fi')
system('exit')
system('date > /tmp/date.tmp')
system('date > /nop/date.tmp')
system('date > /nop/date.tmp', exception: true)

The command line may also contain arguments and options for the command:

system('echo "Foo"')

Output:

Foo

See Execution Shell for details about the shell.

Argument exe_path

Argument exe_path is one of the following:

Arguments args

If command_line does not contain shell meta characters except for spaces and tabs, or exe_path is given, Ruby invokes the executable directly. This form does not use the shell:

spawn("doesnt_exist")
spawn("doesnt_exist", "\n")

spawn("doesnt_exist\n")

The error message is from a shell and would vary depending on your system.

If one or more args is given after exe_path, each is an argument or option to be passed to the executable:

Example:

system('echo', '<', 'C*', '|', '$SHELL', '>')

Output:

< C* | $SHELL >

However, there are exceptions on Windows. See Execution Shell on Windows.

If you want to invoke a path containing spaces with no arguments without shell, you will need to use a 2-element array exe_path.

Example:

path = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' spawn(path) spawn([path] * 2)

Execution Options

Optional trailing argument options is a hash of execution options.

Working Directory (:chdir)

By default, the working directory for the new process is the same as that of the current process:

Dir.chdir('/var') Process.spawn('ruby -e "puts Dir.pwd"')

Output:

/var

Use option :chdir to set the working directory for the new process:

Process.spawn('ruby -e "puts Dir.pwd"', {chdir: '/tmp'})

Output:

/tmp

The working directory of the current process is not changed:

Dir.pwd

File Redirection (File Descriptor)

Use execution options for file redirection in the new process.

The key for such an option may be an integer file descriptor (fd), specifying a source, or an array of fds, specifying multiple sources.

An integer source fd may be specified as:

There are these shorthand symbols for fds:

The value given with a source is one of:

See Access Modes and File Permissions.

Environment Variables (:unsetenv_others)

By default, the new process inherits environment variables from the parent process; use execution option key :unsetenv_others with value true to clear environment variables in the new process.

Any changes specified by execution option env are made after the new process inherits or clears its environment variables; see Execution Environment.

File-Creation Access (:umask)

Use execution option :umask to set the file-creation access for the new process; see Access Modes:

command = 'ruby -e "puts sprintf("0%o", File.umask)"' options = {:umask => 0644} Process.spawn(command, options)

Output:

0644

Process Groups (:pgroup and :new_pgroup)

By default, the new process belongs to the same process group as the parent process.

To specify a different process group. use execution option :pgroup with one of the following values:

On Windows only, use execution option :new_pgroup with value true to create a new process group for the new process.

Resource Limits

Use execution options to set resource limits.

The keys for these options are symbols of the form :rlimit_ _resourcename_, where resource_name is the downcased form of one of the string resource names described at method Process.setrlimit. For example, key :rlimit_cpu corresponds to resource limit 'CPU'.

The value for such as key is one of:

File Descriptor Inheritance

By default, the new process inherits file descriptors from the parent process.

Use execution option :close_others => true to modify that inheritance by closing non-standard fds (3 and greater) that are not otherwise redirected.

Execution Shell

On a Unix-like system, the shell invoked is /bin/sh; the entire string command_line is passed as an argument to shell option -c.

The shell performs normal shell expansion on the command line:

Example:

system('echo $SHELL: C*')

Output:

/bin/bash: CONTRIBUTING.md COPYING COPYING.ja

Execution Shell on Windows

On Windows, the shell invoked is determined by environment variable RUBYSHELL, if defined, or COMSPEC otherwise; the entire string command_line is passed as an argument to -c option for RUBYSHELL, as well as /bin/sh, and /c option for COMSPEC. The shell is invoked automatically in the following cases:

Note that the command will still be invoked as command_line form even when called in exe_path form, because cmd.exe does not accept a script name like /bin/sh does but only works with /c option.

The standard shell cmd.exe performs environment variable expansion but does not have globbing functionality:

Example:

system("echo %COMSPEC%: C*")' # => true

Output:

C:\WINDOWS\system32\cmd.exe: C*

What’s Here

Current-Process Getters

Current-Process Setters

Current-Process Execution

Child Processes

Process Groups

Timing

Constants

CLOCK_BOOTTIME

see Process.clock_gettime

CLOCK_BOOTTIME_ALARM

see Process.clock_gettime

CLOCK_MONOTONIC

see Process.clock_gettime

CLOCK_MONOTONIC_COARSE

see Process.clock_gettime

CLOCK_MONOTONIC_FAST

see Process.clock_gettime

CLOCK_MONOTONIC_PRECISE

see Process.clock_gettime

CLOCK_MONOTONIC_RAW

see Process.clock_gettime

CLOCK_MONOTONIC_RAW_APPROX

see Process.clock_gettime

CLOCK_PROCESS_CPUTIME_ID

see Process.clock_gettime

CLOCK_PROF

see Process.clock_gettime

CLOCK_REALTIME

see Process.clock_gettime

CLOCK_REALTIME_ALARM

see Process.clock_gettime

CLOCK_REALTIME_COARSE

see Process.clock_gettime

CLOCK_REALTIME_FAST

see Process.clock_gettime

CLOCK_REALTIME_PRECISE

see Process.clock_gettime

CLOCK_SECOND

see Process.clock_gettime

CLOCK_TAI

see Process.clock_gettime

CLOCK_THREAD_CPUTIME_ID

see Process.clock_gettime

CLOCK_UPTIME

see Process.clock_gettime

CLOCK_UPTIME_FAST

see Process.clock_gettime

CLOCK_UPTIME_PRECISE

see Process.clock_gettime

CLOCK_UPTIME_RAW

see Process.clock_gettime

CLOCK_UPTIME_RAW_APPROX

see Process.clock_gettime

CLOCK_VIRTUAL

see Process.clock_gettime

PRIO_PGRP

see Process.setpriority

PRIO_PROCESS

see Process.setpriority

PRIO_USER

see Process.setpriority

RLIMIT_AS

Maximum size of the process’s virtual memory (address space) in bytes.

see the system getrlimit(2) manual for details.

RLIMIT_CORE

Maximum size of the core file.

see the system getrlimit(2) manual for details.

RLIMIT_CPU

CPU time limit in seconds.

see the system getrlimit(2) manual for details.

RLIMIT_DATA

Maximum size of the process’s data segment.

see the system getrlimit(2) manual for details.

RLIMIT_FSIZE

Maximum size of files that the process may create.

see the system getrlimit(2) manual for details.

RLIMIT_MEMLOCK

Maximum number of bytes of memory that may be locked into RAM.

see the system getrlimit(2) manual for details.

RLIMIT_MSGQUEUE

Specifies the limit on the number of bytes that can be allocated for POSIX message queues for the real user ID of the calling process.

see the system getrlimit(2) manual for details.

RLIMIT_NICE

Specifies a ceiling to which the process’s nice value can be raised.

see the system getrlimit(2) manual for details.

RLIMIT_NOFILE

Specifies a value one greater than the maximum file descriptor number that can be opened by this process.

see the system getrlimit(2) manual for details.

RLIMIT_NPROC

The maximum number of processes that can be created for the real user ID of the calling process.

see the system getrlimit(2) manual for details.

RLIMIT_NPTS

The maximum number of pseudo-terminals that can be created for the real user ID of the calling process.

see the system getrlimit(2) manual for details.

Specifies the limit (in pages) of the process’s resident set.

see the system getrlimit(2) manual for details.

RLIMIT_RTPRIO

Specifies a ceiling on the real-time priority that may be set for this process.

see the system getrlimit(2) manual for details.

RLIMIT_RTTIME

Specifies limit on CPU time this process scheduled under a real-time scheduling policy can consume.

see the system getrlimit(2) manual for details.

RLIMIT_SBSIZE

Maximum size of the socket buffer.

RLIMIT_SIGPENDING

Specifies a limit on the number of signals that may be queued for the real user ID of the calling process.

see the system getrlimit(2) manual for details.

RLIMIT_STACK

Maximum size of the stack, in bytes.

see the system getrlimit(2) manual for details.

RLIM_INFINITY

see Process.setrlimit

RLIM_SAVED_CUR

see Process.setrlimit

RLIM_SAVED_MAX

see Process.setrlimit

WNOHANG

see Process.wait

WUNTRACED

see Process.wait

Public Class Methods

_fork → integer click to toggle source

An internal API for fork. Do not call this method directly. Currently, this is called via Kernel#fork, Process.fork, and IO.popen with "-".

This method is not for casual code but for application monitoring libraries. You can add custom code before and after fork events by overriding this method.

Note: Process.daemon may be implemented using fork(2) BUT does not go through this method. Thus, depending on your reason to hook into this method, you may also want to hook into that one. See this issue for a more detailed discussion of this.

VALUE rb_proc__fork(VALUE _obj) { rb_pid_t pid = proc_fork_pid(); return PIDT2NUM(pid); }

abort click to toggle source

abort(msg = nil)

Terminates execution immediately, effectively by calling Kernel.exit(false).

If string argument msg is given, it is written to STDERR prior to termination; otherwise, if an exception was raised, prints its message and backtrace.

static VALUE f_abort(int c, const VALUE *a, VALUE _) { rb_f_abort(c, a); UNREACHABLE_RETURN(Qnil); }

argv0 → frozen_string click to toggle source

Returns the name of the script being executed. The value is not affected by assigning a new value to $0.

This method first appeared in Ruby 2.1 to serve as a global variable free means to get the script name.

static VALUE proc_argv0(VALUE process) { return rb_orig_progname; }

clock_getres(clock_id, unit = :float_second) → number click to toggle source

Returns a clock resolution as determined by POSIX function clock_getres():

Process.clock_getres(:CLOCK_REALTIME)

See Process.clock_gettime for the values of clock_id and unit.

Examples:

Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :float_microsecond) Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :float_millisecond) Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :float_second)
Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :microsecond)
Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :millisecond)
Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :nanosecond)
Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :second)

In addition to the values for unit supported in Process.clock_gettime, this method supports :hertz, the integer number of clock ticks per second (which is the reciprocal of :float_second):

Process.clock_getres(:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)
Process.clock_getres(:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID, :float_second)

Accuracy: Note that the returned resolution may be inaccurate on some platforms due to underlying bugs. Inaccurate resolutions have been reported for various clocks including :CLOCK_MONOTONIC and :CLOCK_MONOTONIC_RAW on Linux, macOS, BSD or AIX platforms, when using ARM processors, or when using virtualization.

static VALUE rb_clock_getres(int argc, VALUE *argv, VALUE _) { int ret;

struct timetick tt;
timetick_int_t numerators[2];
timetick_int_t denominators[2];
int num_numerators = 0;
int num_denominators = 0;

#ifdef HAVE_CLOCK_GETRES clockid_t c; #endif

VALUE unit = (rb_check_arity(argc, 1, 2) == 2) ? argv[1] : Qnil;
VALUE clk_id = argv[0];

if (SYMBOL_P(clk_id)) {

#ifdef CLOCK_REALTIME if (clk_id == RUBY_CLOCK_REALTIME) { c = CLOCK_REALTIME; goto getres; } #endif

#ifdef CLOCK_MONOTONIC if (clk_id == RUBY_CLOCK_MONOTONIC) { c = CLOCK_MONOTONIC; goto getres; } #endif

#ifdef CLOCK_PROCESS_CPUTIME_ID if (clk_id == RUBY_CLOCK_PROCESS_CPUTIME_ID) { c = CLOCK_PROCESS_CPUTIME_ID; goto getres; } #endif

#ifdef CLOCK_THREAD_CPUTIME_ID if (clk_id == RUBY_CLOCK_THREAD_CPUTIME_ID) { c = CLOCK_THREAD_CPUTIME_ID; goto getres; } #endif

#ifdef RUBY_GETTIMEOFDAY_BASED_CLOCK_REALTIME if (clk_id == RUBY_GETTIMEOFDAY_BASED_CLOCK_REALTIME) { tt.giga_count = 0; tt.count = 1000; denominators[num_denominators++] = 1000000000; goto success; } #endif

#ifdef RUBY_TIME_BASED_CLOCK_REALTIME if (clk_id == RUBY_TIME_BASED_CLOCK_REALTIME) { tt.giga_count = 1; tt.count = 0; denominators[num_denominators++] = 1000000000; goto success; } #endif

#ifdef RUBY_TIMES_BASED_CLOCK_MONOTONIC if (clk_id == RUBY_TIMES_BASED_CLOCK_MONOTONIC) { tt.count = 1; tt.giga_count = 0; denominators[num_denominators++] = get_clk_tck(); goto success; } #endif

#ifdef RUBY_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID if (clk_id == RUBY_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID) { tt.giga_count = 0; tt.count = 1000; denominators[num_denominators++] = 1000000000; goto success; } #endif

#ifdef RUBY_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID if (clk_id == RUBY_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID) { tt.count = 1; tt.giga_count = 0; denominators[num_denominators++] = get_clk_tck(); goto success; } #endif

#ifdef RUBY_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID if (clk_id == RUBY_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID) { tt.count = 1; tt.giga_count = 0; denominators[num_denominators++] = CLOCKS_PER_SEC; goto success; } #endif

#ifdef RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC if (clk_id == RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC) { const mach_timebase_info_data_t *info = get_mach_timebase_info(); tt.count = 1; tt.giga_count = 0; numerators[num_numerators++] = info->numer; denominators[num_denominators++] = info->denom; denominators[num_denominators++] = 1000000000; goto success; } #endif } else if (NUMERIC_CLOCKID) { #if defined(HAVE_CLOCK_GETRES) struct timespec ts; c = NUM2CLOCKID(clk_id); getres: ret = clock_getres(c, &ts); if (ret == -1) clock_failed("getres", errno, clk_id); tt.count = (int32_t)ts.tv_nsec; tt.giga_count = ts.tv_sec; denominators[num_denominators++] = 1000000000; goto success; #endif } else { rb_unexpected_type(clk_id, T_SYMBOL); } clock_failed("getres", EINVAL, clk_id);

success: if (unit == ID2SYM(id_hertz)) { return timetick2dblnum_reciprocal(&tt, numerators, num_numerators, denominators, num_denominators); } else { return make_clock_result(&tt, numerators, num_numerators, denominators, num_denominators, unit); } }

clock_gettime(clock_id, unit = :float_second) → number click to toggle source

Returns a clock time as determined by POSIX function clock_gettime():

Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID)

Argument clock_id should be a symbol or a constant that specifies the clock whose time is to be returned; see below.

Optional argument unit should be a symbol that specifies the unit to be used in the returned clock time; see below.

Argument clock_id

Argument clock_id specifies the clock whose time is to be returned; it may be a constant such as Process::CLOCK_REALTIME, or a symbol shorthand such as :CLOCK_REALTIME.

The supported clocks depend on the underlying operating system; this method supports the following clocks on the indicated platforms (raises Errno::EINVAL if called with an unsupported clock):

Note that SUS stands for Single Unix Specification. SUS contains POSIX and clock_gettime is defined in the POSIX part. SUS defines :CLOCK_REALTIME as mandatory but :CLOCK_MONOTONIC, :CLOCK_PROCESS_CPUTIME_ID, and :CLOCK_THREAD_CPUTIME_ID are optional.

Certain emulations are used when the given clock_id is not supported directly:

Argument unit

Optional argument unit (default :float_second) specifies the unit for the returned value.

Examples:

Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :float_microsecond)

Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :float_millisecond)

Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :float_second)

Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :microsecond)

Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :millisecond)

Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :nanosecond)

Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :second)

The underlying function, clock_gettime(), returns a number of nanoseconds. Float object (IEEE 754 double) is not enough to represent the return value for :CLOCK_REALTIME. If the exact nanoseconds value is required, use :nanosecond as the unit.

The origin (time zero) of the returned value is system-dependent, and may be, for example, system start up time, process start up time, the Epoch, etc.

The origin in :CLOCK_REALTIME is defined as the Epoch: 1970-01-01 00:00:00 UTC; some systems count leap seconds and others don’t, so the result may vary across systems.

static VALUE rb_clock_gettime(int argc, VALUE *argv, VALUE _) { int ret;

struct timetick tt;
timetick_int_t numerators[2];
timetick_int_t denominators[2];
int num_numerators = 0;
int num_denominators = 0;

VALUE unit = (rb_check_arity(argc, 1, 2) == 2) ? argv[1] : Qnil;
VALUE clk_id = argv[0];

#ifdef HAVE_CLOCK_GETTIME clockid_t c; #endif

if (SYMBOL_P(clk_id)) {

#ifdef CLOCK_REALTIME if (clk_id == RUBY_CLOCK_REALTIME) { c = CLOCK_REALTIME; goto gettime; } #endif

#ifdef CLOCK_MONOTONIC if (clk_id == RUBY_CLOCK_MONOTONIC) { c = CLOCK_MONOTONIC; goto gettime; } #endif

#ifdef CLOCK_PROCESS_CPUTIME_ID if (clk_id == RUBY_CLOCK_PROCESS_CPUTIME_ID) { c = CLOCK_PROCESS_CPUTIME_ID; goto gettime; } #endif

#ifdef CLOCK_THREAD_CPUTIME_ID if (clk_id == RUBY_CLOCK_THREAD_CPUTIME_ID) { c = CLOCK_THREAD_CPUTIME_ID; goto gettime; } #endif

    /*
     * Non-clock_gettime clocks are provided by symbol clk_id.
     */

#ifdef HAVE_GETTIMEOFDAY /* * GETTIMEOFDAY_BASED_CLOCK_REALTIME is used for * CLOCK_REALTIME if clock_gettime is not available. */ #define RUBY_GETTIMEOFDAY_BASED_CLOCK_REALTIME ID2SYM(id_GETTIMEOFDAY_BASED_CLOCK_REALTIME) if (clk_id == RUBY_GETTIMEOFDAY_BASED_CLOCK_REALTIME) { struct timeval tv; ret = gettimeofday(&tv, 0); if (ret != 0) rb_sys_fail("gettimeofday"); tt.giga_count = tv.tv_sec; tt.count = (int32_t)tv.tv_usec * 1000; denominators[num_denominators++] = 1000000000; goto success; } #endif

#define RUBY_TIME_BASED_CLOCK_REALTIME ID2SYM(id_TIME_BASED_CLOCK_REALTIME) if (clk_id == RUBY_TIME_BASED_CLOCK_REALTIME) { time_t t; t = time(NULL); if (t == (time_t)-1) rb_sys_fail("time"); tt.giga_count = t; tt.count = 0; denominators[num_denominators++] = 1000000000; goto success; }

#ifdef HAVE_TIMES #define RUBY_TIMES_BASED_CLOCK_MONOTONIC
ID2SYM(id_TIMES_BASED_CLOCK_MONOTONIC) if (clk_id == RUBY_TIMES_BASED_CLOCK_MONOTONIC) { struct tms buf; clock_t c; unsigned_clock_t uc; c = times(&buf); if (c == (clock_t)-1) rb_sys_fail("times"); uc = (unsigned_clock_t)c; tt.count = (int32_t)(uc % 1000000000); tt.giga_count = (uc / 1000000000); denominators[num_denominators++] = get_clk_tck(); goto success; } #endif

#ifdef RUSAGE_SELF #define RUBY_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID
ID2SYM(id_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID) if (clk_id == RUBY_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID) { struct rusage usage; int32_t usec; ret = getrusage(RUSAGE_SELF, &usage); if (ret != 0) rb_sys_fail("getrusage"); tt.giga_count = usage.ru_utime.tv_sec + usage.ru_stime.tv_sec; usec = (int32_t)(usage.ru_utime.tv_usec + usage.ru_stime.tv_usec); if (1000000 <= usec) { tt.giga_count++; usec -= 1000000; } tt.count = usec * 1000; denominators[num_denominators++] = 1000000000; goto success; } #endif

#ifdef HAVE_TIMES #define RUBY_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID
ID2SYM(id_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID) if (clk_id == RUBY_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID) { struct tms buf; unsigned_clock_t utime, stime; if (times(&buf) == (clock_t)-1) rb_sys_fail("times"); utime = (unsigned_clock_t)buf.tms_utime; stime = (unsigned_clock_t)buf.tms_stime; tt.count = (int32_t)((utime % 1000000000) + (stime % 1000000000)); tt.giga_count = (utime / 1000000000) + (stime / 1000000000); if (1000000000 <= tt.count) { tt.count -= 1000000000; tt.giga_count++; } denominators[num_denominators++] = get_clk_tck(); goto success; } #endif

#define RUBY_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID
ID2SYM(id_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID) if (clk_id == RUBY_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID) { clock_t c; unsigned_clock_t uc; errno = 0; c = clock(); if (c == (clock_t)-1) rb_sys_fail("clock"); uc = (unsigned_clock_t)c; tt.count = (int32_t)(uc % 1000000000); tt.giga_count = uc / 1000000000; denominators[num_denominators++] = CLOCKS_PER_SEC; goto success; }

#ifdef APPLE if (clk_id == RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC) { const mach_timebase_info_data_t *info = get_mach_timebase_info(); uint64_t t = mach_absolute_time(); tt.count = (int32_t)(t % 1000000000); tt.giga_count = t / 1000000000; numerators[num_numerators++] = info->numer; denominators[num_denominators++] = info->denom; denominators[num_denominators++] = 1000000000; goto success; } #endif } else if (NUMERIC_CLOCKID) { #if defined(HAVE_CLOCK_GETTIME) struct timespec ts; c = NUM2CLOCKID(clk_id); gettime: ret = clock_gettime(c, &ts); if (ret == -1) clock_failed("gettime", errno, clk_id); tt.count = (int32_t)ts.tv_nsec; tt.giga_count = ts.tv_sec; denominators[num_denominators++] = 1000000000; goto success; #endif } else { rb_unexpected_type(clk_id, T_SYMBOL); } clock_failed("gettime", EINVAL, clk_id);

success: return make_clock_result(&tt, numerators, num_numerators, denominators, num_denominators, unit); }

daemon(nochdir = nil, noclose = nil) → 0 click to toggle source

Detaches the current process from its controlling terminal and runs it in the background as system daemon; returns zero.

By default:

If optional argument nochdir is true, does not change the current working directory.

If optional argument noclose is true, does not redirect stdin,stdin, stdin,stdout, or $stderr.

static VALUE proc_daemon(int argc, VALUE *argv, VALUE _) { int n, nochdir = FALSE, noclose = FALSE;

switch (rb_check_arity(argc, 0, 2)) {
  case 2: noclose = TO_BOOL(argv[1], "noclose");
  case 1: nochdir = TO_BOOL(argv[0], "nochdir");
}

prefork();
n = rb_daemon(nochdir, noclose);
if (n < 0) rb_sys_fail("daemon");
return INT2FIX(n);

}

detach(pid) → thread click to toggle source

Avoids the potential for a child process to become a zombie process. Process.detach prevents this by setting up a separate Ruby thread whose sole job is to reap the status of the process pid when it terminates.

This method is needed only when the parent process will never wait for the child process.

This example does not reap the second child process; that process appears as a zombie in the process status (ps) output:

pid = Process.spawn('ruby', '-e', 'exit 13') sleep(1)

system("ps -ho pid,state -p #{pid}")

Output:

312716 Z

This example also does not reap the second child process, but it does detach the process so that it does not become a zombie:

pid = Process.spawn('ruby', '-e', 'exit 13') thread = Process.detach(pid) sleep(1)

system("ps -ho pid,state -p #{pid}")

The waiting thread can return the pid of the detached child process:

thread.join.pid

static VALUE proc_detach(VALUE obj, VALUE pid) { return rb_detach_process(NUM2PIDT(pid)); }

egid → integer click to toggle source

Process::GID.eid → integer

Process::Sys.geteid → integer

Returns the effective group ID for the current process:

Process.egid

Not available on all platforms.

static VALUE proc_getegid(VALUE obj) { rb_gid_t egid = getegid();

return GIDT2NUM(egid);

}

egid = new_egid → new_egid click to toggle source

Sets the effective group ID for the current process.

Not available on all platforms.

static VALUE proc_setegid(VALUE obj, VALUE egid) { #if defined(HAVE_SETRESGID) || defined(HAVE_SETREGID) || defined(HAVE_SETEGID) || defined(HAVE_SETGID) rb_gid_t gid; #endif

check_gid_switch();

#if defined(HAVE_SETRESGID) || defined(HAVE_SETREGID) || defined(HAVE_SETEGID) || defined(HAVE_SETGID) gid = OBJ2GID(egid); #endif

#if defined(HAVE_SETRESGID) if (setresgid(-1, gid, -1) < 0) rb_sys_fail(0); #elif defined HAVE_SETREGID if (setregid(-1, gid) < 0) rb_sys_fail(0); #elif defined HAVE_SETEGID if (setegid(gid) < 0) rb_sys_fail(0); #elif defined HAVE_SETGID if (gid == getgid()) { if (setgid(gid) < 0) rb_sys_fail(0); } else { rb_notimplement(); } #else rb_notimplement(); #endif return egid; }

euid → integer click to toggle source

Process::UID.eid → integer

Process::Sys.geteuid → integer

Returns the effective user ID for the current process.

Process.euid

static VALUE proc_geteuid(VALUE obj) { rb_uid_t euid = geteuid(); return UIDT2NUM(euid); }

euid = new_euid → new_euid click to toggle source

Sets the effective user ID for the current process.

Not available on all platforms.

static VALUE proc_seteuid_m(VALUE mod, VALUE euid) { check_uid_switch(); proc_seteuid(OBJ2UID(euid)); return euid; }

exec([env, ] command_line, options = {}) click to toggle source

exec([env, ] exe_path, *args, options = {})

Replaces the current process by doing one of the following:

This method has potential security vulnerabilities if called with untrusted input; see Command Injection.

The new process is created using the exec system call; it may inherit some of its environment from the calling program (possibly including open file descriptors).

Argument env, if given, is a hash that affects ENV for the new process; see Execution Environment.

Argument options is a hash of options for the new process; see Execution Options.

The first required argument is one of the following:

Argument command_line

String argument command_line is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:

exec('if true; then echo "Foo"; fi') exec('exit')
exec('date > date.tmp')

The command line may also contain arguments and options for the command:

exec('echo "Foo"')

Output:

Foo

See Execution Shell for details about the shell.

Raises an exception if the new process could not execute.

Argument exe_path

Argument exe_path is one of the following:

Example:

exec('/usr/bin/date')

Output:

Sat Aug 26 09:38:00 AM CDT 2023

Ruby invokes the executable directly. This form does not use the shell; see Arguments args for caveats.

exec('doesnt_exist')

If one or more args is given, each is an argument or option to be passed to the executable:

exec('echo', 'C*') exec('echo', 'hello', 'world')

Output:

C* hello world

Raises an exception if the new process could not execute.

static VALUE f_exec(int c, const VALUE *a, VALUE _) { rb_f_exec(c, a); UNREACHABLE_RETURN(Qnil); }

exit(status = true) click to toggle source

exit(status = true)

Initiates termination of the Ruby script by raising SystemExit; the exception may be caught. Returns exit status status to the underlying operating system.

Values true and false for argument status indicate, respectively, success and failure; The meanings of integer values are system-dependent.

Example:

begin exit puts 'Never get here.' rescue SystemExit puts 'Rescued a SystemExit exception.' end puts 'After begin block.'

Output:

Rescued a SystemExit exception. After begin block.

Just prior to final termination, Ruby executes any at-exit procedures (see Kernel::at_exit) and any object finalizers (see ObjectSpace::define_finalizer).

Example:

at_exit { puts 'In at_exit function.' } ObjectSpace.define_finalizer('string', proc { puts 'In finalizer.' }) exit

Output:

In at_exit function. In finalizer.

static VALUE f_exit(int c, const VALUE *a, VALUE _) { rb_f_exit(c, a); UNREACHABLE_RETURN(Qnil); }

exit!(status = false) click to toggle source

exit!(status = false)

Exits the process immediately; no exit handlers are called. Returns exit status status to the underlying operating system.

Process.exit!(true)

Values true and false for argument status indicate, respectively, success and failure; The meanings of integer values are system-dependent.

static VALUE rb_f_exit_bang(int argc, VALUE *argv, VALUE obj) { int istatus;

if (rb_check_arity(argc, 0, 1) == 1) {
    istatus = exit_status_code(argv[0]);
}
else {
    istatus = EXIT_FAILURE;
}
_exit(istatus);

UNREACHABLE_RETURN(Qnil);

}

fork { ... } → integer or nil click to toggle source

fork → integer or nil

Creates a child process.

With a block given, runs the block in the child process; on block exit, the child terminates with a status of zero:

puts "Before the fork: #{Process.pid}" fork do puts "In the child process: #{Process.pid}" end
puts "After the fork: #{Process.pid}"

Output:

Before the fork: 420496 After the fork: 420496 In the child process: 420520

With no block given, the fork call returns twice:

Example:

puts "This is the first line before the fork (pid #{Process.pid})" puts fork puts "This is the second line after the fork (pid #{Process.pid})"

Output:

This is the first line before the fork (pid 420199) 420223 This is the second line after the fork (pid 420199)

This is the second line after the fork (pid 420223)

In either case, the child process may exit using Kernel.exit! to avoid the call to Kernel#at_exit.

To avoid zombie processes, the parent process should call either:

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

Note that method fork is available on some platforms, but not on others:

Process.respond_to?(:fork)

If not, you may use ::spawn instead of fork.

static VALUE rb_f_fork(VALUE obj) { rb_pid_t pid;

pid = rb_call_proc__fork();

if (pid == 0) {
    if (rb_block_given_p()) {
        int status;
        rb_protect(rb_yield, Qundef, &status);
        ruby_stop(status);
    }
    return Qnil;
}

return PIDT2NUM(pid);

}

getpgid(pid) → integer click to toggle source

Returns the process group ID for the given process ID +pid+:

Process.getpgid(Process.ppid) # => 25527

Not available on all platforms.

static VALUE proc_getpgid(VALUE obj, VALUE pid) { rb_pid_t i;

i = getpgid(NUM2PIDT(pid));
if (i < 0) rb_sys_fail(0);
return PIDT2NUM(i);

}

getpgrp → integer click to toggle source

Returns the process group ID for the current process:

Process.getpgid(0) Process.getpgrp

static VALUE proc_getpgrp(VALUE _) { rb_pid_t pgrp;

#if defined(HAVE_GETPGRP) && defined(GETPGRP_VOID) pgrp = getpgrp(); if (pgrp < 0) rb_sys_fail(0); return PIDT2NUM(pgrp); #else /* defined(HAVE_GETPGID) */ pgrp = getpgid(0); if (pgrp < 0) rb_sys_fail(0); return PIDT2NUM(pgrp); #endif }

getpriority(kind, id) → integer click to toggle source

Returns the scheduling priority for specified process, process group, or user.

Argument kind is one of:

Argument id is the ID for the process, process group, or user; zero specified the current ID for kind.

Examples:

Process.getpriority(Process::PRIO_USER, 0)
Process.getpriority(Process::PRIO_PROCESS, 0)

Not available on all platforms.

static VALUE proc_getpriority(VALUE obj, VALUE which, VALUE who) { int prio, iwhich, iwho;

iwhich = NUM2INT(which);
iwho   = NUM2INT(who);

errno = 0;
prio = getpriority(iwhich, iwho);
if (errno) rb_sys_fail(0);
return INT2FIX(prio);

}

getrlimit(resource) → [cur_limit, max_limit] click to toggle source

Returns a 2-element array of the current (soft) limit and maximum (hard) limit for the given resource.

Argument resource specifies the resource whose limits are to be returned; see Process.setrlimit.

Each of the returned values cur_limit and max_limit is an integer; see Process.setrlimit.

Example:

Process.getrlimit(:CORE)

See Process.setrlimit.

Not available on all platforms.

static VALUE proc_getrlimit(VALUE obj, VALUE resource) { struct rlimit rlim;

if (getrlimit(rlimit_resource_type(resource), &rlim) < 0) {
    rb_sys_fail("getrlimit");
}
return rb_assoc_new(RLIM2NUM(rlim.rlim_cur), RLIM2NUM(rlim.rlim_max));

}

getsid(pid = nil) → integer click to toggle source

Returns the session ID of the given process ID pid, or of the current process if not given:

Process.getsid
Process.getsid(0)
Process.getsid(Process.pid())

Not available on all platforms.

static VALUE proc_getsid(int argc, VALUE *argv, VALUE _) { rb_pid_t sid; rb_pid_t pid = 0;

if (rb_check_arity(argc, 0, 1) == 1 && !NIL_P(argv[0]))
    pid = NUM2PIDT(argv[0]);

sid = getsid(pid);
if (sid < 0) rb_sys_fail(0);
return PIDT2NUM(sid);

}

gid → integer click to toggle source

Process::GID.rid → integer

Process::Sys.getgid → integer

Returns the (real) group ID for the current process:

Process.gid

static VALUE proc_getgid(VALUE obj) { rb_gid_t gid = getgid(); return GIDT2NUM(gid); }

gid = new_gid → new_gid click to toggle source

Sets the group ID for the current process to new_gid:

Process.gid = 1000

static VALUE proc_setgid(VALUE obj, VALUE id) { rb_gid_t gid;

check_gid_switch();

gid = OBJ2GID(id);

#if defined(HAVE_SETRESGID) if (setresgid(gid, -1, -1) < 0) rb_sys_fail(0); #elif defined HAVE_SETREGID if (setregid(gid, -1) < 0) rb_sys_fail(0); #elif defined HAVE_SETRGID if (setrgid(gid) < 0) rb_sys_fail(0); #elif defined HAVE_SETGID { if (getegid() == gid) { if (setgid(gid) < 0) rb_sys_fail(0); } else { rb_notimplement(); } } #endif return GIDT2NUM(gid); }

groups → array click to toggle source

Returns an array of the group IDs in the supplemental group access list for the current process:

Process.groups

These properties of the returned array are system-dependent:

Use this call to get a sorted and unique array:

Process.groups.uniq.sort

static VALUE proc_getgroups(VALUE obj) { VALUE ary, tmp; int i, ngroups; rb_gid_t *groups;

ngroups = getgroups(0, NULL);
if (ngroups == -1)
    rb_sys_fail(0);

groups = ALLOCV_N(rb_gid_t, tmp, ngroups);

ngroups = getgroups(ngroups, groups);
if (ngroups == -1)
    rb_sys_fail(0);

ary = rb_ary_new();
for (i = 0; i < ngroups; i++)
    rb_ary_push(ary, GIDT2NUM(groups[i]));

ALLOCV_END(tmp);

return ary;

}

groups = new_groups → new_groups click to toggle source

Sets the supplemental group access list to the given array of group IDs.

Process.groups
Process.groups = [27, 6, 10, 11]
Process.groups

static VALUE proc_setgroups(VALUE obj, VALUE ary) { int ngroups, i; rb_gid_t *groups; VALUE tmp; PREPARE_GETGRNAM;

Check_Type(ary, T_ARRAY);

ngroups = RARRAY_LENINT(ary);
if (ngroups > maxgroups())
    rb_raise(rb_eArgError, "too many groups, %d max", maxgroups());

groups = ALLOCV_N(rb_gid_t, tmp, ngroups);

for (i = 0; i < ngroups; i++) {
    VALUE g = RARRAY_AREF(ary, i);

    groups[i] = OBJ2GID1(g);
}
FINISH_GETGRNAM;

if (setgroups(ngroups, groups) == -1) /* ngroups <= maxgroups */
    rb_sys_fail(0);

ALLOCV_END(tmp);

return proc_getgroups(obj);

}

initgroups(username, gid) → array click to toggle source

Sets the supplemental group access list; the new list includes:

Example:

Process.groups
Process.initgroups('me', 30)
Process.groups

Not available on all platforms.

static VALUE proc_initgroups(VALUE obj, VALUE uname, VALUE base_grp) { if (initgroups(StringValueCStr(uname), OBJ2GID(base_grp)) != 0) { rb_sys_fail(0); } return proc_getgroups(obj); }

kill(signal, *ids) → count click to toggle source

Sends a signal to each process specified by ids (which must specify at least one ID); returns the count of signals sent.

For each given id, if id is:

Argument signal specifies the signal to be sent; the argument may be:

If signal is:

Use method Signal.list to see which signals are supported by Ruby on the underlying platform; the method returns a hash of the string names and non-negative integer values of the supported signals. The size and content of the returned hash varies widely among platforms.

Additionally, signal 0 is useful to determine if the process exists.

Example:

pid = fork do Signal.trap('HUP') { puts 'Ouch!'; exit }

end

Process.kill('HUP', pid) Process.wait

Output:

Ouch!

Exceptions:

In the last two cases, signals may have been sent to some processes.

static VALUE proc_rb_f_kill(int c, const VALUE *v, VALUE _) { return rb_f_kill(c, v); }

last_status → Process::Status or nil click to toggle source

Returns a Process::Status object representing the most recently exited child process in the current thread, or nil if none:

Process.spawn('ruby', '-e', 'exit 13') Process.wait Process.last_status

Process.spawn('ruby', '-e', 'exit 14') Process.wait Process.last_status

Process.spawn('ruby', '-e', 'exit 15')

Process.last_status Process.wait Process.last_status

static VALUE proc_s_last_status(VALUE mod) { return rb_last_status_get(); }

maxgroups → integer click to toggle source

Returns the maximum number of group IDs allowed in the supplemental group access list:

Process.maxgroups

static VALUE proc_getmaxgroups(VALUE obj) { return INT2FIX(maxgroups()); }

maxgroups = new_max → new_max click to toggle source

Sets the maximum number of group IDs allowed in the supplemental group access list.

static VALUE proc_setmaxgroups(VALUE obj, VALUE val) { int ngroups = FIX2INT(val); int ngroups_max = get_sc_ngroups_max();

if (ngroups <= 0)
    rb_raise(rb_eArgError, "maxgroups %d should be positive", ngroups);

if (ngroups > RB_MAX_GROUPS)
    ngroups = RB_MAX_GROUPS;

if (ngroups_max > 0 && ngroups > ngroups_max)
    ngroups = ngroups_max;

_maxgroups = ngroups;

return INT2FIX(_maxgroups);

}

pid → integer click to toggle source

Returns the process ID of the current process:

Process.pid

static VALUE proc_get_pid(VALUE _) { return get_pid(); }

ppid → integer click to toggle source

Returns the process ID of the parent of the current process:

puts "Pid is #{Process.pid}." fork { puts "Parent pid is #{Process.ppid}." }

Output:

Pid is 271290. Parent pid is 271290

May not return a trustworthy value on certain platforms.

static VALUE proc_get_ppid(VALUE _) { return get_ppid(); }

setpgid(pid, pgid) → 0 click to toggle source

Sets the process group ID for the process given by process ID pid to pgid.

Not available on all platforms.

static VALUE proc_setpgid(VALUE obj, VALUE pid, VALUE pgrp) { rb_pid_t ipid, ipgrp;

ipid = NUM2PIDT(pid);
ipgrp = NUM2PIDT(pgrp);

if (setpgid(ipid, ipgrp) < 0) rb_sys_fail(0);
return INT2FIX(0);

}

setpgrp → 0 click to toggle source

Equivalent to setpgid(0, 0).

Not available on all platforms.

static VALUE proc_setpgrp(VALUE _) { /* check for posix setpgid() first; this matches the posix / / getpgrp() above. It appears that configure will set SETPGRP_VOID / / even though setpgrp(0,0) would be preferred. The posix call avoids / / this confusion. */ #ifdef HAVE_SETPGID if (setpgid(0,0) < 0) rb_sys_fail(0); #elif defined(HAVE_SETPGRP) && defined(SETPGRP_VOID) if (setpgrp() < 0) rb_sys_fail(0); #endif return INT2FIX(0); }

setpriority(kind, integer, priority) → 0 click to toggle source

See Process.getpriority.

Examples:

Process.setpriority(Process::PRIO_USER, 0, 19)
Process.setpriority(Process::PRIO_PROCESS, 0, 19) Process.getpriority(Process::PRIO_USER, 0)
Process.getpriority(Process::PRIO_PROCESS, 0)

Not available on all platforms.

static VALUE proc_setpriority(VALUE obj, VALUE which, VALUE who, VALUE prio) { int iwhich, iwho, iprio;

iwhich = NUM2INT(which);
iwho   = NUM2INT(who);
iprio  = NUM2INT(prio);

if (setpriority(iwhich, iwho, iprio) < 0)
    rb_sys_fail(0);
return INT2FIX(0);

}

setproctitle(string) → string click to toggle source

Sets the process title that appears on the ps(1) command. Not necessarily effective on all platforms. No exception will be raised regardless of the result, nor will NotImplementedError be raised even if the platform does not support the feature.

Calling this method does not affect the value of $0.

Process.setproctitle('myapp: worker #%d' % worker_id)

This method first appeared in Ruby 2.1 to serve as a global variable free means to change the process title.

static VALUE proc_setproctitle(VALUE process, VALUE title) { return ruby_setproctitle(title); }

setrlimit(resource, cur_limit, max_limit = cur_limit) → nil click to toggle source

Sets limits for the current process for the given resource to cur_limit (soft limit) and max_limit (hard limit); returns nil.

Argument resource specifies the resource whose limits are to be set; the argument may be given as a symbol, as a string, or as a constant beginning with Process::RLIMIT_ (e.g., :CORE, 'CORE', or Process::RLIMIT_CORE.

The resources available and supported are system-dependent, and may include (here expressed as symbols):

Arguments cur_limit and max_limit may be:

This example raises the soft limit of core size to the hard limit to try to make core dump possible:

Process.setrlimit(:CORE, Process.getrlimit(:CORE)[1])

Not available on all platforms.

static VALUE proc_setrlimit(int argc, VALUE *argv, VALUE obj) { VALUE resource, rlim_cur, rlim_max; struct rlimit rlim;

rb_check_arity(argc, 2, 3);
resource = argv[0];
rlim_cur = argv[1];
if (argc < 3 || NIL_P(rlim_max = argv[2]))
    rlim_max = rlim_cur;

rlim.rlim_cur = rlimit_resource_value(rlim_cur);
rlim.rlim_max = rlimit_resource_value(rlim_max);

if (setrlimit(rlimit_resource_type(resource), &rlim) < 0) {
    rb_sys_fail("setrlimit");
}
return Qnil;

}

setsid → integer click to toggle source

Establishes the current process as a new session and process group leader, with no controlling tty; returns the session ID:

Process.setsid

Not available on all platforms.

static VALUE proc_setsid(VALUE _) { rb_pid_t pid;

pid = setsid();
if (pid < 0) rb_sys_fail(0);
return PIDT2NUM(pid);

}

spawn([env, ] command_line, options = {}) → pid click to toggle source

spawn([env, ] exe_path, *args, options = {}) → pid

Creates a new child process by doing one of the following in that process:

This method has potential security vulnerabilities if called with untrusted input; see Command Injection.

Returns the process ID (pid) of the new process, without waiting for it to complete.

To avoid zombie processes, the parent process should call either:

The new process is created using the exec system call; it may inherit some of its environment from the calling program (possibly including open file descriptors).

Argument env, if given, is a hash that affects ENV for the new process; see Execution Environment.

Argument options is a hash of options for the new process; see Execution Options.

The first required argument is one of the following:

Argument command_line

String argument command_line is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:

spawn('if true; then echo "Foo"; fi') Process.wait
spawn('exit')
Process.wait
spawn('date > /tmp/date.tmp')
Process.wait
spawn('date > /nop/date.tmp')
Process.wait

The command line may also contain arguments and options for the command:

spawn('echo "Foo"') Process.wait

Output:

Foo

See Execution Shell for details about the shell.

Raises an exception if the new process could not execute.

Argument exe_path

Argument exe_path is one of the following:

Ruby invokes the executable directly. This form does not use the shell; see Arguments args for caveats.

If one or more args is given, each is an argument or option to be passed to the executable:

spawn('echo', 'C*')
Process.wait
spawn('echo', 'hello', 'world') Process.wait

Output:

C* hello world

Raises an exception if the new process could not execute.

static VALUE rb_f_spawn(int argc, VALUE *argv, VALUE _) { rb_pid_t pid; char errmsg[CHILD_ERRMSG_BUFLEN] = { '\0' }; VALUE execarg_obj, fail_str; struct rb_execarg *eargp;

execarg_obj = rb_execarg_new(argc, argv, TRUE, FALSE);
eargp = rb_execarg_get(execarg_obj);
fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;

pid = rb_execarg_spawn(execarg_obj, errmsg, sizeof(errmsg));

if (pid == -1) {
    int err = errno;
    rb_exec_fail(eargp, err, errmsg);
    RB_GC_GUARD(execarg_obj);
    rb_syserr_fail_str(err, fail_str);
}

#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV) return PIDT2NUM(pid); #else return Qnil; #endif }

times → process_tms click to toggle source

Returns a Process::Tms structure that contains user and system CPU times for the current process, and for its children processes:

Process.times

The precision is platform-defined.

VALUE rb_proc_times(VALUE obj) { VALUE utime, stime, cutime, cstime, ret; #if defined(RUSAGE_SELF) && defined(RUSAGE_CHILDREN) struct rusage usage_s, usage_c;

if (getrusage(RUSAGE_SELF, &usage_s) != 0 || getrusage(RUSAGE_CHILDREN, &usage_c) != 0)
    rb_sys_fail("getrusage");
utime = DBL2NUM((double)usage_s.ru_utime.tv_sec + (double)usage_s.ru_utime.tv_usec/1e6);
stime = DBL2NUM((double)usage_s.ru_stime.tv_sec + (double)usage_s.ru_stime.tv_usec/1e6);
cutime = DBL2NUM((double)usage_c.ru_utime.tv_sec + (double)usage_c.ru_utime.tv_usec/1e6);
cstime = DBL2NUM((double)usage_c.ru_stime.tv_sec + (double)usage_c.ru_stime.tv_usec/1e6);

#else const double hertz = (double)get_clk_tck(); struct tms buf;

times(&buf);
utime = DBL2NUM(buf.tms_utime / hertz);
stime = DBL2NUM(buf.tms_stime / hertz);
cutime = DBL2NUM(buf.tms_cutime / hertz);
cstime = DBL2NUM(buf.tms_cstime / hertz);

#endif ret = rb_struct_new(rb_cProcessTms, utime, stime, cutime, cstime); RB_GC_GUARD(utime); RB_GC_GUARD(stime); RB_GC_GUARD(cutime); RB_GC_GUARD(cstime); return ret; }

uid → integer click to toggle source

Process::UID.rid → integer

Process::Sys.getuid → integer

Returns the (real) user ID of the current process.

Process.uid

static VALUE proc_getuid(VALUE obj) { rb_uid_t uid = getuid(); return UIDT2NUM(uid); }

uid = new_uid → new_uid click to toggle source

Sets the (user) user ID for the current process to new_uid:

Process.uid = 1000

Not available on all platforms.

static VALUE proc_setuid(VALUE obj, VALUE id) { rb_uid_t uid;

check_uid_switch();

uid = OBJ2UID(id);

#if defined(HAVE_SETRESUID) if (setresuid(uid, -1, -1) < 0) rb_sys_fail(0); #elif defined HAVE_SETREUID if (setreuid(uid, -1) < 0) rb_sys_fail(0); #elif defined HAVE_SETRUID if (setruid(uid) < 0) rb_sys_fail(0); #elif defined HAVE_SETUID { if (geteuid() == uid) { if (setuid(uid) < 0) rb_sys_fail(0); } else { rb_notimplement(); } } #endif return id; }

wait(pid = -1, flags = 0) → integer click to toggle source

Waits for a suitable child process to exit, returns its process ID, and sets $? to a Process::Status object containing information on that process. Which child it waits for depends on the value of the given pid:

Argument flags should be given as one of the following constants, or as the logical OR of both:

Not all flags are available on all platforms.

Raises Errno::ECHILD if there is no suitable child process.

Not available on all platforms.

Process.waitpid is an alias for Process.wait.

static VALUE proc_m_wait(int c, VALUE *v, VALUE _) { return proc_wait(c, v); }

wait2(pid = -1, flags = 0) → [pid, status] click to toggle source

Like Process.waitpid, but returns an array containing the child process pid and Process::Status status:

pid = Process.spawn('ruby', '-e', 'exit 13') Process.wait2(pid)

Process.waitpid2 is an alias for Process.wait2.

static VALUE proc_wait2(int argc, VALUE *argv, VALUE _) { VALUE pid = proc_wait(argc, argv); if (NIL_P(pid)) return Qnil; return rb_assoc_new(pid, rb_last_status_get()); }

waitall → array click to toggle source

Waits for all children, returns an array of 2-element arrays; each subarray contains the integer pid and Process::Status status for one of the reaped child processes:

pid0 = Process.spawn('ruby', '-e', 'exit 13') pid1 = Process.spawn('ruby', '-e', 'exit 14') Process.waitall

static VALUE proc_waitall(VALUE _) { VALUE result; rb_pid_t pid; int status;

result = rb_ary_new();
rb_last_status_clear();

for (pid = -1;;) {
    pid = rb_waitpid(-1, &status, 0);
    if (pid == -1) {
        int e = errno;
        if (e == ECHILD)
            break;
        rb_syserr_fail(e, 0);
    }
    rb_ary_push(result, rb_assoc_new(PIDT2NUM(pid), rb_last_status_get()));
}
return result;

}

wait(pid = -1, flags = 0) → integer click to toggle source

Waits for a suitable child process to exit, returns its process ID, and sets $? to a Process::Status object containing information on that process. Which child it waits for depends on the value of the given pid:

Argument flags should be given as one of the following constants, or as the logical OR of both:

Not all flags are available on all platforms.

Raises Errno::ECHILD if there is no suitable child process.

Not available on all platforms.

Process.waitpid is an alias for Process.wait.

static VALUE proc_m_wait(int c, VALUE *v, VALUE _) { return proc_wait(c, v); }

wait2(pid = -1, flags = 0) → [pid, status] click to toggle source

Like Process.waitpid, but returns an array containing the child process pid and Process::Status status:

pid = Process.spawn('ruby', '-e', 'exit 13') Process.wait2(pid)

Process.waitpid2 is an alias for Process.wait2.

static VALUE proc_wait2(int argc, VALUE *argv, VALUE _) { VALUE pid = proc_wait(argc, argv); if (NIL_P(pid)) return Qnil; return rb_assoc_new(pid, rb_last_status_get()); }

warmup → true click to toggle source

Notify the Ruby virtual machine that the boot sequence is finished, and that now is a good time to optimize the application. This is useful for long running applications.

This method is expected to be called at the end of the application boot. If the application is deployed using a pre-forking model, Process.warmup should be called in the original process before the first fork.

The actual optimizations performed are entirely implementation specific and may change in the future without notice.

On CRuby, Process.warmup:

static VALUE proc_warmup(VALUE _) { RB_VM_LOCK_ENTER(); rb_gc_prepare_heap(); RB_VM_LOCK_LEAVE(); return Qtrue; }