static int ossl_pkcs7_sym2typeid(VALUE sym) { int i, ret = Qnil; const char *s; size_t l; static const struct { char name[20]; int nid; } p7_type_tab[] = { { "signed", NID_pkcs7_signed }, { "data", NID_pkcs7_data }, { "signedAndEnveloped", NID_pkcs7_signedAndEnveloped }, { "enveloped", NID_pkcs7_enveloped }, { "encrypted", NID_pkcs7_encrypted }, { "digest", NID_pkcs7_digest }, }; if (RB_TYPE_P(sym, T_SYMBOL)) sym = rb_sym2str(sym); else StringValue(sym); RSTRING_GETMEM(sym, s, l); for(i = 0; ; i++){ if(i == numberof(p7_type_tab)) ossl_raise(ePKCS7Error, "unknown type \"%s\"", s); if(strlen(p7_type_tab[i].name) != l) continue; if(strcmp(p7_type_tab[i].name, s) == 0){ ret = p7_type_tab[i].nid; break; } } return ret; }
static int trap_signm(VALUE vsig) { int sig = -1; const char *s; switch (TYPE(vsig)) { case T_FIXNUM: sig = FIX2INT(vsig); if (sig < 0 || sig >= NSIG) { rb_raise(rb_eArgError, "invalid signal number (%d)", sig); } break; case T_SYMBOL: vsig = rb_sym2str(vsig); s = RSTRING_PTR(vsig); goto str_signal; default: s = StringValuePtr(vsig); str_signal: if (strncmp(signame_prefix, s, sizeof(signame_prefix)) == 0) s += 3; sig = signm2signo(s); if (sig == 0 && strcmp(s, "EXIT") != 0) { long ofs = s - RSTRING_PTR(vsig); if (ofs) vsig = rb_str_subseq(vsig, ofs, RSTRING_LEN(vsig)-ofs); rb_raise(rb_eArgError, "unsupported signal SIG%"PRIsVALUE"", vsig); } } return sig; }
int rb_enc_get_index(VALUE obj) { int i = -1; VALUE tmp; if (SPECIAL_CONST_P(obj)) { if (!SYMBOL_P(obj)) return -1; obj = rb_sym2str(obj); } switch (BUILTIN_TYPE(obj)) { case T_STRING: case T_SYMBOL: case T_REGEXP: i = enc_get_index_str(obj); break; case T_FILE: tmp = rb_funcallv(obj, rb_intern("internal_encoding"), 0, 0); if (NIL_P(tmp)) { tmp = rb_funcallv(obj, rb_intern("external_encoding"), 0, 0); } if (is_obj_encoding(tmp)) { i = enc_check_encoding(tmp); } break; case T_DATA: if (is_data_encoding(obj)) { i = enc_check_encoding(obj); } break; default: break; } return i; }
static void ctx_push_ruby_object(struct state *state, VALUE obj) { duk_context *ctx = state->ctx; duk_idx_t arr_idx; VALUE str; switch (TYPE(obj)) { case T_FIXNUM: duk_push_int(ctx, NUM2INT(obj)); return; case T_FLOAT: duk_push_number(ctx, NUM2DBL(obj)); return; case T_SYMBOL: #ifdef HAVE_RB_SYM2STR obj = rb_sym2str(obj); #else obj = rb_id2str(SYM2ID(obj)); #endif // Intentional fall-through: case T_STRING: str = encode_cesu8(state, obj); duk_push_lstring(ctx, RSTRING_PTR(str), RSTRING_LEN(str)); return; case T_TRUE: duk_push_true(ctx); return; case T_FALSE: duk_push_false(ctx); return; case T_NIL: duk_push_null(ctx); return; case T_ARRAY: arr_idx = duk_push_array(ctx); for (int idx = 0; idx < RARRAY_LEN(obj); idx++) { ctx_push_ruby_object(state, rb_ary_entry(obj, idx)); duk_put_prop_index(ctx, arr_idx, idx); } return; case T_HASH: duk_push_object(ctx); rb_hash_foreach(obj, ctx_push_hash_element, (VALUE)state); return; default: // Cannot convert break; } clean_raise(ctx, rb_eTypeError, "cannot convert %s", rb_obj_classname(obj)); }
static VALUE console_key_pressed_p(VALUE io, VALUE k) { int vk = -1; if (FIXNUM_P(k)) { vk = NUM2UINT(k); } else { const struct vktable *t; const char *kn; if (SYMBOL_P(k)) { k = rb_sym2str(k); kn = RSTRING_PTR(k); } else { kn = StringValuePtr(k); } t = console_win32_vk(kn, RSTRING_LEN(k)); if (!t || (vk = (short)t->vk) == -1) { rb_raise(rb_eArgError, "unknown virtual key code: % "PRIsVALUE, k); } } return GetKeyState(vk) & 0x80 ? Qtrue : Qfalse; }
/* See Object#inspect. */ static VALUE iow_inspect(VALUE self) { VALUE obj = (VALUE)DATA_PTR(self); VALUE type = type2sym(BUILTIN_TYPE(obj)); return rb_sprintf("#<InternalObject:%p %"PRIsVALUE">", (void *)obj, rb_sym2str(type)); }
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; }
VALUE rb_str_format(int argc, const VALUE *argv, VALUE fmt) { enum {default_float_precision = 6}; rb_encoding *enc; const char *p, *end; char *buf; long blen, bsiz; VALUE result; long scanned = 0; int coderange = ENC_CODERANGE_7BIT; int width, prec, flags = FNONE; int nextarg = 1; int posarg = 0; int tainted = 0; VALUE nextvalue; VALUE tmp; VALUE str; volatile VALUE hash = Qundef; #define CHECK_FOR_WIDTH(f) \ if ((f) & FWIDTH) { \ rb_raise(rb_eArgError, "width given twice"); \ } \ if ((f) & FPREC0) { \ rb_raise(rb_eArgError, "width after precision"); \ } #define CHECK_FOR_FLAGS(f) \ if ((f) & FWIDTH) { \ rb_raise(rb_eArgError, "flag after width"); \ } \ if ((f) & FPREC0) { \ rb_raise(rb_eArgError, "flag after precision"); \ } ++argc; --argv; if (OBJ_TAINTED(fmt)) tainted = 1; StringValue(fmt); enc = rb_enc_get(fmt); fmt = rb_str_new4(fmt); p = RSTRING_PTR(fmt); end = p + RSTRING_LEN(fmt); blen = 0; bsiz = 120; result = rb_str_buf_new(bsiz); rb_enc_copy(result, fmt); buf = RSTRING_PTR(result); memset(buf, 0, bsiz); ENC_CODERANGE_SET(result, coderange); for (; p < end; p++) { const char *t; int n; VALUE sym = Qnil; for (t = p; t < end && *t != '%'; t++) ; PUSH(p, t - p); if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) { scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &coderange); ENC_CODERANGE_SET(result, coderange); } if (t >= end) { /* end of fmt string */ goto sprint_exit; } p = t + 1; /* skip `%' */ width = prec = -1; nextvalue = Qundef; retry: switch (*p) { default: if (rb_enc_isprint(*p, enc)) rb_raise(rb_eArgError, "malformed format string - %%%c", *p); else rb_raise(rb_eArgError, "malformed format string"); break; case ' ': CHECK_FOR_FLAGS(flags); flags |= FSPACE; p++; goto retry; case '#': CHECK_FOR_FLAGS(flags); flags |= FSHARP; p++; goto retry; case '+': CHECK_FOR_FLAGS(flags); flags |= FPLUS; p++; goto retry; case '-': CHECK_FOR_FLAGS(flags); flags |= FMINUS; p++; goto retry; case '0': CHECK_FOR_FLAGS(flags); flags |= FZERO; p++; goto retry; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = 0; GETNUM(n, width); if (*p == '$') { if (nextvalue != Qundef) { rb_raise(rb_eArgError, "value given twice - %d$", n); } nextvalue = GETPOSARG(n); p++; goto retry; } CHECK_FOR_WIDTH(flags); width = n; flags |= FWIDTH; goto retry; case '<': case '{': { const char *start = p; char term = (*p == '<') ? '>' : '}'; int len; for (; p < end && *p != term; ) { p += rb_enc_mbclen(p, end, enc); } if (p >= end) { rb_raise(rb_eArgError, "malformed name - unmatched parenthesis"); } #if SIZEOF_INT < SIZEOF_SIZE_T if ((size_t)(p - start) >= INT_MAX) { const int message_limit = 20; len = (int)(rb_enc_right_char_head(start, start + message_limit, p, enc) - start); rb_enc_raise(enc, rb_eArgError, "too long name (%"PRIdSIZE" bytes) - %.*s...%c", (size_t)(p - start - 2), len, start, term); } #endif len = (int)(p - start + 1); /* including parenthesis */ if (sym != Qnil) { rb_enc_raise(enc, rb_eArgError, "named%.*s after <%"PRIsVALUE">", len, start, rb_sym2str(sym)); } CHECKNAMEARG(start, len, enc); get_hash(&hash, argc, argv); sym = rb_check_symbol_cstr(start + 1, len - 2 /* without parenthesis */, enc); if (sym != Qnil) nextvalue = rb_hash_lookup2(hash, sym, Qundef); if (nextvalue == Qundef) { rb_enc_raise(enc, rb_eKeyError, "key%.*s not found", len, start); } if (term == '}') goto format_s; p++; goto retry; } case '*': CHECK_FOR_WIDTH(flags); flags |= FWIDTH; GETASTER(width); if (width < 0) { flags |= FMINUS; width = -width; } p++; goto retry; case '.': if (flags & FPREC0) { rb_raise(rb_eArgError, "precision given twice"); } flags |= FPREC|FPREC0; prec = 0; p++; if (*p == '*') { GETASTER(prec); if (prec < 0) { /* ignore negative precision */ flags &= ~FPREC; } p++; goto retry; } GETNUM(prec, precision); goto retry; case '\n': case '\0': p--; case '%': if (flags != FNONE) { rb_raise(rb_eArgError, "invalid format character - %%"); } PUSH("%", 1); break; case 'c': { VALUE val = GETARG(); VALUE tmp; unsigned int c; int n; tmp = rb_check_string_type(val); if (!NIL_P(tmp)) { if (rb_enc_strlen(RSTRING_PTR(tmp),RSTRING_END(tmp),enc) != 1) { rb_raise(rb_eArgError, "%%c requires a character"); } c = rb_enc_codepoint_len(RSTRING_PTR(tmp), RSTRING_END(tmp), &n, enc); RB_GC_GUARD(tmp); } else { c = NUM2INT(val); n = rb_enc_codelen(c, enc); } if (n <= 0) { rb_raise(rb_eArgError, "invalid character"); } if (!(flags & FWIDTH)) { CHECK(n); rb_enc_mbcput(c, &buf[blen], enc); blen += n; } else if ((flags & FMINUS)) { CHECK(n); rb_enc_mbcput(c, &buf[blen], enc); blen += n; FILL(' ', width-1); } else { FILL(' ', width-1); CHECK(n); rb_enc_mbcput(c, &buf[blen], enc); blen += n; } } break; case 's': case 'p': format_s: { VALUE arg = GETARG(); long len, slen; if (*p == 'p') arg = rb_inspect(arg); str = rb_obj_as_string(arg); if (OBJ_TAINTED(str)) tainted = 1; len = RSTRING_LEN(str); rb_str_set_len(result, blen); if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) { int cr = coderange; scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &cr); ENC_CODERANGE_SET(result, (cr == ENC_CODERANGE_UNKNOWN ? ENC_CODERANGE_BROKEN : (coderange = cr))); } enc = rb_enc_check(result, str); if (flags&(FPREC|FWIDTH)) { slen = rb_enc_strlen(RSTRING_PTR(str),RSTRING_END(str),enc); if (slen < 0) { rb_raise(rb_eArgError, "invalid mbstring sequence"); } if ((flags&FPREC) && (prec < slen)) { char *p = rb_enc_nth(RSTRING_PTR(str), RSTRING_END(str), prec, enc); slen = prec; len = p - RSTRING_PTR(str); } /* need to adjust multi-byte string pos */ if ((flags&FWIDTH) && (width > slen)) { width -= (int)slen; if (!(flags&FMINUS)) { CHECK(width); while (width--) { buf[blen++] = ' '; } } CHECK(len); memcpy(&buf[blen], RSTRING_PTR(str), len); RB_GC_GUARD(str); blen += len; if (flags&FMINUS) { CHECK(width); while (width--) { buf[blen++] = ' '; } } rb_enc_associate(result, enc); break; } } PUSH(RSTRING_PTR(str), len); RB_GC_GUARD(str); rb_enc_associate(result, enc); } break; case 'd': case 'i': case 'o': case 'x': case 'X': case 'b': case 'B': case 'u': { volatile VALUE val = GETARG(); int valsign; char nbuf[64], *s; const char *prefix = 0; int sign = 0, dots = 0; char sc = 0; long v = 0; int base, bignum = 0; int len; switch (*p) { case 'd': case 'i': case 'u': sign = 1; break; case 'o': case 'x': case 'X': case 'b': case 'B': if (flags&(FPLUS|FSPACE)) sign = 1; break; } if (flags & FSHARP) { switch (*p) { case 'o': prefix = "0"; break; case 'x': prefix = "0x"; break; case 'X': prefix = "0X"; break; case 'b': prefix = "0b"; break; case 'B': prefix = "0B"; break; } } bin_retry: switch (TYPE(val)) { case T_FLOAT: if (FIXABLE(RFLOAT_VALUE(val))) { val = LONG2FIX((long)RFLOAT_VALUE(val)); goto bin_retry; } val = rb_dbl2big(RFLOAT_VALUE(val)); if (FIXNUM_P(val)) goto bin_retry; bignum = 1; break; case T_STRING: val = rb_str_to_inum(val, 0, TRUE); goto bin_retry; case T_BIGNUM: bignum = 1; break; case T_FIXNUM: v = FIX2LONG(val); break; default: val = rb_Integer(val); goto bin_retry; } switch (*p) { case 'o': base = 8; break; case 'x': case 'X': base = 16; break; case 'b': case 'B': base = 2; break; case 'u': case 'd': case 'i': default: base = 10; break; } if (base != 10) { int numbits = ffs(base)-1; size_t abs_nlz_bits; size_t numdigits = rb_absint_numwords(val, numbits, &abs_nlz_bits); long i; if (INT_MAX-1 < numdigits) /* INT_MAX is used because rb_long2int is used later. */ rb_raise(rb_eArgError, "size too big"); if (sign) { if (numdigits == 0) numdigits = 1; tmp = rb_str_new(NULL, numdigits); valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp), 1, CHAR_BIT-numbits, INTEGER_PACK_BIG_ENDIAN); for (i = 0; i < RSTRING_LEN(tmp); i++) RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]]; s = RSTRING_PTR(tmp); if (valsign < 0) { sc = '-'; width--; } else if (flags & FPLUS) { sc = '+'; width--; } else if (flags & FSPACE) { sc = ' '; width--; } } else { /* Following conditional "numdigits++" guarantees the * most significant digit as * - '1'(bin), '7'(oct) or 'f'(hex) for negative numbers * - '0' for zero * - not '0' for positive numbers. * * It also guarantees the most significant two * digits will not be '11'(bin), '77'(oct), 'ff'(hex) * or '00'. */ if (numdigits == 0 || ((abs_nlz_bits != (size_t)(numbits-1) || !rb_absint_singlebit_p(val)) && (!bignum ? v < 0 : BIGNUM_NEGATIVE_P(val)))) numdigits++; tmp = rb_str_new(NULL, numdigits); valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp), 1, CHAR_BIT-numbits, INTEGER_PACK_2COMP | INTEGER_PACK_BIG_ENDIAN); for (i = 0; i < RSTRING_LEN(tmp); i++) RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]]; s = RSTRING_PTR(tmp); dots = valsign < 0; } len = rb_long2int(RSTRING_END(tmp) - s); } else if (!bignum) { valsign = 1; if (v < 0) { v = -v; sc = '-'; width--; valsign = -1; } else if (flags & FPLUS) { sc = '+'; width--; } else if (flags & FSPACE) { sc = ' '; width--; } snprintf(nbuf, sizeof(nbuf), "%ld", v); s = nbuf; len = (int)strlen(s); } else { tmp = rb_big2str(val, 10); s = RSTRING_PTR(tmp); valsign = 1; if (s[0] == '-') { s++; sc = '-'; width--; valsign = -1; } else if (flags & FPLUS) { sc = '+'; width--; } else if (flags & FSPACE) { sc = ' '; width--; } len = rb_long2int(RSTRING_END(tmp) - s); } if (dots) { prec -= 2; width -= 2; } if (*p == 'X') { char *pp = s; int c; while ((c = (int)(unsigned char)*pp) != 0) { *pp = rb_enc_toupper(c, enc); pp++; } } if (prefix && !prefix[1]) { /* octal */ if (dots) { prefix = 0; } else if (len == 1 && *s == '0') { len = 0; if (flags & FPREC) prec--; } else if ((flags & FPREC) && (prec > len)) { prefix = 0; } } else if (len == 1 && *s == '0') { prefix = 0; } if (prefix) { width -= (int)strlen(prefix); } if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) { prec = width; width = 0; } else { if (prec < len) { if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0; prec = len; } width -= prec; } if (!(flags&FMINUS)) { CHECK(width); while (width-- > 0) { buf[blen++] = ' '; } } if (sc) PUSH(&sc, 1); if (prefix) { int plen = (int)strlen(prefix); PUSH(prefix, plen); } CHECK(prec - len); if (dots) PUSH("..", 2); if (!sign && valsign < 0) { char c = sign_bits(base, p); while (len < prec--) { buf[blen++] = c; } } else if ((flags & (FMINUS|FPREC)) != FMINUS) { while (len < prec--) { buf[blen++] = '0'; } } PUSH(s, len); RB_GC_GUARD(tmp); CHECK(width); while (width-- > 0) { buf[blen++] = ' '; } } break; case 'f': { VALUE val = GETARG(), num, den; int sign = (flags&FPLUS) ? 1 : 0, zero = 0; long len, done = 0; int prefix = 0; if (!RB_TYPE_P(val, T_RATIONAL)) { nextvalue = val; goto float_value; } if (!(flags&FPREC)) prec = default_float_precision; den = rb_rational_den(val); num = rb_rational_num(val); if (FIXNUM_P(num)) { if ((SIGNED_VALUE)num < 0) { long n = -FIX2LONG(num); num = LONG2FIX(n); sign = -1; } } else if (rb_num_negative_p(num)) { sign = -1; num = rb_funcallv(num, idUMinus, 0, 0); } if (den != INT2FIX(1) || prec > 1) { const ID idDiv = rb_intern("div"); VALUE p10 = rb_int_positive_pow(10, prec); VALUE den_2 = rb_funcall(den, idDiv, 1, INT2FIX(2)); num = rb_funcallv(num, '*', 1, &p10); num = rb_funcallv(num, '+', 1, &den_2); num = rb_funcallv(num, idDiv, 1, &den); } else if (prec >= 0) { zero = prec; } val = rb_obj_as_string(num); len = RSTRING_LEN(val) + zero; if (prec >= len) ++len; /* integer part 0 */ if (sign || (flags&FSPACE)) ++len; if (prec > 0) ++len; /* period */ CHECK(len > width ? len : width); if (sign || (flags&FSPACE)) { buf[blen++] = sign > 0 ? '+' : sign < 0 ? '-' : ' '; prefix++; done++; } len = RSTRING_LEN(val) + zero; t = RSTRING_PTR(val); if (len > prec) { memcpy(&buf[blen], t, len - prec); blen += len - prec; done += len - prec; } else { buf[blen++] = '0'; done++; } if (prec > 0) { buf[blen++] = '.'; done++; } if (zero) { FILL('0', zero); done += zero; } else if (prec > len) { FILL('0', prec - len); memcpy(&buf[blen], t, len); blen += len; done += prec; } else if (prec > 0) { memcpy(&buf[blen], t + len - prec, prec); blen += prec; done += prec; } if ((flags & FWIDTH) && width > done) { int fill = ' '; long shifting = 0; if (!(flags&FMINUS)) { shifting = done; if (flags&FZERO) { shifting -= prefix; fill = '0'; } blen -= shifting; memmove(&buf[blen + width - done], &buf[blen], shifting); } FILL(fill, width - done); blen += shifting; } RB_GC_GUARD(val); break; } case 'g': case 'G': case 'e': case 'E': /* TODO: rational support */ case 'a': case 'A': float_value: { VALUE val = GETARG(); double fval; int i, need; char fbuf[32]; fval = RFLOAT_VALUE(rb_Float(val)); if (isnan(fval) || isinf(fval)) { const char *expr; if (isnan(fval)) { expr = "NaN"; } else { expr = "Inf"; } need = (int)strlen(expr); if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS)) need++; if ((flags & FWIDTH) && need < width) need = width; CHECK(need + 1); snprintf(&buf[blen], need + 1, "%*s", need, ""); if (flags & FMINUS) { if (!isnan(fval) && fval < 0.0) buf[blen++] = '-'; else if (flags & FPLUS) buf[blen++] = '+'; else if (flags & FSPACE) blen++; memcpy(&buf[blen], expr, strlen(expr)); } else { if (!isnan(fval) && fval < 0.0) buf[blen + need - strlen(expr) - 1] = '-'; else if (flags & FPLUS) buf[blen + need - strlen(expr) - 1] = '+'; else if ((flags & FSPACE) && need > width) blen++; memcpy(&buf[blen + need - strlen(expr)], expr, strlen(expr)); } blen += strlen(&buf[blen]); break; } fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec); need = 0; if (*p != 'e' && *p != 'E') { i = INT_MIN; frexp(fval, &i); if (i > 0) need = BIT_DIGITS(i); } need += (flags&FPREC) ? prec : default_float_precision; if ((flags&FWIDTH) && need < width) need = width; need += 20; CHECK(need); snprintf(&buf[blen], need, fbuf, fval); blen += strlen(&buf[blen]); } break; } flags = FNONE; } sprint_exit: RB_GC_GUARD(fmt); /* XXX - We cannot validate the number of arguments if (digit)$ style used. */ if (posarg >= 0 && nextarg < argc) { const char *mesg = "too many arguments for format string"; if (RTEST(ruby_debug)) rb_raise(rb_eArgError, "%s", mesg); if (RTEST(ruby_verbose)) rb_warn("%s", mesg); } rb_str_resize(result, blen); if (tainted) OBJ_TAINT(result); return result; }
static sighandler_t trap_handler(VALUE *cmd, int sig) { sighandler_t func = sighandler; VALUE command; if (NIL_P(*cmd)) { func = SIG_IGN; } else { command = rb_check_string_type(*cmd); if (NIL_P(command) && SYMBOL_P(*cmd)) { command = rb_sym2str(*cmd); if (!command) rb_raise(rb_eArgError, "bad handler"); } if (!NIL_P(command)) { SafeStringValue(command); /* taint check */ *cmd = command; switch (RSTRING_LEN(command)) { case 0: goto sig_ign; break; case 14: if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) { func = SIG_DFL; *cmd = 0; } break; case 7: if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) { sig_ign: func = SIG_IGN; *cmd = Qtrue; } else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) { sig_dfl: func = default_handler(sig); *cmd = 0; } else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) { goto sig_dfl; } break; case 6: if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) { goto sig_ign; } break; case 4: if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) { *cmd = Qundef; } break; } } else { rb_proc_t *proc; GetProcPtr(*cmd, proc); (void)proc; } } return func; }
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); }
static void control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp) { ptrdiff_t pc = -1; ptrdiff_t ep = cfp->ep - th->stack; char ep_in_heap = ' '; char posbuf[MAX_POSBUF+1]; int line = 0; const char *magic, *iseq_name = "-", *selfstr = "-", *biseq_name = "-"; VALUE tmp; const rb_callable_method_entry_t *me; if (ep < 0 || (size_t)ep > th->stack_size) { ep = (ptrdiff_t)cfp->ep; ep_in_heap = 'p'; } switch (VM_FRAME_TYPE(cfp)) { case VM_FRAME_MAGIC_TOP: magic = "TOP"; break; case VM_FRAME_MAGIC_METHOD: magic = "METHOD"; break; case VM_FRAME_MAGIC_CLASS: magic = "CLASS"; break; case VM_FRAME_MAGIC_BLOCK: magic = "BLOCK"; break; case VM_FRAME_MAGIC_CFUNC: magic = "CFUNC"; break; case VM_FRAME_MAGIC_PROC: magic = "PROC"; break; case VM_FRAME_MAGIC_LAMBDA: magic = "LAMBDA"; break; case VM_FRAME_MAGIC_IFUNC: magic = "IFUNC"; break; case VM_FRAME_MAGIC_EVAL: magic = "EVAL"; break; case VM_FRAME_MAGIC_RESCUE: magic = "RESCUE"; break; case 0: magic = "------"; break; default: magic = "(none)"; break; } if (0) { tmp = rb_inspect(cfp->self); selfstr = StringValueCStr(tmp); } else { selfstr = ""; } if (cfp->iseq != 0) { #define RUBY_VM_IFUNC_P(ptr) (RB_TYPE_P((VALUE)(ptr), T_IMEMO) && imemo_type((VALUE)ptr) == imemo_ifunc) if (RUBY_VM_IFUNC_P(cfp->iseq)) { iseq_name = "<ifunc>"; } else if (SYMBOL_P(cfp->iseq)) { tmp = rb_sym2str((VALUE)cfp->iseq); iseq_name = RSTRING_PTR(tmp); snprintf(posbuf, MAX_POSBUF, ":%s", iseq_name); line = -1; } else { pc = cfp->pc - cfp->iseq->body->iseq_encoded; iseq_name = RSTRING_PTR(cfp->iseq->body->location.label); line = rb_vm_get_sourceline(cfp); if (line) { snprintf(posbuf, MAX_POSBUF, "%s:%d", RSTRING_PTR(cfp->iseq->body->location.path), line); } } } else if ((me = rb_vm_frame_method_entry(cfp)) != NULL) { iseq_name = rb_id2name(me->def->original_id); snprintf(posbuf, MAX_POSBUF, ":%s", iseq_name); line = -1; } fprintf(stderr, "c:%04"PRIdPTRDIFF" ", ((rb_control_frame_t *)(th->stack + th->stack_size) - cfp)); if (pc == -1) { fprintf(stderr, "p:---- "); } else { fprintf(stderr, "p:%04"PRIdPTRDIFF" ", pc); } fprintf(stderr, "s:%04"PRIdPTRDIFF" ", cfp->sp - th->stack); fprintf(stderr, ep_in_heap == ' ' ? "e:%06"PRIdPTRDIFF" " : "E:%06"PRIxPTRDIFF" ", ep % 10000); fprintf(stderr, "%-6s", magic); if (line) { fprintf(stderr, " %s", posbuf); } if (VM_FRAME_FINISHED_P(cfp)) { fprintf(stderr, " [FINISH]"); } if (0) { fprintf(stderr, " \t"); fprintf(stderr, "iseq: %-24s ", iseq_name); fprintf(stderr, "self: %-24s ", selfstr); fprintf(stderr, "%-1s ", biseq_name); } fprintf(stderr, "\n"); }
VALUE symbol_spec_rb_sym2str(VALUE self, VALUE sym) { return rb_sym2str(sym); }
static VALUE bug_id2str(VALUE self, VALUE sym) { return rb_sym2str(sym); }