Class: Process::Status

Inherits:
Object show all
Defined in:
process.c,
process.c

Overview

*******************************************************************

Process::Status encapsulates the information on the
status of a running or terminated system process. The built-in
variable <code>$?</code> is either +nil+ or a
Process::Status object.

   fork { exit 99 }   #=> 26557
   Process.wait       #=> 26557
   $?.class           #=> Process::Status
   $?.to_i            #=> 25344
   $? >> 8            #=> 99
   $?.stopped?        #=> false
   $?.exited?         #=> true
   $?.exitstatus      #=> 99

Posix systems record information on processes using a 16-bit
integer.  The lower bits record the process status (stopped,
exited, signaled) and the upper bits possibly contain additional
information (for example the program's return code in the case of
exited processes). Pre Ruby 1.8, these bits were exposed directly
to the Ruby program. Ruby now encapsulates these in a
Process::Status object. To maximize compatibility,
however, these objects retain a bit-oriented interface. In the
descriptions that follow, when we talk about the integer value of
_stat_, we're referring to this 16 bit value.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.Process::Status.wait(pid = -1, flags = 0) ⇒ Process::Status

Waits for a child process to exit and returns a Process::Status object containing information on that process. Which child it waits on depends on the value of pid:

> 0

Waits for the child whose process ID equals pid.

0

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

-1

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

< -1

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

The flags argument may be a logical or of the flag values Process::WNOHANG (do not block if no child available) or Process::WUNTRACED (return stopped children that haven't been reported). Not all flags are available on all platforms, but a flag value of zero will work on all platforms.

Returns nil if there are no child processes. Not available on all platforms.

May invoke the scheduler hook process_wait.

fork { exit 99 }                              #=> 27429
Process::Status.wait                          #=> pid 27429 exit 99
$?                                            #=> nil

pid = fork { sleep 3 }                        #=> 27440
Time.now                                      #=> 2008-03-08 19:56:16 +0900
Process::Status.wait(pid, Process::WNOHANG)   #=> nil
Time.now                                      #=> 2008-03-08 19:56:16 +0900
Process::Status.wait(pid, 0)                  #=> pid 27440 exit 99
Time.now                                      #=> 2008-03-08 19:56:19 +0900

This is an EXPERIMENTAL FEATURE.

Returns:


1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
# File 'process.c', line 1423

VALUE
rb_process_status_waitv(int argc, VALUE *argv, VALUE _)
{
    rb_check_arity(argc, 0, 2);

    rb_pid_t pid = -1;
    int flags = 0;

    if (argc >= 1) {
        pid = NUM2PIDT(argv[0]);
    }

    if (argc >= 2) {
        flags = RB_NUM2INT(argv[1]);
    }

    return rb_process_status_wait(pid, flags);
}

Instance Method Details

#&(num) ⇒ Integer

Logical AND of the bits in stat with num.

fork { exit 0x37 }
Process.wait
sprintf('%04x', $?.to_i)       #=> "3700"
sprintf('%04x', $? & 0x1e00)   #=> "1600"

Returns:


854
855
856
857
858
859
860
# File 'process.c', line 854

static VALUE
pst_bitand(VALUE st1, VALUE st2)
{
    int status = PST2INT(st1) & NUM2INT(st2);

    return INT2NUM(status);
}

#==(other) ⇒ Boolean

Returns true if the integer value of stat equals other.

Returns:

  • (Boolean)

834
835
836
837
838
839
# File 'process.c', line 834

static VALUE
pst_equal(VALUE st1, VALUE st2)
{
    if (st1 == st2) return Qtrue;
    return rb_equal(pst_to_i(st1), st2);
}

#>>(num) ⇒ Integer

Shift the bits in stat right num places.

fork { exit 99 }   #=> 26563
Process.wait       #=> 26563
$?.to_i            #=> 25344
$? >> 8            #=> 99

Returns:


875
876
877
878
879
880
881
# File 'process.c', line 875

static VALUE
pst_rshift(VALUE st1, VALUE st2)
{
    int status = PST2INT(st1) >> NUM2INT(st2);

    return INT2NUM(status);
}

#coredump?Boolean

Returns true if stat generated a coredump when it terminated. Not available on all platforms.

Returns:

  • (Boolean)

1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
# File 'process.c', line 1041

static VALUE
pst_wcoredump(VALUE st)
{
#ifdef WCOREDUMP
    int status = PST2INT(st);

    if (WCOREDUMP(status))
	return Qtrue;
    else
	return Qfalse;
#else
    return Qfalse;
#endif
}

#exited?Boolean

Returns true if stat exited normally (for example using an exit() call or finishing the program).

Returns:

  • (Boolean)

973
974
975
976
977
978
979
980
981
982
# File 'process.c', line 973

static VALUE
pst_wifexited(VALUE st)
{
    int status = PST2INT(st);

    if (WIFEXITED(status))
	return Qtrue;
    else
	return Qfalse;
}

#exitstatusInteger?

Returns the least significant eight bits of the return code of stat. Only available if #exited? is true.

fork { }           #=> 26572
Process.wait       #=> 26572
$?.exited?         #=> true
$?.exitstatus      #=> 0

fork { exit 99 }   #=> 26573
Process.wait       #=> 26573
$?.exited?         #=> true
$?.exitstatus      #=> 99

Returns:


1003
1004
1005
1006
1007
1008
1009
1010
1011
# File 'process.c', line 1003

static VALUE
pst_wexitstatus(VALUE st)
{
    int status = PST2INT(st);

    if (WIFEXITED(status))
	return INT2NUM(WEXITSTATUS(status));
    return Qnil;
}

#inspectString

Override the inspection method.

system("false")
p $?.inspect #=> "#<Process::Status: pid 12861 exit 1>"

Returns:


806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
# File 'process.c', line 806

static VALUE
pst_inspect(VALUE st)
{
    rb_pid_t pid;
    int status;
    VALUE str;

    pid = pst_pid(st);
    if (!pid) {
        return rb_sprintf("#<%s: uninitialized>", rb_class2name(CLASS_OF(st)));
    }
    status = PST2INT(st);

    str = rb_sprintf("#<%s: ", rb_class2name(CLASS_OF(st)));
    pst_message(str, pid, status);
    rb_str_cat2(str, ">");
    return str;
}

#pidInteger

Returns the process ID that this status object represents.

fork { exit }   #=> 26569
Process.wait    #=> 26569
$?.pid          #=> 26569

Returns:


717
718
719
720
721
722
# File 'process.c', line 717

static VALUE
pst_pid_m(VALUE self)
{
    rb_pid_t pid = pst_pid(self);
    return PIDT2NUM(pid);
}

#signaled?Boolean

Returns true if stat terminated because of an uncaught signal.

Returns:

  • (Boolean)

932
933
934
935
936
937
938
939
940
941
# File 'process.c', line 932

static VALUE
pst_wifsignaled(VALUE st)
{
    int status = PST2INT(st);

    if (WIFSIGNALED(status))
	return Qtrue;
    else
	return Qfalse;
}

#stopped?Boolean

Returns true if this process is stopped. This is only returned if the corresponding #wait call had the Process::WUNTRACED flag set.

Returns:

  • (Boolean)

893
894
895
896
897
898
899
900
901
902
# File 'process.c', line 893

static VALUE
pst_wifstopped(VALUE st)
{
    int status = PST2INT(st);

    if (WIFSTOPPED(status))
	return Qtrue;
    else
	return Qfalse;
}

#stopsigInteger?

Returns the number of the signal that caused stat to stop (or nil if self is not stopped).

Returns:


913
914
915
916
917
918
919
920
921
# File 'process.c', line 913

static VALUE
pst_wstopsig(VALUE st)
{
    int status = PST2INT(st);

    if (WIFSTOPPED(status))
	return INT2NUM(WSTOPSIG(status));
    return Qnil;
}

#success?true, ...

Returns true if stat is successful, false if not. Returns nil if #exited? is not true.

Returns:

  • (true, false, nil)

1022
1023
1024
1025
1026
1027
1028
1029
1030
# File 'process.c', line 1022

static VALUE
pst_success_p(VALUE st)
{
    int status = PST2INT(st);

    if (!WIFEXITED(status))
	return Qnil;
    return WEXITSTATUS(status) == EXIT_SUCCESS ? Qtrue : Qfalse;
}

#termsigInteger?

Returns the number of the signal that caused stat to terminate (or nil if self was not terminated by an uncaught signal).

Returns:


953
954
955
956
957
958
959
960
961
# File 'process.c', line 953

static VALUE
pst_wtermsig(VALUE st)
{
    int status = PST2INT(st);

    if (WIFSIGNALED(status))
	return INT2NUM(WTERMSIG(status));
    return Qnil;
}

#to_iInteger

Returns the bits in stat as an Integer. Poking around in these bits is platform dependent.

fork { exit 0xab }         #=> 26566
Process.wait               #=> 26566
sprintf('%04x', $?.to_i)   #=> "ab00"

Returns:


697
698
699
700
701
702
# File 'process.c', line 697

static VALUE
pst_to_i(VALUE self)
{
    int status = pst_status(self);
    return RB_INT2NUM(status);
}

#to_sString

Show pid and exit status as a string.

system("false")
p $?.to_s         #=> "pid 12766 exit 1"

Returns:


779
780
781
782
783
784
785
786
787
788
789
790
791
792
# File 'process.c', line 779

static VALUE
pst_to_s(VALUE st)
{
    rb_pid_t pid;
    int status;
    VALUE str;

    pid = pst_pid(st);
    status = PST2INT(st);

    str = rb_str_buf_new(0);
    pst_message(str, pid, status);
    return str;
}