/* * call-seq: * Enumerator.new(size = nil) { |yielder| ... } * Enumerator.new(obj, method = :each, *args) * * Creates a new Enumerator object, which can be used as an * Enumerable. * * In the first form, iteration is defined by the given block, in * which a "yielder" object, given as block parameter, can be used to * yield a value by calling the +yield+ method (aliased as +<<+): * * fib = Enumerator.new do |y| * a = b = 1 * loop do * y << a * a, b = b, a + b * end * end * * p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] * * The optional parameter can be used to specify how to calculate the size * in a lazy fashion (see Enumerator#size). It can either be a value or * a callable object. * * In the second, deprecated, form, a generated Enumerator iterates over the * given object using the given method with the given arguments passed. * * Use of this form is discouraged. Use Kernel#enum_for or Kernel#to_enum * instead. * * e = Enumerator.new(ObjectSpace, :each_object) * #-> ObjectSpace.enum_for(:each_object) * * e.select { |obj| obj.is_a?(Class) } #=> array of all classes * */ static VALUE enumerator_initialize(int argc, VALUE *argv, VALUE obj) { VALUE recv, meth = sym_each; VALUE size = Qnil; if (rb_block_given_p()) { rb_check_arity(argc, 0, 1); recv = generator_init(generator_allocate(rb_cGenerator), rb_block_proc()); if (argc) { if (NIL_P(argv[0]) || rb_obj_is_proc(argv[0]) || (RB_TYPE_P(argv[0], T_FLOAT) && RFLOAT_VALUE(argv[0]) == INFINITY)) { size = argv[0]; } else { size = rb_to_int(argv[0]); } argc = 0; } } else { rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS); rb_warn("Enumerator.new without a block is deprecated; use Object#to_enum"); recv = *argv++; if (--argc) { meth = *argv++; --argc; } } return enumerator_init(obj, recv, meth, argc, argv, 0, size); }
VALUE method_atomic_boolean_initialize(int argc, VALUE* argv, VALUE self) { VALUE value = Qfalse; rb_check_arity(argc, 0, 1); if (argc == 1) value = TRUTHY(argv[0]); DATA_PTR(self) = (void *) value; return(self); }
/* * call-seq: * WIN32OLE_VARIANT.new(val, vartype) #=> WIN32OLE_VARIANT object. * * Returns Ruby object wrapping OLE variant. * The first argument specifies Ruby object to convert OLE variant variable. * The second argument specifies VARIANT type. * In some situation, you need the WIN32OLE_VARIANT object to pass OLE method * * shell = WIN32OLE.new("Shell.Application") * folder = shell.NameSpace("C:\\Windows") * item = folder.ParseName("tmp.txt") * # You can't use Ruby String object to call FolderItem.InvokeVerb. * # Instead, you have to use WIN32OLE_VARIANT object to call the method. * shortcut = WIN32OLE_VARIANT.new("Create Shortcut(\&S)") * item.invokeVerb(shortcut) * */ static VALUE folevariant_initialize(VALUE self, VALUE args) { int len = 0; VARIANT var; VALUE val; VALUE vvt; VARTYPE vt; struct olevariantdata *pvar; len = RARRAY_LEN(args); rb_check_arity(len, 1, 3); VariantInit(&var); val = rb_ary_entry(args, 0); check_type_val2variant(val); TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); if (len == 1) { ole_val2variant(val, &(pvar->var)); } else { vvt = rb_ary_entry(args, 1); vt = RB_NUM2INT(vvt); if ((vt & VT_TYPEMASK) == VT_RECORD) { rb_raise(rb_eArgError, "not supported VT_RECORD WIN32OLE_VARIANT object"); } ole_val2olevariantdata(val, vt, pvar); } return self; }
/* * call-seq: * Signal.trap( signal, command ) -> obj * Signal.trap( signal ) {| | block } -> obj * * Specifies the handling of signals. The first parameter is a signal * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a * signal number. The characters ``SIG'' may be omitted from the * signal name. The command or block specifies code to be run when the * signal is raised. * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal * will be ignored. * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler * will be invoked. * If the command is ``EXIT'', the script will be terminated by the signal. * If the command is ``SYSTEM_DEFAULT'', the operating system's default * handler will be invoked. * Otherwise, the given command or block will be run. * The special signal name ``EXIT'' or signal number zero will be * invoked just prior to program termination. * trap returns the previous handler for the given signal. * * Signal.trap(0, proc { puts "Terminating: #{$$}" }) * Signal.trap("CLD") { puts "Child died" } * fork && Process.wait * * produces: * Terminating: 27461 * Child died * Terminating: 27460 */ static VALUE sig_trap(int argc, VALUE *argv) { int sig; sighandler_t func; VALUE cmd; rb_secure(2); rb_check_arity(argc, 1, 2); sig = trap_signm(argv[0]); if (reserved_signal_p(sig)) { const char *name = signo2signm(sig); if (name) rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name); else rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig); } if (argc == 1) { cmd = rb_block_proc(); func = sighandler; } else { cmd = argv[1]; func = trap_handler(&cmd, sig); } if (OBJ_TAINTED(cmd)) { rb_raise(rb_eSecurityError, "Insecure: tainted signal trap"); } return trap(sig, func, cmd); }
VALUE rb_obj_methods(int argc, VALUE *argv, VALUE obj) { rb_check_arity(argc, 0, 1); if (argc > 0 && !RTEST(argv[0])) { return rb_obj_singleton_methods(argc, argv, obj); } return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i); }
static VALUE lp_send(int argc, VALUE* argv, VALUE self) { VALUE obj; ID method_id; rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS); obj = lp_get_resolv(self); method_id = rb_to_id(*argv); return rb_funcall2(obj, method_id, --argc, ++argv); }
static int queue_pop_should_block(int argc, const VALUE *argv) { int should_block = 1; rb_check_arity(argc, 0, 1); if (argc > 0) { should_block = !RTEST(argv[0]); } return should_block; }
static int szqueue_push_should_block(int argc, const VALUE *argv) { int should_block = 1; rb_check_arity(argc, 1, 2); if (argc > 1) { should_block = !RTEST(argv[1]); } return should_block; }
VALUE method_atomic_fixnum_initialize(int argc, VALUE* argv, VALUE self) { VALUE value = LL2NUM(0); rb_check_arity(argc, 0, 1); if (argc == 1) { Check_Type(argv[0], T_FIXNUM); value = argv[0]; } DATA_PTR(self) = (void *) value; return(self); }
/* * call-seq: * io.winsize = [rows, columns] * * Tries to set console size. The effect depends on the platform and * the running environment. * * You must require 'io/console' to use this method. */ static VALUE console_set_winsize(VALUE io, VALUE size) { rb_io_t *fptr; rb_console_size_t ws; #if defined _WIN32 HANDLE wh; int newrow, newcol; #endif VALUE row, col, xpixel, ypixel; const VALUE *sz; int fd; GetOpenFile(io, fptr); size = rb_Array(size); rb_check_arity(RARRAY_LENINT(size), 2, 4); sz = RARRAY_CONST_PTR(size); row = sz[0], col = sz[1], xpixel = sz[2], ypixel = sz[3]; fd = GetWriteFD(fptr); #if defined TIOCSWINSZ ws.ws_row = ws.ws_col = ws.ws_xpixel = ws.ws_ypixel = 0; #define SET(m) ws.ws_##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m) SET(row); SET(col); SET(xpixel); SET(ypixel); #undef SET if (!setwinsize(fd, &ws)) rb_sys_fail(0); #elif defined _WIN32 wh = (HANDLE)rb_w32_get_osfhandle(fd); #define SET(m) new##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m) SET(row); SET(col); #undef SET if (!NIL_P(xpixel)) (void)NUM2UINT(xpixel); if (!NIL_P(ypixel)) (void)NUM2UINT(ypixel); if (!GetConsoleScreenBufferInfo(wh, &ws)) { rb_syserr_fail(LAST_ERROR, "GetConsoleScreenBufferInfo"); } if ((ws.dwSize.X < newcol && (ws.dwSize.X = newcol, 1)) || (ws.dwSize.Y < newrow && (ws.dwSize.Y = newrow, 1))) { if (!SetConsoleScreenBufferSize(wh, ws.dwSize)) { rb_syserr_fail(LAST_ERROR, "SetConsoleScreenBufferInfo"); } } ws.srWindow.Left = 0; ws.srWindow.Top = 0; ws.srWindow.Right = newcol; ws.srWindow.Bottom = newrow; if (!SetConsoleWindowInfo(wh, FALSE, &ws.srWindow)) { rb_syserr_fail(LAST_ERROR, "SetConsoleWindowInfo"); } #endif return io; }
/* * call-seq: * io.getpass(prompt=nil) -> string * * See IO#getpass. */ static VALUE io_getpass(int argc, VALUE *argv, VALUE io) { VALUE str; rb_check_arity(argc, 0, 1); prompt(argc, argv, io); str = str_chomp(rb_funcallv(io, id_gets, 0, 0)); puts_call(io); return str; }
static VALUE lp_initialize(int argc, VALUE* argv, VALUE self) { VALUE arg, blk; rb_check_arity(argc, 0, 1); arg = (argc == 1) ? *argv : Qnil; blk = rb_block_given_p() ? rb_block_proc() : Qnil; lp_set(self, arg, blk, NIL_P(arg) && !NIL_P(blk)); return self; }
/* * call-seq: * io.getpass(prompt=nil) -> string * * Reads and returns a line without echo back. * Prints +prompt+ unless it is +nil+. * * You must require 'io/console' to use this method. */ static VALUE console_getpass(int argc, VALUE *argv, VALUE io) { VALUE str, wio; rb_check_arity(argc, 0, 1); wio = rb_io_get_write_io(io); if (wio == io && io == rb_stdin) wio = rb_stderr; prompt(argc, argv, wio); str = rb_ensure(getpass_call, io, puts_call, wio); return str_chomp(str); }
/* * call-seq: * CGI.unescape(string, encoding=@@accept_charset) -> string * * Returns URL-unescaped string. * */ static VALUE cgiesc_unescape(int argc, VALUE *argv, VALUE self) { VALUE str = (rb_check_arity(argc, 1, 2), argv[0]); StringValue(str); if (rb_enc_str_asciicompat_p(str)) { VALUE enc = accept_charset(argc-1, argv+1, self); return optimized_unescape(str, enc); } else { return rb_call_super(argc, argv); } }
/* call-seq: * log(priority, format_string, *format_args) * * Log a message with the specified priority. Example: * * Syslog.log(Syslog::LOG_CRIT, "Out of disk space") * Syslog.log(Syslog::LOG_CRIT, "User %s logged in", ENV['USER']) * * The priority levels, in descending order, are: * * LOG_EMERG:: System is unusable * LOG_ALERT:: Action needs to be taken immediately * LOG_CRIT:: A critical condition has occurred * LOG_ERR:: An error occurred * LOG_WARNING:: Warning of a possible problem * LOG_NOTICE:: A normal but significant condition occurred * LOG_INFO:: Informational message * LOG_DEBUG:: Debugging information * * Each priority level also has a shortcut method that logs with it's named priority. * As an example, the two following statements would produce the same result: * * Syslog.log(Syslog::LOG_ALERT, "Out of memory") * Syslog.alert("Out of memory") * * Format strings are as for printf/sprintf, except that in addition %m is * replaced with the error message string that would be returned by * strerror(errno). * */ static VALUE mSyslog_log(int argc, VALUE *argv, VALUE self) { VALUE pri; rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS); argc--; pri = *argv++; if (!FIXNUM_P(pri)) { rb_raise(rb_eTypeError, "type mismatch: %"PRIsVALUE" given", rb_obj_class(pri)); } syslog_write(FIX2INT(pri), argc, argv); return self; }
static VALUE esignal_init(int argc, VALUE *argv, VALUE self) { int argnum = 1; VALUE sig = Qnil; int signo; const char *signm; if (argc > 0) { sig = rb_check_to_integer(argv[0], "to_int"); if (!NIL_P(sig)) argnum = 2; else sig = argv[0]; } rb_check_arity(argc, 1, argnum); if (argnum == 2) { signo = NUM2INT(sig); if (signo < 0 || signo > NSIG) { rb_raise(rb_eArgError, "invalid signal number (%d)", signo); } if (argc > 1) { sig = argv[1]; } else { signm = signo2signm(signo); if (signm) { sig = rb_sprintf("SIG%s", signm); } else { sig = rb_sprintf("SIG%u", signo); } } } else { signm = SYMBOL_P(sig) ? rb_id2name(SYM2ID(sig)) : StringValuePtr(sig); if (strncmp(signm, "SIG", 3) == 0) signm += 3; signo = signm2signo(signm); if (!signo) { rb_raise(rb_eArgError, "unsupported name `SIG%s'", signm); } sig = rb_sprintf("SIG%s", signm); } rb_call_super(1, &sig); rb_iv_set(self, "signo", INT2NUM(signo)); return self; }
static VALUE esignal_init(int argc, VALUE *argv, VALUE self) { int argnum = 1; VALUE sig = Qnil; int signo; const char *signm; if (argc > 0) { sig = rb_check_to_integer(argv[0], "to_int"); if (!NIL_P(sig)) argnum = 2; else sig = argv[0]; } rb_check_arity(argc, 1, argnum); if (argnum == 2) { signo = NUM2INT(sig); if (signo < 0 || signo > NSIG) { rb_raise(rb_eArgError, "invalid signal number (%d)", signo); } if (argc > 1) { sig = argv[1]; } else { sig = rb_signo2signm(signo); } } else { int len = sizeof(signame_prefix); if (SYMBOL_P(sig)) sig = rb_sym2str(sig); else StringValue(sig); signm = RSTRING_PTR(sig); if (strncmp(signm, signame_prefix, len) == 0) { signm += len; len = 0; } signo = signm2signo(signm); if (!signo) { rb_raise(rb_eArgError, "unsupported name `%.*s%"PRIsVALUE"'", len, signame_prefix, sig); } sig = rb_sprintf("SIG%s", signm); } rb_call_super(1, &sig); rb_iv_set(self, "signo", INT2NUM(signo)); return self; }
static VALUE rb_struct_select(int argc, VALUE *argv, VALUE s) { VALUE result; long i; rb_check_arity(argc, 0, 0); RETURN_SIZED_ENUMERATOR(s, 0, 0, rb_struct_size); result = rb_ary_new(); for (i = 0; i < RSTRUCT_LEN(s); i++) { if (RTEST(rb_yield(RSTRUCT_PTR(s)[i]))) { rb_ary_push(result, RSTRUCT_PTR(s)[i]); } } return result; }
/* * call-seq: * Signal.trap( signal, command ) -> obj * Signal.trap( signal ) {| | block } -> obj * * Specifies the handling of signals. The first parameter is a signal * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a * signal number. The characters ``SIG'' may be omitted from the * signal name. The command or block specifies code to be run when the * signal is raised. * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal * will be ignored. * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler * will be invoked. * If the command is ``EXIT'', the script will be terminated by the signal. * If the command is ``SYSTEM_DEFAULT'', the operating system's default * handler will be invoked. * Otherwise, the given command or block will be run. * The special signal name ``EXIT'' or signal number zero will be * invoked just prior to program termination. * trap returns the previous handler for the given signal. * * Signal.trap(0, proc { puts "Terminating: #{$$}" }) * Signal.trap("CLD") { puts "Child died" } * fork && Process.wait * * produces: * Terminating: 27461 * Child died * Terminating: 27460 */ static VALUE sig_trap(int argc, VALUE *argv) { struct trap_arg arg; rb_secure(2); rb_check_arity(argc, 1, 2); arg.sig = trap_signm(argv[0]); if (reserved_signal_p(arg.sig)) { const char *name = signo2signm(arg.sig); if (name) rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name); else rb_raise(rb_eArgError, "can't trap reserved signal: %d", (int)arg.sig); } if (argc == 1) { arg.cmd = rb_block_proc(); arg.func = sighandler; } else { arg.cmd = argv[1]; arg.func = trap_handler(&arg.cmd, arg.sig); } if (OBJ_TAINTED(arg.cmd)) { rb_raise(rb_eSecurityError, "Insecure: tainted signal trap"); } #if USE_TRAP_MASK { sigset_t fullmask; /* disable interrupt */ sigfillset(&fullmask); pthread_sigmask(SIG_BLOCK, &fullmask, &arg.mask); return rb_ensure(trap, (VALUE)&arg, trap_ensure, (VALUE)&arg); } #else return trap(&arg); #endif }
/* * call-seq: * Lazy.new(obj, size=nil) { |yielder, *values| ... } * * Creates a new Lazy enumerator. When the enumerator is actually enumerated * (e.g. by calling #force), +obj+ will be enumerated and each value passed * to the given block. The block can yield values back using +yielder+. * For example, to create a method +filter_map+ in both lazy and * non-lazy fashions: * * module Enumerable * def filter_map(&block) * map(&block).compact * end * end * * class Enumerator::Lazy * def filter_map * Lazy.new(self) do |yielder, *values| * result = yield *values * yielder << result if result * end * end * end * * (1..Float::INFINITY).lazy.filter_map{|i| i*i if i.even?}.first(5) * # => [4, 16, 36, 64, 100] */ static VALUE lazy_initialize(int argc, VALUE *argv, VALUE self) { VALUE obj, size = Qnil; VALUE generator; rb_check_arity(argc, 1, 2); if (!rb_block_given_p()) { rb_raise(rb_eArgError, "tried to call lazy new without a block"); } obj = argv[0]; if (argc > 1) { size = argv[1]; } generator = generator_allocate(rb_cGenerator); rb_block_call(generator, id_initialize, 0, 0, lazy_init_block_i, obj); enumerator_init(self, generator, sym_each, 0, 0, 0, size); rb_ivar_set(self, id_receiver, obj); return self; }
/* * call-seq: * Enumerator.new { |yielder| ... } * Enumerator.new(obj, method = :each, *args) * * Creates a new Enumerator object, which can be used as an * Enumerable. * * In the first form, iteration is defined by the given block, in * which a "yielder" object, given as block parameter, can be used to * yield a value by calling the +yield+ method (aliased as +<<+): * * fib = Enumerator.new do |y| * a = b = 1 * loop do * y << a * a, b = b, a + b * end * end * * p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] * * The block form can be used to create a lazy enumeration that only processes * elements as-needed. The generic pattern for this is: * * Enumerator.new do |yielder| * source.each do |source_item| * # process source_item and append the yielder * end * end * * This can be used with infinite streams to support multiple chains: * * class Fib * def initialize(a = 1, b = 1) * @a, @b = a, b * end * * def each * a, b = @a, @b * yield a * while true * yield b * a, b = b, a+b * end * end * end * * def lazy_select enum * Enumerator.new do |y| * enum.each do |e| * y << e if yield e * end * end * end * * def lazy_map enum * Enumerator.new do |y| * enum.each do |e| * y << yield(e) * end * end * end * * even_fibs = lazy_select(Fibs.new) { |x| x % 2 == 0 } * string_fibs = lazy_map(even_fibs) { |x| "<#{x}>" } * string_fibs.each_with_index do |fib, i| * puts "#{i}: #{fib}" * break if i >= 3 * end * * This allows output even though the Fib produces an infinite sequence of * Fibonacci numbers: * * 0: <2> * 1: <8> * 2: <34> * 3: <144> * * In the second, deprecated, form, a generated Enumerator iterates over the * given object using the given method with the given arguments passed. * * Use of this form is discouraged. Use Kernel#enum_for or Kernel#to_enum * instead. * * e = Enumerator.new(ObjectSpace, :each_object) * #-> ObjectSpace.enum_for(:each_object) * * e.select { |obj| obj.is_a?(Class) } #=> array of all classes * */ static VALUE enumerator_initialize(int argc, VALUE *argv, VALUE obj) { VALUE recv, meth = sym_each; if (argc == 0) { if (!rb_block_given_p()) rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS); recv = generator_init(generator_allocate(rb_cGenerator), rb_block_proc()); } else { recv = *argv++; if (--argc) { meth = *argv++; --argc; } } return enumerator_init(obj, recv, meth, argc, argv); }
/* * call-seq: * WIN32OLE_TYPELIB.new(typelib [, version1, version2]) -> WIN32OLE_TYPELIB object * * Returns a new WIN32OLE_TYPELIB object. * * The first argument <i>typelib</i> specifies OLE type library name or GUID or * OLE library file. * The second argument is major version or version of the type library. * The third argument is minor version. * The second argument and third argument are optional. * If the first argument is type library name, then the second and third argument * are ignored. * * tlib1 = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library') * tlib2 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}') * tlib3 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1.3) * tlib4 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1, 3) * tlib5 = WIN32OLE_TYPELIB.new("C:\\WINNT\\SYSTEM32\\SHELL32.DLL") * puts tlib1.name # -> 'Microsoft Excel 9.0 Object Library' * puts tlib2.name # -> 'Microsoft Excel 9.0 Object Library' * puts tlib3.name # -> 'Microsoft Excel 9.0 Object Library' * puts tlib4.name # -> 'Microsoft Excel 9.0 Object Library' * puts tlib5.name # -> 'Microsoft Shell Controls And Automation' * */ static VALUE foletypelib_initialize(VALUE self, VALUE args) { VALUE found = Qfalse; VALUE typelib = Qnil; int len = 0; OLECHAR * pbuf; ITypeLib *pTypeLib; HRESULT hr = S_OK; len = RARRAY_LEN(args); rb_check_arity(len, 1, 3); typelib = rb_ary_entry(args, 0); SafeStringValue(typelib); found = oletypelib_search_registry(self, typelib); if (found == Qfalse) { found = oletypelib_search_registry2(self, args); } if (found == Qfalse) { pbuf = ole_vstr2wc(typelib); hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib); SysFreeString(pbuf); if (SUCCEEDED(hr)) { found = Qtrue; oletypelib_set_member(self, pTypeLib); } } if (found == Qfalse) { rb_raise(eWIN32OLERuntimeError, "not found type library `%s`", StringValuePtr(typelib)); } return self; }
static VALUE rb_struct_s_def(int argc, VALUE *argv, VALUE klass) { VALUE name, rest; long i; VALUE st; ID id; rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS); name = argv[0]; if (SYMBOL_P(name)) { name = Qnil; } else { --argc; ++argv; } rest = rb_ary_tmp_new(argc); for (i=0; i<argc; i++) { id = rb_to_id(argv[i]); RARRAY_ASET(rest, i, ID2SYM(id)); rb_ary_set_len(rest, i+1); } if (NIL_P(name)) { st = anonymous_struct(klass); } else { st = new_struct(name, klass); } setup_struct(st, rest); if (rb_block_given_p()) { rb_mod_module_eval(0, 0, st); } return st; }
VALUE rb_f_kill(int argc, const VALUE *argv) { #ifndef HAVE_KILLPG #define killpg(pg, sig) kill(-(pg), (sig)) #endif int negative = 0; int sig; int i; VALUE str; const char *s; rb_secure(2); rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS); switch (TYPE(argv[0])) { case T_FIXNUM: sig = FIX2INT(argv[0]); break; case T_SYMBOL: str = rb_sym2str(argv[0]); goto str_signal; case T_STRING: str = argv[0]; str_signal: s = RSTRING_PTR(str); if (s[0] == '-') { negative++; s++; } if (strncmp(signame_prefix, s, sizeof(signame_prefix)) == 0) s += 3; if ((sig = signm2signo(s)) == 0) { long ofs = s - RSTRING_PTR(str); if (ofs) str = rb_str_subseq(str, ofs, RSTRING_LEN(str)-ofs); rb_raise(rb_eArgError, "unsupported name `SIG%"PRIsVALUE"'", str); } if (negative) sig = -sig; break; default: str = rb_check_string_type(argv[0]); if (!NIL_P(str)) { goto str_signal; } rb_raise(rb_eArgError, "bad signal type %s", rb_obj_classname(argv[0])); break; } if (argc <= 1) return INT2FIX(0); if (sig < 0) { sig = -sig; for (i=1; i<argc; i++) { if (killpg(NUM2PIDT(argv[i]), sig) < 0) rb_sys_fail(0); } } else { const rb_pid_t self = (GET_THREAD() == GET_VM()->main_thread) ? getpid() : -1; int wakeup = 0; for (i=1; i<argc; i++) { rb_pid_t pid = NUM2PIDT(argv[i]); if ((sig != 0) && (self != -1) && (pid == self)) { int t; /* * When target pid is self, many caller assume signal will be * delivered immediately and synchronously. */ switch (sig) { case SIGSEGV: #ifdef SIGBUS case SIGBUS: #endif #ifdef SIGKILL case SIGKILL: #endif #ifdef SIGSTOP case SIGSTOP: #endif ruby_kill(pid, sig); break; default: t = signal_ignored(sig); if (t) { if (t < 0 && kill(pid, sig)) rb_sys_fail(0); break; } signal_enque(sig); wakeup = 1; } } else if (kill(pid, sig) < 0) { rb_sys_fail(0); } } if (wakeup) { rb_threadptr_check_signal(GET_VM()->main_thread); } } rb_thread_execute_interrupts(rb_thread_current()); return INT2FIX(i-1); }
/* * call-seq: * IO.console -> #<File:/dev/tty> * IO.console(sym, *args) * * Returns an File instance opened console. * * If +sym+ is given, it will be sent to the opened console with * +args+ and the result will be returned instead of the console IO * itself. * * You must require 'io/console' to use this method. */ static VALUE console_dev(int argc, VALUE *argv, VALUE klass) { VALUE con = 0; rb_io_t *fptr; VALUE sym = 0; rb_check_arity(argc, 0, UNLIMITED_ARGUMENTS); if (argc) { Check_Type(sym = argv[0], T_SYMBOL); } if (klass == rb_cIO) klass = rb_cFile; if (rb_const_defined(klass, id_console)) { con = rb_const_get(klass, id_console); if (!RB_TYPE_P(con, T_FILE) || (!(fptr = RFILE(con)->fptr) || GetReadFD(fptr) == -1)) { rb_const_remove(klass, id_console); con = 0; } } if (sym) { if (sym == ID2SYM(id_close) && argc == 1) { if (con) { rb_io_close(con); rb_const_remove(klass, id_console); con = 0; } return Qnil; } } if (!con) { VALUE args[2]; #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H || defined HAVE_SGTTY_H # define CONSOLE_DEVICE "/dev/tty" #elif defined _WIN32 # define CONSOLE_DEVICE "con$" # define CONSOLE_DEVICE_FOR_READING "conin$" # define CONSOLE_DEVICE_FOR_WRITING "conout$" #endif #ifndef CONSOLE_DEVICE_FOR_READING # define CONSOLE_DEVICE_FOR_READING CONSOLE_DEVICE #endif #ifdef CONSOLE_DEVICE_FOR_WRITING VALUE out; rb_io_t *ofptr; #endif int fd; #ifdef CONSOLE_DEVICE_FOR_WRITING fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0); if (fd < 0) return Qnil; rb_update_max_fd(fd); args[1] = INT2FIX(O_WRONLY); args[0] = INT2NUM(fd); out = rb_class_new_instance(2, args, klass); #endif fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0); if (fd < 0) { #ifdef CONSOLE_DEVICE_FOR_WRITING rb_io_close(out); #endif return Qnil; } rb_update_max_fd(fd); args[1] = INT2FIX(O_RDWR); args[0] = INT2NUM(fd); con = rb_class_new_instance(2, args, klass); GetOpenFile(con, fptr); fptr->pathv = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE)); #ifdef CONSOLE_DEVICE_FOR_WRITING GetOpenFile(out, ofptr); ofptr->pathv = fptr->pathv; fptr->tied_io_for_writing = out; ofptr->mode |= FMODE_SYNC; #endif fptr->mode |= FMODE_SYNC; rb_const_set(klass, id_console, con); } if (sym) { return rb_f_send(argc, argv, con); } return con; }
VALUE rb_f_kill(int argc, VALUE *argv) { #ifndef HAVE_KILLPG #define killpg(pg, sig) kill(-(pg), (sig)) #endif int negative = 0; int sig; int i; volatile VALUE str; const char *s; rb_secure(2); rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS); switch (TYPE(argv[0])) { case T_FIXNUM: sig = FIX2INT(argv[0]); break; case T_SYMBOL: s = rb_id2name(SYM2ID(argv[0])); if (!s) rb_raise(rb_eArgError, "bad signal"); goto str_signal; case T_STRING: s = RSTRING_PTR(argv[0]); str_signal: if (s[0] == '-') { negative++; s++; } if (strncmp("SIG", s, 3) == 0) s += 3; if ((sig = signm2signo(s)) == 0) rb_raise(rb_eArgError, "unsupported name `SIG%s'", s); if (negative) sig = -sig; break; default: str = rb_check_string_type(argv[0]); if (!NIL_P(str)) { s = RSTRING_PTR(str); goto str_signal; } rb_raise(rb_eArgError, "bad signal type %s", rb_obj_classname(argv[0])); break; } if (sig < 0) { sig = -sig; for (i=1; i<argc; i++) { if (killpg(NUM2PIDT(argv[i]), sig) < 0) rb_sys_fail(0); } } else { for (i=1; i<argc; i++) { if (kill(NUM2PIDT(argv[i]), sig) < 0) rb_sys_fail(0); } } return INT2FIX(i-1); }
static VALUE yield_block(int argc, VALUE *argv, VALUE self) { rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS); return rb_block_call(self, rb_to_id(argv[0]), argc-1, argv+1, rb_yield_block, 0); }
/* :nodoc: */ static VALUE enc_dump(int argc, VALUE *argv, VALUE self) { rb_check_arity(argc, 0, 1); return enc_name(self); }
VALUE method_mathematic_random_real(int argc, VALUE* argv, VALUE self) { rb_check_arity(argc, 0, 1); if (argc == 1) Check_Type_Numeric(argv[0]); long max = (argc == 2 ? NUM2DBL(argv[1]) : 1.0); return(DBL2NUM(alglib::randomreal() * max)); }
VALUE method_mathematic_random_integer(int argc, VALUE* argv, VALUE self) { rb_check_arity(argc, 0, 1); if (argc == 2) Check_Type(argv[0], T_FIXNUM); long max = (argc == 2 ? NUM2INT(argv[1]) : 10); return(INT2NUM(alglib::randominteger(NUM2INT(max)))); }