Movatterモバイル変換


[0]ホーム

URL:


HomeClassesMethods

In Files

  • process.c
  • ruby.c

Namespace

Methods

Files

Class/Module Index[+]

Quicksearch
No matching classes.

Process

The module contains several groups of functionality for handling OSprocesses:

  • Low-level property introspection and management of the current process,like::argv0,::pid;

  • Low-level introspection of other processes, like::getpgid,::getpriority;

  • Management of the current process:::abort,::exit,::daemon, etc. (for convenience,most of those are also available as global functions and module functionsofKernel);

  • Creation and management of child processes:::fork,::spawn, and related methods;

  • Management of low-level system clock:::times and::clock_gettime, which couldbe important for proper benchmarking and other elapsed time measurementtasks.

Constants

CLOCK_BOOTTIME

see::clock_gettime

CLOCK_BOOTTIME_ALARM

see::clock_gettime

CLOCK_MONOTONIC

see::clock_gettime

CLOCK_MONOTONIC_COARSE

see::clock_gettime

CLOCK_MONOTONIC_FAST

see::clock_gettime

CLOCK_MONOTONIC_PRECISE

see::clock_gettime

CLOCK_MONOTONIC_RAW

see::clock_gettime

CLOCK_MONOTONIC_RAW_APPROX

see::clock_gettime

CLOCK_PROCESS_CPUTIME_ID

see::clock_gettime

CLOCK_PROF

see::clock_gettime

CLOCK_REALTIME

see::clock_gettime

CLOCK_REALTIME_ALARM

see::clock_gettime

CLOCK_REALTIME_COARSE

see::clock_gettime

CLOCK_REALTIME_FAST

see::clock_gettime

CLOCK_REALTIME_PRECISE

see::clock_gettime

CLOCK_SECOND

see::clock_gettime

CLOCK_TAI

see::clock_gettime

CLOCK_THREAD_CPUTIME_ID

see::clock_gettime

CLOCK_UPTIME

see::clock_gettime

CLOCK_UPTIME_FAST

see::clock_gettime

CLOCK_UPTIME_PRECISE

see::clock_gettime

CLOCK_UPTIME_RAW

see::clock_gettime

CLOCK_UPTIME_RAW_APPROX

see::clock_gettime

CLOCK_VIRTUAL

see::clock_gettime

PRIO_PGRP

see::setpriority

PRIO_PROCESS

see::setpriority

PRIO_USER

see::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 POSIXmessage 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 thatcan 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 ofthe calling process.

see the system getrlimit(2) manual for details.

RLIMIT_RSS

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 thisprocess.

see the system getrlimit(2) manual for details.

RLIMIT_RTTIME

Specifies limit on CPU time this process scheduled under a real-timescheduling 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 realuser 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::setrlimit

RLIM_SAVED_CUR

see::setrlimit

RLIM_SAVED_MAX

see::setrlimit

WNOHANG

see::wait

WUNTRACED

see::wait

Public Class Methods

abort(*args)click to toggle source
                static VALUE f_abort(int c, const VALUE *a, VALUE _))
argv0 → frozen_stringclick to toggle source

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

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

                static VALUEproc_argv0(VALUE process){    return rb_orig_progname;}
clock_getres(clock_id [, unit]) → numberclick to toggle source

Returns an estimate of the resolution of aclock_id using thePOSIXclock_getres() function.

Note the reported resolution is often inaccurate on most platforms due tounderlying bugs for this function and therefore the reported resolutionoften differs from the actual resolution of the clock in practice.Inaccurate reported resolutions have been observed for various clocksincludingCLOCK_MONOTONIC andCLOCK_MONOTONIC_RAW when usingLinux, macOS, BSD or AIX platforms, when using ARM processors, or whenusing virtualization.

clock_id specifies a kind of clock. See the document ofProcess.clock_gettime for details.clock_id canbe a symbol as forProcess.clock_gettime.

If the givenclock_id is not supported, Errno::EINVAL israised.

unit specifies the type of the return value.Process.clock_getres acceptsunit asProcess.clock_gettime. The default value,:float_second, is also the same asProcess.clock_gettime.

Process.clock_getres also accepts:hertz asunit.:hertz means the reciprocal of:float_second.

:hertz can be used to obtain the exact value of the clockticks per second for the times() function and CLOCKS_PER_SEC for theclock() function.

Process.clock_getres(:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID,:hertz) returns the clock ticks per second.

Process.clock_getres(:CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID,:hertz) returns CLOCKS_PER_SEC.

pProcess.clock_getres(Process::CLOCK_MONOTONIC)#=> 1.0e-09
                static VALUErb_clock_getres(int argc, VALUE *argv, VALUE _){    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];    if (SYMBOL_P(clk_id)) {#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 defined(HAVE_CLOCK_GETRES)        struct timespec ts;        clockid_t c = NUM2CLOCKID(clk_id);        int ret = clock_getres(c, &ts);        if (ret == -1)            rb_sys_fail("clock_getres");        tt.count = (int32_t)ts.tv_nsec;        tt.giga_count = ts.tv_sec;        denominators[num_denominators++] = 1000000000;        goto success;#endif    }    /* EINVAL emulates clock_getres behavior when clock_id is invalid. */    rb_syserr_fail(EINVAL, 0);  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]) → numberclick to toggle source

Returns a time returned by POSIX::clock_gettime() function.

pProcess.clock_gettime(Process::CLOCK_MONOTONIC)#=> 896053.968060096

clock_id specifies a kind of clock. It is specified as aconstant which begins withProcess::CLOCK_ such asProcess::CLOCK_REALTIME andProcess::CLOCK_MONOTONIC.

The supported constants depends on OS and version. Ruby provides followingtypes ofclock_id if available.

CLOCK_REALTIME

SUSv2 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 2.1, macOS 10.12

CLOCK_MONOTONIC

SUSv3 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 3.4, macOS 10.12

CLOCK_PROCESS_CPUTIME_ID

SUSv3 to 4, Linux 2.5.63, FreeBSD 9.3, OpenBSD 5.4, macOS 10.12

CLOCK_THREAD_CPUTIME_ID

SUSv3 to 4, Linux 2.5.63, FreeBSD 7.1, OpenBSD 5.4, macOS 10.12

CLOCK_VIRTUAL

FreeBSD 3.0, OpenBSD 2.1

CLOCK_PROF

FreeBSD 3.0, OpenBSD 2.1

CLOCK_REALTIME_FAST

FreeBSD 8.1

CLOCK_REALTIME_PRECISE

FreeBSD 8.1

CLOCK_REALTIME_COARSE

Linux 2.6.32

CLOCK_REALTIME_ALARM

Linux 3.0

CLOCK_MONOTONIC_FAST

FreeBSD 8.1

CLOCK_MONOTONIC_PRECISE

FreeBSD 8.1

CLOCK_MONOTONIC_COARSE

Linux 2.6.32

CLOCK_MONOTONIC_RAW

Linux 2.6.28, macOS 10.12

CLOCK_MONOTONIC_RAW_APPROX

macOS 10.12

CLOCK_BOOTTIME

Linux 2.6.39

CLOCK_BOOTTIME_ALARM

Linux 3.0

CLOCK_UPTIME

FreeBSD 7.0, OpenBSD 5.5

CLOCK_UPTIME_FAST

FreeBSD 8.1

CLOCK_UPTIME_RAW

macOS 10.12

CLOCK_UPTIME_RAW_APPROX

macOS 10.12

CLOCK_UPTIME_PRECISE

FreeBSD 8.1

CLOCK_SECOND

FreeBSD 8.1

CLOCK_TAI

Linux 3.10

Note that SUS stands for Single Unix Specification. SUS contains POSIX and::clock_gettime isdefined in the POSIX part. SUS definesCLOCK_REALTIME mandatory butCLOCK_MONOTONIC,CLOCK_PROCESS_CPUTIME_IDandCLOCK_THREAD_CPUTIME_ID areoptional.

Also, several symbols are accepted asclock_id. There areemulations for::clock_gettime().

For example,Process::CLOCK_REALTIME is definedas:GETTIMEOFDAY_BASED_CLOCK_REALTIME when::clock_gettime() is notavailable.

Emulations forCLOCK_REALTIME:

:GETTIMEOFDAY_BASED_CLOCK_REALTIME

Use gettimeofday() defined by SUS. (SUSv4 obsoleted it, though.) Theresolution is 1 microsecond.

:TIME_BASED_CLOCK_REALTIME

Use time() defined by ISO C. The resolution is 1 second.

Emulations forCLOCK_MONOTONIC:

:MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC

Use mach_absolute_time(), available on Darwin. The resolution is CPUdependent.

:TIMES_BASED_CLOCK_MONOTONIC

Use the result value of times() defined by POSIX. POSIX defines it as“times() shall return the elapsed real time, in clock ticks, since anarbitrary point in the past (for example, system start-up time)”. Forexample, GNU/Linux returns a value based on jiffies and it is monotonic.However, 4.4BSD uses gettimeofday() and it is not monotonic. (FreeBSD uses::clock_gettime(CLOCK_MONOTONIC)instead, though.) The resolution is the clock tick. “getconf CLK_TCK”command shows the clock ticks per second. (The clock ticks per second isdefined by HZ macro in older systems.) If it is 100 and clock_t is 32 bitsinteger type, the resolution is 10 millisecond and cannot represent over497 days.

Emulations forCLOCK_PROCESS_CPUTIME_ID:

:GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID

Use getrusage() defined by SUS. getrusage() is used with RUSAGE_SELF toobtain the time only for the calling process (excluding the time for childprocesses). The result is addition of user time (ru_utime) and system time(ru_stime). The resolution is 1 microsecond.

:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID

Use times() defined by POSIX. The result is addition of user time(tms_utime) and system time (tms_stime). tms_cutime and tms_cstime areignored to exclude the time for child processes. The resolution is theclock tick. “getconf CLK_TCK” command shows the clock ticks per second.(The clock ticks per second is defined by HZ macro in older systems.) If itis 100, the resolution is 10 millisecond.

:CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID

Use clock() defined by ISO C. The resolution is 1/CLOCKS_PER_SEC.CLOCKS_PER_SEC is the C-level macro defined by time.h. SUS definesCLOCKS_PER_SEC is 1000000. Non-Unix systems may define it a differentvalue, though. If CLOCKS_PER_SEC is 1000000 as SUS, the resolution is 1microsecond. If CLOCKS_PER_SEC is 1000000 and clock_t is 32 bits integertype, it cannot represent over 72 minutes.

If the givenclock_id is not supported, Errno::EINVAL israised.

unit specifies a type of the return value.

:float_second

number of seconds as a float (default)

:float_millisecond

number of milliseconds as a float

:float_microsecond

number of microseconds as a float

:second

number of seconds as an integer

:millisecond

number of milliseconds as an integer

:microsecond

number of microseconds as an integer

:nanosecond

number of nanoseconds as an integer

The underlying function,::clock_gettime(), returns anumber of nanoseconds.Float object (IEEE 754double) is not enough to represent the return value forCLOCK_REALTIME. If the exactnanoseconds value is required, use:nanoseconds as theunit.

The origin (zero) of the returned value varies. For example, system startup time, process start up time, the Epoch, etc.

The origin inCLOCK_REALTIME isdefined as the Epoch (1970-01-01 00:00:00 UTC). But some systems count leapseconds and others doesn't. So the result can be interpreteddifferently across systems.Time.nowis recommended overCLOCK_REALTIME.

                static VALUErb_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];    if (SYMBOL_P(clk_id)) {        /*         * 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__#define RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC ID2SYM(id_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();            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 defined(HAVE_CLOCK_GETTIME)        struct timespec ts;        clockid_t c;        c = NUM2CLOCKID(clk_id);        ret = clock_gettime(c, &ts);        if (ret == -1)            rb_sys_fail("clock_gettime");        tt.count = (int32_t)ts.tv_nsec;        tt.giga_count = ts.tv_sec;        denominators[num_denominators++] = 1000000000;        goto success;#endif    }    /* EINVAL emulates clock_gettime behavior when clock_id is invalid. */    rb_syserr_fail(EINVAL, 0);  success:    return make_clock_result(&tt, numerators, num_numerators, denominators, num_denominators, unit);}
daemon() → 0click to toggle source
daemon(nochdir=nil,noclose=nil) → 0

Detach the process from controlling terminal and run in the background assystem daemon. Unless the argument nochdir is true (i.e. non false), itchanges the current working directory to the root (“/”). Unless theargument noclose is true, daemon() will redirect standard input, standardoutput and standard error to /dev/null. Return zero on success, or raiseone of Errno::*.

                static VALUEproc_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) → threadclick to toggle source

Some operating systems retain the status of terminated child processesuntil the parent collects that status (normally using some variant ofwait()). If the parent never collects this status, the childstays around as azombie process.::detach prevents this by settingup a separate Ruby thread whose sole job is to reap the status of theprocesspid when it terminates. Use detach only when you do notintend to explicitly wait for the child to terminate.

The waiting thread returns the exit status of the detached process when itterminates, so you can useThread#join to know the result. Ifspecifiedpid is not a valid child process ID, the thread returnsnil immediately.

The waiting thread has pid method which returns the pid.

In this first example, we don't reap the first child process, so itappears as a zombie in the process status display.

p1 =fork {sleep0.1 }p2 =fork {sleep0.2 }Process.waitpid(p2)sleep2system("ps -ho pid,state -p #{p1}")

produces:

27389 Z

In the next example,::detach isused to reap the child automatically.

p1 =fork {sleep0.1 }p2 =fork {sleep0.2 }Process.detach(p1)Process.waitpid(p2)sleep2system("ps -ho pid,state -p #{p1}")

(produces no output)

                static VALUEproc_detach(VALUE obj, VALUE pid){    return rb_detach_process(NUM2PIDT(pid));}
egid → integerclick to toggle source
Process::GID.eid → integer
Process::Sys.geteid → integer

Returns the effective group ID for this process. Not available on allplatforms.

Process.egid#=> 500
                static VALUEproc_getegid(VALUE obj){    rb_gid_t egid = getegid();    return GIDT2NUM(egid);}
egid = integer → integerclick to toggle source

Sets the effective group ID for this process. Not available on allplatforms.

                static VALUEproc_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 → integerclick to toggle source
Process::UID.eid → integer
Process::Sys.geteuid → integer

Returns the effective user ID for this process.

Process.euid#=> 501
                static VALUEproc_geteuid(VALUE obj){    rb_uid_t euid = geteuid();    return UIDT2NUM(euid);}
euid= userclick to toggle source

Sets the effective user ID for this process. Not available on allplatforms.

                static VALUEproc_seteuid_m(VALUE mod, VALUE euid){    check_uid_switch();    proc_seteuid(OBJ2UID(euid));    return euid;}
exec(*args)click to toggle source
                static VALUE f_exec(int c, const VALUE *a, VALUE _))
exit(*args)click to toggle source
                static VALUE f_exit(int c, const VALUE *a, VALUE _))
exit!(*args)click to toggle source
                static VALUE rb_f_exit_bang(int argc, VALUE *argv, VALUE obj))
fork [{ block }] → integer or nilclick to toggle source
fork [{ block }] → integer or nil

Creates a subprocess. If a block is specified, that block is run in thesubprocess, and the subprocess terminates with a status of zero. Otherwise,thefork call returns twice, once in the parent, returning theprocess ID of the child, and once in the child, returningnil. Thechild process can exit usingKernel#exit! to avoid running anyat_exit functions. The parent process should use::wait to collect the terminationstatuses of its children or use::detach to register disinterest intheir status; otherwise, the operating system may accumulate zombieprocesses.

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

If fork is not usable, Process.respond_to?(:fork) returns false.

Note that fork(2) is not available on some platforms like Windows andNetBSD 4. Therefore you should use spawn() instead of fork().

                static VALUErb_f_fork(VALUE obj){    rb_pid_t pid;    switch (pid = rb_fork_ruby(NULL)) {      case 0:        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 PIDT2NUM(pid);    }}
getpgid(pid) → integerclick to toggle source

Returns the process group ID for the given process id. Not available on allplatforms.

Process.getpgid(Process.ppid())#=> 25527
                static VALUEproc_getpgid(VALUE obj, VALUE pid){    rb_pid_t i;    i = getpgid(NUM2PIDT(pid));    if (i < 0) rb_sys_fail(0);    return PIDT2NUM(i);}
getpgrp → integerclick to toggle source

Returns the process group ID for this process. Not available on allplatforms.

Process.getpgid(0)#=> 25527Process.getpgrp#=> 25527
                static VALUEproc_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, integer) → integerclick to toggle source

Gets the scheduling priority for specified process, process group, or user.kind indicates the kind of entity to find: one ofProcess::PRIO_PGRP,Process::PRIO_USER, orProcess::PRIO_PROCESS.integer is an id indicating the particular process, process group,or user (an id of 0 meanscurrent). Lower priorities are morefavorable for scheduling. Not available on all platforms.

Process.getpriority(Process::PRIO_USER,0)#=> 19Process.getpriority(Process::PRIO_PROCESS,0)#=> 19
                static VALUEproc_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

Gets the resource limit of the process.cur_limit means current(soft) limit andmax_limit means maximum (hard) limit.

resource indicates the kind of resource to limit. It is specifiedas a symbol such as:CORE, a string such as"CORE" or a constant such asProcess::RLIMIT_CORE. See::setrlimit for details.

cur_limit andmax_limit may beProcess::RLIM_INFINITY,Process::RLIM_SAVED_MAX orProcess::RLIM_SAVED_CUR. See::setrlimit and the systemgetrlimit(2) manual for details.

                static VALUEproc_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() → integerclick to toggle source
getsid(pid) → integer

Returns the session ID for the given process id. If not given, returncurrent process sid. Not available on all platforms.

Process.getsid()#=> 27422Process.getsid(0)#=> 27422Process.getsid(Process.pid())#=> 27422
                static VALUEproc_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 → integerclick to toggle source
Process::GID.rid → integer
Process::Sys.getgid → integer

Returns the (real) group ID for this process.

Process.gid#=> 500
                static VALUEproc_getgid(VALUE obj){    rb_gid_t gid = getgid();    return GIDT2NUM(gid);}
gid= integer → integerclick to toggle source

Sets the group ID for this process.

                static VALUEproc_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 → arrayclick to toggle source

Get anArray of the group IDs in the supplementalgroup access list for this process.

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

Note that this method is just a wrapper of getgroups(2). This means thatthe following characteristics of the result completely depend on yoursystem:

  • the result is sorted

  • the result includes effective GIDs

  • the result does not include duplicated GIDs

You can make sure to get a sorted uniqueGIDlist of the current process by this expression:

Process.groups.uniq.sort
                static VALUEproc_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= array → arrayclick to toggle source

Set the supplemental group access list to the givenArray of group IDs.

Process.groups#=> [0, 1, 2, 3, 4, 6, 10, 11, 20, 26, 27]Process.groups = [27,6,10,11]#=> [27, 6, 10, 11]Process.groups#=> [27, 6, 10, 11]
                static VALUEproc_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) → arrayclick to toggle source

Initializes the supplemental group access list by reading the system groupdatabase and using all groups of which the given user is a member. Thegroup with the specifiedgid is also added to the list. Returnsthe resultingArray of the gids of all the groupsin the supplementary group access list. Not available on all platforms.

Process.groups#=> [0, 1, 2, 3, 4, 6, 10, 11, 20, 26, 27]Process.initgroups("mgranger",30 )#=> [30, 6, 10, 11]Process.groups#=> [30, 6, 10, 11]
                static VALUEproc_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, pid, ...) → integerclick to toggle source

Sends the given signal to the specified process id(s) ifpid ispositive. Ifpid is zero,signal is sent to all processeswhose group ID is equal to the group ID of the process. Ifpid isnegative, results are dependent on the operating system.signalmay be an integer signal number or a POSIX signal name (either with orwithout aSIG prefix). Ifsignal is negative (orstarts with a minus sign), kills process groups instead of processes. Notall signals are available on all platforms. The keys and values ofSignal.list are known signal names andnumbers, respectively.

pid =forkdoSignal.trap("HUP") {puts"Ouch!";exit }# ... do some work ...end# ...Process.kill("HUP",pid)Process.wait

produces:

Ouch!

Ifsignal is an integer but wrong for signal, Errno::EINVAL orRangeError will be raised. Otherwise unlesssignal is aString or aSymbol, and a known signal name,ArgumentError will be raised.

Also, Errno::ESRCH orRangeError for invalidpid, Errno::EPERM when failed because of no privilege, will beraised. In these cases, signals may have been sent to preceding processes.

                static VALUEproc_rb_f_kill(int c, const VALUE *v, VALUE _){    return rb_f_kill(c, v);}
last_status → Process::Status or nilclick to toggle source

Returns the status of the last executed child process in the currentthread.

Process.waitProcess.spawn("ruby","-e","exit 13")Process.last_status#=> #<Process::Status: pid 4825 exit 13>

If no child process has ever been executed in the current thread, thisreturnsnil.

Process.last_status#=> nil
                static VALUEproc_s_last_status(VALUE mod){    return rb_last_status_get();}
maxgroups → integerclick to toggle source

Returns the maximum number of gids allowed in the supplemental group accesslist.

Process.maxgroups#=> 32
                static VALUEproc_getmaxgroups(VALUE obj){    return INT2FIX(maxgroups());}
maxgroups= integer → integerclick to toggle source

Sets the maximum number of gids allowed in the supplemental group accesslist.

                static VALUEproc_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 → integerclick to toggle source

Returns the process id of this process. Not available on all platforms.

Process.pid#=> 27415
                static VALUEproc_get_pid(VALUE _){    return get_pid();}
ppid → integerclick to toggle source

Returns the process id of the parent of this process. Returns untrustworthyvalue on Win32/64. Not available on all platforms.

puts"I am #{Process.pid}"Process.fork {puts"Dad is #{Process.ppid}" }

produces:

Iam27417Dadis27417
                static VALUEproc_get_ppid(VALUE _){    return get_ppid();}
setpgid(pid, integer) → 0click to toggle source

Sets the process group ID ofpid (0 indicates this process) tointeger. Not available on all platforms.

                static VALUEproc_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 → 0click to toggle source

Equivalent tosetpgid(0,0). Not available on all platforms.

                static VALUEproc_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) → 0click to toggle source

See::getpriority.

Process.setpriority(Process::PRIO_USER,0,19)#=> 0Process.setpriority(Process::PRIO_PROCESS,0,19)#=> 0Process.getpriority(Process::PRIO_USER,0)#=> 19Process.getpriority(Process::PRIO_PROCESS,0)#=> 19
                static VALUEproc_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) → stringclick to toggle source

Sets the process title that appears on the ps(1) command. Not necessarilyeffective on all platforms. No exception will be raised regardless of theresult, nor willNotImplementedErrorbe 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 freemeans to change the process title.

                static VALUEproc_setproctitle(VALUE process, VALUE title){    return ruby_setproctitle(title);}
setrlimit(resource, cur_limit, max_limit) → nilclick to toggle source
setrlimit(resource, cur_limit) → nil

Sets the resource limit of the process.cur_limit means current(soft) limit andmax_limit means maximum (hard) limit.

Ifmax_limit is not given,cur_limit is used.

resource indicates the kind of resource to limit. It should be asymbol such as:CORE, a string such as"CORE" or a constant such asProcess::RLIMIT_CORE. The availableresources are OS dependent. Ruby may support following resources.

AS

total available memory (bytes) (SUSv3, NetBSD, FreeBSD, OpenBSD but4.4BSD-Lite)

CORE

core size (bytes) (SUSv3)

CPU

CPU time (seconds) (SUSv3)

DATA

data segment (bytes) (SUSv3)

FSIZE

file size (bytes) (SUSv3)

MEMLOCK

total size for mlock(2) (bytes) (4.4BSD, GNU/Linux)

MSGQUEUE

allocation for POSIX message queues (bytes) (GNU/Linux)

NICE

ceiling on process's nice(2) value (number) (GNU/Linux)

NOFILE

file descriptors (number) (SUSv3)

NPROC

number of processes for the user (number) (4.4BSD, GNU/Linux)

RSS

resident memory size (bytes) (4.2BSD, GNU/Linux)

RTPRIO

ceiling on the process's real-time priority (number) (GNU/Linux)

RTTIME

CPU time for real-time process (us) (GNU/Linux)

SBSIZE

all socket buffers (bytes) (NetBSD, FreeBSD)

SIGPENDING

number of queued signals allowed (signals) (GNU/Linux)

STACK

stack size (bytes) (SUSv3)

cur_limit andmax_limit may be:INFINITY,"INFINITY" orProcess::RLIM_INFINITY, which meansthat the resource is not limited. They may beProcess::RLIM_SAVED_MAX,Process::RLIM_SAVED_CUR andcorresponding symbols and strings too. See system setrlimit(2) manual fordetails.

The following example raises the soft limit of core size to the hard limitto try to make core dump possible.

Process.setrlimit(:CORE,Process.getrlimit(:CORE)[1])
                static VALUEproc_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 → integerclick to toggle source

Establishes this process as a new session and process group leader, with nocontrolling tty. Returns the session id. Not available on all platforms.

Process.setsid#=> 27422
                static VALUEproc_setsid(VALUE _){    rb_pid_t pid;    pid = setsid();    if (pid < 0) rb_sys_fail(0);    return PIDT2NUM(pid);}
spawn([env,] command... [,options]) → pidclick to toggle source
spawn([env,] command... [,options]) → pid

spawn executes specified command and return its pid.

pid =spawn("tar xf ruby-2.0.0-p195.tar.bz2")Process.waitpidpid =spawn(RbConfig.ruby,"-eputs'Hello, world!'")Process.waitpid

This method is similar toKernel#system but it doesn'twait for the command to finish.

The parent process should use::wait to collect the terminationstatus of its child or use::detach to register disinterest intheir status; otherwise, the operating system may accumulate zombieprocesses.

spawn has bunch of options to specify process attributes:

env: hash  name => val : set the environment variable  name => nil : unset the environment variable  the keys and the values except for +nil+ must be strings.command...:  commandline                 : command line string which is passed to the standard shell  cmdname, arg1, ...          : command name and one or more arguments (This form does not use the shell. See below for caveats.)  [cmdname, argv0], arg1, ... : command name, argv[0] and zero or more arguments (no shell)options: hash  clearing environment variables:    :unsetenv_others => true   : clear environment variables except specified by env    :unsetenv_others => false  : don't clear (default)  process group:    :pgroup => true or 0 : make a new process group    :pgroup => pgid      : join the specified process group    :pgroup => nil       : don't change the process group (default)  create new process group: Windows only    :new_pgroup => true  : the new process is the root process of a new process group    :new_pgroup => false : don't create a new process group (default)  resource limit: resourcename is core, cpu, data, etc.  See Process.setrlimit.    :rlimit_resourcename => limit    :rlimit_resourcename => [cur_limit, max_limit]  umask:    :umask => int  redirection:    key:      FD              : single file descriptor in child process      [FD, FD, ...]   : multiple file descriptor in child process    value:      FD                        : redirect to the file descriptor in parent process      string                    : redirect to file with open(string, "r" or "w")      [string]                  : redirect to file with open(string, File::RDONLY)      [string, open_mode]       : redirect to file with open(string, open_mode, 0644)      [string, open_mode, perm] : redirect to file with open(string, open_mode, perm)      [:child, FD]              : redirect to the redirected file descriptor      :close                    : close the file descriptor in child process    FD is one of follows      :in     : the file descriptor 0 which is the standard input      :out    : the file descriptor 1 which is the standard output      :err    : the file descriptor 2 which is the standard error      integer : the file descriptor of specified the integer      io      : the file descriptor specified as io.fileno  file descriptor inheritance: close non-redirected non-standard fds (3, 4, 5, ...) or not    :close_others => false  : inherit  current directory:    :chdir => str

Thecmdname, arg1, ... form does not use the shell. However,on different OSes, different things are provided as built-in commands. Anexample of this is +'echo'+, which is a built-in on Windows, but isa normal program on Linux and Mac OS X. This means thatProcess.spawn'echo', '%Path%' will display the contents of the%Path% environment variable on Windows, butProcess.spawn 'echo', '$PATH' prints theliteral$PATH.

If a hash is given asenv, the environment is updated byenv beforeexec(2) in the child process. If apair inenv has nil as the value, the variable is deleted.

# set FOO as BAR and unset BAZ.pid =spawn({"FOO"=>"BAR","BAZ"=>nil},command)

If a hash is given asoptions, it specifies process group,create new process group, resource limit, current directory, umask andredirects for the child process. Also, it can be specified to clearenvironment variables.

The:unsetenv_others key inoptions specifies toclear environment variables, other than specified byenv.

pid =spawn(command, :unsetenv_others=>true)# no environment variablepid =spawn({"FOO"=>"BAR"},command, :unsetenv_others=>true)# FOO only

The:pgroup key inoptions specifies a processgroup. The corresponding value should be true, zero, a positive integer, ornil. true and zero cause the process to be a process leader of a newprocess group. A non-zero positive integer causes the process to join theprovided process group. The default value, nil, causes the process toremain in the same process group.

pid =spawn(command, :pgroup=>true)# process leaderpid =spawn(command, :pgroup=>10)# belongs to the process group 10

The:new_pgroup key inoptions specifies to passCREATE_NEW_PROCESS_GROUP flag toCreateProcessW()that is Windows API. This option is only for Windows. true means the newprocess is the root process of the new process group. The new process hasCTRL+C disabled. This flag is necessary forProcess.kill(:SIGINT,pid) on the subprocess. :new_pgroup is false by default.

pid =spawn(command, :new_pgroup=>true)# new process grouppid =spawn(command, :new_pgroup=>false)# same process group

The:rlimit_foo key specifies a resource limit.foo should be one of resource types such ascore. Thecorresponding value should be an integer or an array which have one or twointegers: same as cur_limit and max_limit arguments for::setrlimit.

cur,max =Process.getrlimit(:CORE)pid =spawn(command, :rlimit_core=>[0,max])# disable core temporary.pid =spawn(command, :rlimit_core=>max)# enable core dumppid =spawn(command, :rlimit_core=>0)# never dump core.

The:umask key inoptions specifies the umask.

pid =spawn(command, :umask=>077)

The :in, :out, :err, an integer, anIO and an arraykey specifies a redirection. The redirection maps a file descriptor in thechild process.

For example, stderr can be merged into stdout as follows:

pid =spawn(command, :err=>:out)pid =spawn(command,2=>1)pid =spawn(command,STDERR=>:out)pid =spawn(command,STDERR=>STDOUT)

The hash keys specifies a file descriptor in the child process started byspawn. :err, 2 and STDERR specifies the standard error stream (stderr).

The hash values specifies a file descriptor in the parent process whichinvokes spawn. :out, 1 and STDOUT specifies the standard output stream(stdout).

In the above example, the standard output in the child process is notspecified. So it is inherited from the parent process.

The standard input stream (stdin) can be specified by :in, 0 and STDIN.

A filename can be specified as a hash value.

pid =spawn(command, :in=>"/dev/null")# read modepid =spawn(command, :out=>"/dev/null")# write modepid =spawn(command, :err=>"log")# write modepid =spawn(command, [:out, :err]=>"/dev/null")# write modepid =spawn(command,3=>"/dev/null")# read mode

For stdout and stderr (and combination of them), it is opened in writemode. Otherwise read mode is used.

For specifying flags and permission of file creation explicitly, an arrayis used instead.

pid =spawn(command, :in=>["file"])# read mode is assumedpid =spawn(command, :in=>["file","r"])pid =spawn(command, :out=>["log","w"])# 0644 assumedpid =spawn(command, :out=>["log","w",0600])pid =spawn(command, :out=>["log",File::WRONLY|File::EXCL|File::CREAT,0600])

The array specifies a filename, flags and permission. The flags can be astring or an integer. If the flags is omitted or nil, File::RDONLY isassumed. The permission should be an integer. If the permission is omittedor nil, 0644 is assumed.

If an array of IOs and integers are specified as a hash key, all theelements are redirected.

# stdout and stderr is redirected to log file.# The file "log" is opened just once.pid =spawn(command, [:out, :err]=>["log","w"])

Another way to merge multiple file descriptors is [:child, fd]. [:child,fd] means the file descriptor in the child process. This is different fromfd. For example, :err=>:out means redirecting child stderr to parentstdout. But :err=>[:child, :out] means redirecting child stderr to childstdout. They differ if stdout is redirected in the child process asfollows.

# stdout and stderr is redirected to log file.# The file "log" is opened just once.pid =spawn(command, :out=>["log","w"], :err=>[:child, :out])

[:child, :out] can be used to merge stderr into stdout inIO.popen. In this case,IO.popen redirects stdout to a pipe inthe child process and [:child, :out] refers the redirected stdout.

io =IO.popen(["sh","-c","echo out; echo err >&2", :err=>[:child, :out]])pio.read#=> "out\nerr\n"

The:chdir key inoptions specifies the currentdirectory.

pid =spawn(command, :chdir=>"/var/tmp")

spawn closes all non-standard unspecified descriptors by default. The“standard” descriptors are 0, 1 and 2. This behavior is specified by:close_others option. :close_others doesn't affect the standarddescriptors which are closed only if :close is specified explicitly.

pid =spawn(command, :close_others=>true)# close 3,4,5,... (default)pid =spawn(command, :close_others=>false)# don't close 3,4,5,...

:close_others is false by default for spawn andIO.popen.

Note that fds which close-on-exec flag is already set are closed regardlessof :close_others option.

SoIO.pipe and spawn can be used asIO.popen.

# similar to r = IO.popen(command)r,w =IO.pipepid =spawn(command, :out=>w)# r, w is closed in the child process.w.close

:close is specified as a hash value to close a fd individually.

f =open(foo)system(command,f=>:close)# don't inherit f.

If a file descriptor need to be inherited, io=>io can be used.

# valgrind has --log-fd option for log destination.# log_w=>log_w indicates log_w.fileno inherits to child process.log_r,log_w =IO.pipepid =spawn("valgrind","--log-fd=#{log_w.fileno}","echo","a",log_w=>log_w)log_w.closeplog_r.read

It is also possible to exchange file descriptors.

pid =spawn(command, :out=>:err, :err=>:out)

The hash keys specify file descriptors in the child process. The hashvalues specifies file descriptors in the parent process. So the abovespecifies exchanging stdout and stderr. Internally,spawn usesan extra file descriptor to resolve such cyclic file descriptor mapping.

SeeKernel#exec for the standardshell.

                static VALUErb_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 → aProcessTmsclick to toggle source

Returns aTms structure (see Process::Tms) that contains userand system CPU times for this process, and also for children processes.

t =Process.times[t.utime,t.stime,t.cutime,t.cstime ]#=> [0.0, 0.02, 0.00, 0.00]
                VALUErb_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 → integerclick to toggle source
Process::UID.rid → integer
Process::Sys.getuid → integer

Returns the (real) user ID of this process.

Process.uid#=> 501
                static VALUEproc_getuid(VALUE obj){    rb_uid_t uid = getuid();    return UIDT2NUM(uid);}
uid= user → numericclick to toggle source

Sets the (user) user ID for this process. Not available on all platforms.

                static VALUEproc_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() → integerclick to toggle source
wait(pid=-1, flags=0) → integer
waitpid(pid=-1, flags=0) → integer

Waits for a child process to exit, returns its process id, and sets$? to aProcess::Statusobject containing information on that process. Which child it waits ondepends on the value ofpid:

> 0

Waits for the child whose process ID equalspid.

0

Waits for any child whose process group ID equals that of the callingprocess.

-1

Waits for any child process (the default if nopid is given).

< -1

Waits for any child whose process group ID equals the absolute value ofpid.

Theflags argument may be a logical or of the flag valuesProcess::WNOHANG (do not block if no childavailable) orProcess::WUNTRACED(return stopped children that haven't been reported). Not all flags areavailable on all platforms, but a flag value of zero will work on allplatforms.

Calling this method raises aSystemCallError if there are no childprocesses. Not available on all platforms.

includeProcessfork {exit99 }#=> 27429wait#=> 27429$?.exitstatus#=> 99pid =fork {sleep3 }#=> 27440Time.now#=> 2008-03-08 19:56:16 +0900waitpid(pid,Process::WNOHANG)#=> nilTime.now#=> 2008-03-08 19:56:16 +0900waitpid(pid,0)#=> 27440Time.now#=> 2008-03-08 19:56:19 +0900
                static VALUEproc_m_wait(int c, VALUE *v, VALUE _){    return proc_wait(c, v);}
wait2(pid=-1, flags=0) → [pid, status]click to toggle source

Waits for a child process to exit (see::waitpid for exact semantics) andreturns an array containing the process id and the exit status (aProcess::Status object) of that child.Raises aSystemCallError if there are nochild processes.

Process.fork {exit99 }#=> 27437pid,status =Process.wait2pid#=> 27437status.exitstatus#=> 99
                static VALUEproc_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 → [ [pid1,status1], ...]click to toggle source

Waits for all children, returning an array ofpid/statuspairs (wherestatus is aProcess::Status object).

fork {sleep0.2;exit2 }#=> 27432fork {sleep0.1;exit1 }#=> 27433fork {exit0 }#=> 27434pProcess.waitall

produces:

[[30982, #<Process::Status: pid 30982 exit 0>], [30979, #<Process::Status: pid 30979 exit 1>], [30976, #<Process::Status: pid 30976 exit 2>]]
                static VALUEproc_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;}
waitpid(pid=-1, flags=0) → integerclick to toggle source

Waits for a child process to exit, returns its process id, and sets$? to aProcess::Statusobject containing information on that process. Which child it waits ondepends on the value ofpid:

> 0

Waits for the child whose process ID equalspid.

0

Waits for any child whose process group ID equals that of the callingprocess.

-1

Waits for any child process (the default if nopid is given).

< -1

Waits for any child whose process group ID equals the absolute value ofpid.

Theflags argument may be a logical or of the flag valuesProcess::WNOHANG (do not block if no childavailable) orProcess::WUNTRACED(return stopped children that haven't been reported). Not all flags areavailable on all platforms, but a flag value of zero will work on allplatforms.

Calling this method raises aSystemCallError if there are no childprocesses. Not available on all platforms.

includeProcessfork {exit99 }#=> 27429wait#=> 27429$?.exitstatus#=> 99pid =fork {sleep3 }#=> 27440Time.now#=> 2008-03-08 19:56:16 +0900waitpid(pid,Process::WNOHANG)#=> nilTime.now#=> 2008-03-08 19:56:16 +0900waitpid(pid,0)#=> 27440Time.now#=> 2008-03-08 19:56:19 +0900
                static VALUEproc_m_wait(int c, VALUE *v, VALUE _){    return proc_wait(c, v);}
waitpid2(pid=-1, flags=0) → [pid, status]click to toggle source

Waits for a child process to exit (see::waitpid for exact semantics) andreturns an array containing the process id and the exit status (aProcess::Status object) of that child.Raises aSystemCallError if there are nochild processes.

Process.fork {exit99 }#=> 27437pid,status =Process.wait2pid#=> 27437status.exitstatus#=> 99
                static VALUEproc_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());}

This page was generated for Ruby 3.0.0

Generated with Ruby-doc Rdoc Generator 0.42.0.


[8]ページ先頭

©2009-2025 Movatter.jp