mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
signal.c: refine error messages
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62716 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
dcb28f0da5
commit
cfcf1d1a1a
2 changed files with 75 additions and 68 deletions
141
signal.c
141
signal.c
|
@ -206,16 +206,75 @@ static const struct signals {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char signame_prefix[3] = "SIG";
|
static const char signame_prefix[3] = "SIG";
|
||||||
|
static const int signame_prefix_len = (int)sizeof(signame_prefix);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
signm2signo(const char *nm)
|
signm2signo(VALUE *sig_ptr, int negative, int exit, int *prefix_ptr)
|
||||||
{
|
{
|
||||||
const struct signals *sigs;
|
const struct signals *sigs;
|
||||||
|
VALUE vsig = *sig_ptr;
|
||||||
|
const char *nm;
|
||||||
|
long len;
|
||||||
|
int prefix = 0;
|
||||||
|
|
||||||
for (sigs = siglist; sigs->signm; sigs++)
|
if (RB_SYMBOL_P(vsig)) {
|
||||||
if (strcmp(sigs->signm, nm) == 0)
|
*sig_ptr = vsig = rb_sym2str(vsig);
|
||||||
return sigs->signo;
|
}
|
||||||
return 0;
|
else if (!RB_TYPE_P(vsig, T_STRING)) {
|
||||||
|
VALUE str = rb_check_string_type(vsig);
|
||||||
|
if (NIL_P(str)) {
|
||||||
|
rb_raise(rb_eArgError, "bad signal type %s",
|
||||||
|
rb_obj_classname(vsig));
|
||||||
|
}
|
||||||
|
*sig_ptr = vsig = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_must_asciicompat(vsig);
|
||||||
|
RSTRING_GETMEM(vsig, nm, len);
|
||||||
|
if (memchr(nm, '\0', len)) {
|
||||||
|
rb_raise(rb_eArgError, "signal name with null byte");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > 0 && nm[0] == '-') {
|
||||||
|
if (!negative)
|
||||||
|
rb_raise(rb_eArgError, "negative signal name: % "PRIsVALUE, vsig);
|
||||||
|
prefix = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
negative = 0;
|
||||||
|
}
|
||||||
|
if (len >= prefix + signame_prefix_len) {
|
||||||
|
if (memcmp(nm + prefix, signame_prefix, sizeof(signame_prefix)) == 0)
|
||||||
|
prefix += signame_prefix_len;
|
||||||
|
}
|
||||||
|
if (len <= (long)prefix) {
|
||||||
|
unsupported:
|
||||||
|
if (prefix == signame_prefix_len) {
|
||||||
|
prefix = 0;
|
||||||
|
}
|
||||||
|
else if (prefix > signame_prefix_len) {
|
||||||
|
prefix -= signame_prefix_len;
|
||||||
|
len -= prefix;
|
||||||
|
vsig = rb_str_subseq(vsig, prefix, len);
|
||||||
|
prefix = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
len -= prefix;
|
||||||
|
vsig = rb_str_subseq(vsig, prefix, len);
|
||||||
|
prefix = signame_prefix_len;
|
||||||
|
}
|
||||||
|
rb_raise(rb_eArgError, "unsupported signal `%.*s%"PRIsVALUE"'",
|
||||||
|
prefix, signame_prefix, vsig);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefix_ptr) *prefix_ptr = prefix;
|
||||||
|
for (sigs = siglist + !exit; sigs->signm; sigs++) {
|
||||||
|
if (memcmp(sigs->signm, nm + prefix, len - prefix) == 0 &&
|
||||||
|
sigs->signm[len - prefix] == '\0') {
|
||||||
|
return negative ? -sigs->signo : sigs->signo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto unsupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char*
|
static const char*
|
||||||
|
@ -284,7 +343,6 @@ esignal_init(int argc, VALUE *argv, VALUE self)
|
||||||
int argnum = 1;
|
int argnum = 1;
|
||||||
VALUE sig = Qnil;
|
VALUE sig = Qnil;
|
||||||
int signo;
|
int signo;
|
||||||
const char *signm;
|
|
||||||
|
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
sig = rb_check_to_integer(argv[0], "to_int");
|
sig = rb_check_to_integer(argv[0], "to_int");
|
||||||
|
@ -305,19 +363,11 @@ esignal_init(int argc, VALUE *argv, VALUE self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int len = sizeof(signame_prefix);
|
int prefix;
|
||||||
if (SYMBOL_P(sig)) sig = rb_sym2str(sig); else StringValue(sig);
|
signo = signm2signo(&sig, FALSE, FALSE, &prefix);
|
||||||
signm = RSTRING_PTR(sig);
|
if (prefix != signame_prefix_len) {
|
||||||
if (strncmp(signm, signame_prefix, len) == 0) {
|
sig = rb_str_append(rb_str_new_cstr("SIG"), sig);
|
||||||
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_call_super(1, &sig);
|
||||||
rb_ivar_set(self, id_signo, INT2NUM(signo));
|
rb_ivar_set(self, id_signo, INT2NUM(signo));
|
||||||
|
@ -402,51 +452,18 @@ rb_f_kill(int argc, const VALUE *argv)
|
||||||
#ifndef HAVE_KILLPG
|
#ifndef HAVE_KILLPG
|
||||||
#define killpg(pg, sig) kill(-(pg), (sig))
|
#define killpg(pg, sig) kill(-(pg), (sig))
|
||||||
#endif
|
#endif
|
||||||
int negative = 0;
|
|
||||||
int sig;
|
int sig;
|
||||||
int i;
|
int i;
|
||||||
VALUE str;
|
VALUE str;
|
||||||
const char *s;
|
|
||||||
|
|
||||||
rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
|
rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
|
||||||
|
|
||||||
switch (TYPE(argv[0])) {
|
if (FIXNUM_P(argv[0])) {
|
||||||
case T_FIXNUM:
|
|
||||||
sig = FIX2INT(argv[0]);
|
sig = FIX2INT(argv[0]);
|
||||||
break;
|
}
|
||||||
|
else {
|
||||||
case T_SYMBOL:
|
|
||||||
str = rb_sym2str(argv[0]);
|
|
||||||
goto str_signal;
|
|
||||||
|
|
||||||
case T_STRING:
|
|
||||||
str = argv[0];
|
str = argv[0];
|
||||||
str_signal:
|
sig = signm2signo(&str, TRUE, FALSE, NULL);
|
||||||
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 (argc <= 1) return INT2FIX(0);
|
||||||
|
@ -1204,7 +1221,6 @@ static int
|
||||||
trap_signm(VALUE vsig)
|
trap_signm(VALUE vsig)
|
||||||
{
|
{
|
||||||
int sig = -1;
|
int sig = -1;
|
||||||
const char *s;
|
|
||||||
|
|
||||||
if (FIXNUM_P(vsig)) {
|
if (FIXNUM_P(vsig)) {
|
||||||
sig = FIX2INT(vsig);
|
sig = FIX2INT(vsig);
|
||||||
|
@ -1213,18 +1229,7 @@ trap_signm(VALUE vsig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (RB_SYMBOL_P(vsig)) {
|
sig = signm2signo(&vsig, FALSE, TRUE, NULL);
|
||||||
vsig = rb_sym2str(vsig);
|
|
||||||
}
|
|
||||||
s = StringValueCStr(vsig);
|
|
||||||
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;
|
return sig;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,8 @@ class TestSignal < Test::Unit::TestCase
|
||||||
assert_equal(signo, SignalException.new(signm.to_sym).signo, signm)
|
assert_equal(signo, SignalException.new(signm.to_sym).signo, signm)
|
||||||
assert_equal(signo, SignalException.new(signo).signo, signo)
|
assert_equal(signo, SignalException.new(signo).signo, signo)
|
||||||
end
|
end
|
||||||
|
e = assert_raise(ArgumentError) {SignalException.new("-SIGEXIT")}
|
||||||
|
assert_not_match(/SIG-SIG/, e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_interrupt
|
def test_interrupt
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue