~ubuntu-branches/ubuntu/intrepid/ruby1.9/intrepid-updates

« back to all changes in this revision

Viewing changes to process.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-09-04 16:01:17 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20070904160117-i15zckg2nhxe9fyw
Tags: 1.9.0+20070830-2ubuntu1
* Sync from Debian; remaining changes:
  - Add -g to CFLAGS.
* Fixes build failure on ia64.
* Fixes build failure with gcc-4.2 on lpia.
* Robustify check for target_os, fixing build failure on lpia.
* Set Ubuntu maintainer address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
  process.c -
4
4
 
5
 
  $Author: nobu $
6
 
  $Date: 2007-03-20 09:12:51 +0900 (火, 20  3月 2007) $
 
5
  $Author: ko1 $
 
6
  $Date: 2007-08-28 01:48:14 +0900 (火, 28  8月 2007) $
7
7
  created at: Tue Aug 10 14:30:50 JST 1993
8
8
 
9
 
  Copyright (C) 1993-2003 Yukihiro Matsumoto
 
9
  Copyright (C) 1993-2007 Yukihiro Matsumoto
10
10
  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
11
11
  Copyright (C) 2000  Information-technology Promotion Agency, Japan
12
12
 
13
13
**********************************************************************/
14
14
 
15
 
#include "ruby.h"
16
 
#include "rubysig.h"
17
 
#include "yarvcore.h"
 
15
#include "ruby/ruby.h"
 
16
#include "ruby/signal.h"
 
17
#include "vm_core.h"
18
18
 
19
19
#include <stdio.h>
20
20
#include <errno.h>
50
50
#ifdef HAVE_SYS_RESOURCE_H
51
51
# include <sys/resource.h>
52
52
#endif
53
 
#include "st.h"
 
53
#include "ruby/st.h"
54
54
 
55
55
#ifdef __EMX__
56
56
#undef HAVE_GETPGRP
606
606
    arg.st = st;
607
607
    arg.flags = flags;
608
608
  retry:
609
 
    result = (rb_pid_t)rb_thread_blocking_region(rb_waitpid_blocking,
610
 
                                                 &arg, RB_UBF_DFL);
 
609
    result = (rb_pid_t)rb_thread_blocking_region(rb_waitpid_blocking, &arg,
 
610
                                                 RB_UBF_DFL, 0);
611
611
    if (result < 0) {
612
612
#if 0
613
613
        if (errno == EINTR) {
829
829
    if (pid_tbl) {
830
830
        st_foreach(pid_tbl, waitall_each, result);
831
831
    }
 
832
#else
 
833
    rb_last_status_clear();
 
834
#endif
832
835
 
833
836
    for (pid = -1;;) {
 
837
#ifdef NO_WAITPID
834
838
        pid = wait(&status);
 
839
#else
 
840
        pid = rb_waitpid(-1, &status, 0);
 
841
#endif
835
842
        if (pid == -1) {
836
843
            if (errno == ECHILD)
837
844
                break;
 
845
#ifdef NO_WAITPID
838
846
            if (errno == EINTR) {
839
847
                rb_thread_schedule();
840
848
                continue;
841
849
            }
 
850
#endif
842
851
            rb_sys_fail(0);
843
852
        }
 
853
#ifdef NO_WAITPID
844
854
        rb_last_status_set(status, pid);
845
 
        rb_ary_push(result, rb_assoc_new(PIDT2NUM(pid), rb_last_status_get()));
846
 
    }
847
 
#else
848
 
    rb_last_status_clear();
849
 
    for (pid = -1;;) {
850
 
        pid = rb_waitpid(-1, &status, 0);
851
 
        if (pid == -1) {
852
 
            if (errno == ECHILD)
853
 
                break;
854
 
            rb_sys_fail(0);
855
 
        }
856
 
        rb_ary_push(result, rb_assoc_new(PIDT2NUM(pid), rb_last_status_get()));
857
 
    }
858
855
#endif
 
856
        rb_ary_push(result, rb_assoc_new(PIDT2NUM(pid), rb_last_status_get()));
 
857
    }
859
858
    return result;
860
859
}
861
860
 
862
861
static VALUE
863
 
detach_process_watcher(int *pid_p)
 
862
detach_process_watcher(void *arg)
864
863
{
865
 
    rb_pid_t cpid;
 
864
    rb_pid_t cpid, pid = (rb_pid_t)arg;
866
865
    int status;
867
866
 
868
 
    for (;;) {
869
 
        cpid = rb_waitpid(*pid_p, &status, WNOHANG);
870
 
        if (cpid != 0) return rb_last_status_get();
871
 
        rb_thread_sleep(1);
 
867
    while ((cpid = rb_waitpid(pid, &status, 0)) == 0) {
 
868
        /* wait while alive */
872
869
    }
 
870
    return rb_last_status_get();
873
871
}
874
872
 
875
873
VALUE
876
874
rb_detach_process(rb_pid_t pid)
877
875
{
878
 
    return rb_thread_create(detach_process_watcher, (void*)&pid);
 
876
    return rb_thread_create(detach_process_watcher, (void*)pid);
879
877
}
880
878
 
881
879
 
891
889
 *  separate Ruby thread whose sole job is to reap the status of the
892
890
 *  process _pid_ when it terminates. Use <code>detach</code>
893
891
 *  only when you do not intent to explicitly wait for the child to
894
 
 *  terminate.  <code>detach</code> only checks the status
895
 
 *  periodically (currently once each second).
 
892
 *  terminate.
896
893
 *
897
894
 *  The waiting thread returns the exit status of the detached process
898
895
 *  when it terminates, so you can use <code>Thread#join</code> to
937
934
#endif
938
935
 
939
936
void rb_thread_stop_timer_thread(void);
 
937
void rb_thread_start_timer_thread(void);
 
938
void rb_thread_reset_timer_thread(void);
940
939
 
941
940
#define before_exec() \
942
941
  (rb_enable_interrupt(), rb_thread_stop_timer_thread())
1082
1081
    ss = ALLOCA_N(char, s-str+1);
1083
1082
    memcpy(ss, str, s-str);
1084
1083
    ss[s-str] = '\0';
1085
 
    if (*a++ = strtok(ss, " \t")) {
1086
 
        while (t = strtok(NULL, " \t")) {
 
1084
    if ((*a++ = strtok(ss, " \t")) != 0) {
 
1085
        while ((t = strtok(NULL, " \t")) != 0) {
1087
1086
            *a++ = t;
1088
1087
        }
1089
1088
        *a = NULL;
1293
1292
#ifndef FD_CLOEXEC
1294
1293
    preserving_errno({
1295
1294
        fprintf(stderr, "%s:%d: command not found: %s\n",
1296
 
                ruby_sourcefile, ruby_sourceline, prog);
 
1295
                rb_sourcefile(), rb_sourceline(), prog);
1297
1296
    });
1298
1297
#endif
1299
1298
    return -1;
1524
1523
    return Qnil;                /* not reached */
1525
1524
}
1526
1525
 
 
1526
void
 
1527
rb_exit(int status)
 
1528
{
 
1529
    if (GET_THREAD()->tag) {
 
1530
        VALUE args[2];
 
1531
 
 
1532
        args[0] = INT2NUM(status);
 
1533
        args[1] = rb_str_new2("exit");
 
1534
        rb_exc_raise(rb_class_new_instance(2, args, rb_eSystemExit));
 
1535
    }
 
1536
    ruby_finalize();
 
1537
    exit(status);
 
1538
}
 
1539
 
 
1540
 
 
1541
/*
 
1542
 *  call-seq:
 
1543
 *     exit(integer=0)
 
1544
 *     Kernel::exit(integer=0)
 
1545
 *     Process::exit(integer=0)
 
1546
 *  
 
1547
 *  Initiates the termination of the Ruby script by raising the
 
1548
 *  <code>SystemExit</code> exception. This exception may be caught. The
 
1549
 *  optional parameter is used to return a status code to the invoking
 
1550
 *  environment.
 
1551
 *     
 
1552
 *     begin
 
1553
 *       exit
 
1554
 *       puts "never get here"
 
1555
 *     rescue SystemExit
 
1556
 *       puts "rescued a SystemExit exception"
 
1557
 *     end
 
1558
 *     puts "after begin block"
 
1559
 *     
 
1560
 *  <em>produces:</em>
 
1561
 *     
 
1562
 *     rescued a SystemExit exception
 
1563
 *     after begin block
 
1564
 *     
 
1565
 *  Just prior to termination, Ruby executes any <code>at_exit</code> functions
 
1566
 *  (see Kernel::at_exit) and runs any object finalizers (see
 
1567
 *  ObjectSpace::define_finalizer).
 
1568
 *     
 
1569
 *     at_exit { puts "at_exit function" }
 
1570
 *     ObjectSpace.define_finalizer("string",  proc { puts "in finalizer" })
 
1571
 *     exit
 
1572
 *     
 
1573
 *  <em>produces:</em>
 
1574
 *     
 
1575
 *     at_exit function
 
1576
 *     in finalizer
 
1577
 */
 
1578
 
 
1579
VALUE
 
1580
rb_f_exit(int argc, VALUE *argv)
 
1581
{
 
1582
    VALUE status;
 
1583
    int istatus;
 
1584
 
 
1585
    rb_secure(4);
 
1586
    if (rb_scan_args(argc, argv, "01", &status) == 1) {
 
1587
        switch (status) {
 
1588
          case Qtrue:
 
1589
            istatus = EXIT_SUCCESS;
 
1590
            break;
 
1591
          case Qfalse:
 
1592
            istatus = EXIT_FAILURE;
 
1593
            break;
 
1594
          default:
 
1595
            istatus = NUM2INT(status);
 
1596
#if EXIT_SUCCESS != 0
 
1597
            if (istatus == 0)
 
1598
                istatus = EXIT_SUCCESS;
 
1599
#endif
 
1600
            break;
 
1601
        }
 
1602
    }
 
1603
    else {
 
1604
        istatus = EXIT_SUCCESS;
 
1605
    }
 
1606
    rb_exit(istatus);
 
1607
    return Qnil;                /* not reached */
 
1608
}
 
1609
 
 
1610
 
 
1611
/*
 
1612
 *  call-seq:
 
1613
 *     abort
 
1614
 *     Kernel::abort
 
1615
 *     Process::abort
 
1616
 *  
 
1617
 *  Terminate execution immediately, effectively by calling
 
1618
 *  <code>Kernel.exit(1)</code>. If _msg_ is given, it is written
 
1619
 *  to STDERR prior to terminating.
 
1620
 */
 
1621
 
 
1622
VALUE
 
1623
rb_f_abort(int argc, VALUE *argv)
 
1624
{
 
1625
    extern void ruby_error_print(void);
 
1626
 
 
1627
    rb_secure(4);
 
1628
    if (argc == 0) {
 
1629
        if (!NIL_P(GET_THREAD()->errinfo)) {
 
1630
            ruby_error_print();
 
1631
        }
 
1632
        rb_exit(EXIT_FAILURE);
 
1633
    }
 
1634
    else {
 
1635
        VALUE args[2];
 
1636
 
 
1637
        rb_scan_args(argc, argv, "1", &args[1]);
 
1638
        StringValue(argv[0]);
 
1639
        rb_io_puts(argc, argv, rb_stderr);
 
1640
        args[0] = INT2NUM(EXIT_FAILURE);
 
1641
        rb_exc_raise(rb_class_new_instance(2, args, rb_eSystemExit));
 
1642
    }
 
1643
    return Qnil;                /* not reached */
 
1644
}
 
1645
 
 
1646
 
1527
1647
#if defined(sun)
1528
1648
#define signal(a,b) sigset(a,b)
1529
1649
#endif
2672
2792
 
2673
2793
    ary = rb_ary_new();
2674
2794
    for (i = 0; i < ngroups; i++)
2675
 
        rb_ary_push(ary, INT2NUM(groups[i]));
 
2795
        rb_ary_push(ary, GIDT2NUM(groups[i]));
2676
2796
 
2677
2797
    return ary;
2678
2798
#else
3065
3185
proc_geteuid(VALUE obj)
3066
3186
{
3067
3187
    rb_uid_t euid = geteuid();
3068
 
    return NUM2UIDT(euid);
 
3188
    return UIDT2NUM(euid);
3069
3189
}
3070
3190
 
3071
3191
 
3669
3789
    rb_define_global_function("system", rb_f_system, -1);
3670
3790
    rb_define_global_function("spawn", rb_f_spawn, -1);
3671
3791
    rb_define_global_function("sleep", rb_f_sleep, -1);
 
3792
    rb_define_global_function("exit", rb_f_exit, -1);
 
3793
    rb_define_global_function("abort", rb_f_abort, -1);
3672
3794
 
3673
3795
    rb_mProcess = rb_define_module("Process");
3674
3796
 
3689
3811
    rb_define_singleton_method(rb_mProcess, "fork", rb_f_fork, 0);
3690
3812
    rb_define_singleton_method(rb_mProcess, "spawn", rb_f_spawn, -1);
3691
3813
    rb_define_singleton_method(rb_mProcess, "exit!", rb_f_exit_bang, -1);
3692
 
    rb_define_singleton_method(rb_mProcess, "exit", rb_f_exit, -1);   /* in eval.c */
3693
 
    rb_define_singleton_method(rb_mProcess, "abort", rb_f_abort, -1); /* in eval.c */
 
3814
    rb_define_singleton_method(rb_mProcess, "exit", rb_f_exit, -1);
 
3815
    rb_define_singleton_method(rb_mProcess, "abort", rb_f_abort, -1);
3694
3816
 
3695
3817
    rb_define_module_function(rb_mProcess, "kill", rb_f_kill, -1); /* in signal.c */
3696
3818
    rb_define_module_function(rb_mProcess, "wait", proc_wait, -1);
3824
3946
    rb_define_module_function(rb_mProcGID, "change_privilege", p_gid_change_privilege, 1);
3825
3947
    rb_define_module_function(rb_mProcUID, "grant_privilege", p_uid_grant_privilege, 1);
3826
3948
    rb_define_module_function(rb_mProcGID, "grant_privilege", p_gid_grant_privilege, 1);
3827
 
    rb_define_alias(rb_mProcUID, "eid=", "grant_privilege");
3828
 
    rb_define_alias(rb_mProcGID, "eid=", "grant_privilege");
 
3949
    rb_define_alias(rb_singleton_class(rb_mProcUID), "eid=", "grant_privilege");
 
3950
    rb_define_alias(rb_singleton_class(rb_mProcGID), "eid=", "grant_privilege");
3829
3951
    rb_define_module_function(rb_mProcUID, "re_exchange", p_uid_exchange, 0);
3830
3952
    rb_define_module_function(rb_mProcGID, "re_exchange", p_gid_exchange, 0);
3831
3953
    rb_define_module_function(rb_mProcUID, "re_exchangeable?", p_uid_exchangeable, 0);