00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "ruby/ruby.h"
00013 #include "ruby/st.h"
00014 #include "ruby/encoding.h"
00015 #include "internal.h"
00016 #include "vm_core.h"
00017
00018 #include <stdio.h>
00019 #include <stdarg.h>
00020 #ifdef HAVE_STDLIB_H
00021 #include <stdlib.h>
00022 #endif
00023 #include <errno.h>
00024 #ifdef HAVE_UNISTD_H
00025 #include <unistd.h>
00026 #endif
00027
00028 #ifndef EXIT_SUCCESS
00029 #define EXIT_SUCCESS 0
00030 #endif
00031
00032 #ifndef WIFEXITED
00033 #define WIFEXITED(status) 1
00034 #endif
00035
00036 #ifndef WEXITSTATUS
00037 #define WEXITSTATUS(status) (status)
00038 #endif
00039
00040 VALUE rb_eEAGAIN;
00041 VALUE rb_eEWOULDBLOCK;
00042 VALUE rb_eEINPROGRESS;
00043
00044 extern const char ruby_description[];
00045
00046 static const char REPORTBUG_MSG[] =
00047 "[NOTE]\n" \
00048 "You may have encountered a bug in the Ruby interpreter" \
00049 " or extension libraries.\n" \
00050 "Bug reports are welcome.\n" \
00051 ""
00052 #if defined __APPLE__
00053 "Don't forget to include the above Crash Report log file.\n"
00054 #endif
00055 "For details: http://www.ruby-lang.org/bugreport.html\n\n" \
00056 ;
00057
00058 static const char *
00059 rb_strerrno(int err)
00060 {
00061 #define defined_error(name, num) if (err == (num)) return (name);
00062 #define undefined_error(name)
00063 #include "known_errors.inc"
00064 #undef defined_error
00065 #undef undefined_error
00066 return NULL;
00067 }
00068
00069 static int
00070 err_position_0(char *buf, long len, const char *file, int line)
00071 {
00072 if (!file) {
00073 return 0;
00074 }
00075 else if (line == 0) {
00076 return snprintf(buf, len, "%s: ", file);
00077 }
00078 else {
00079 return snprintf(buf, len, "%s:%d: ", file, line);
00080 }
00081 }
00082
00083 static VALUE
00084 compile_snprintf(rb_encoding *enc, const char *pre, const char *file, int line, const char *fmt, va_list args)
00085 {
00086 VALUE str = rb_enc_str_new(0, 0, enc);
00087
00088 if (file) {
00089 rb_str_cat2(str, file);
00090 if (line) rb_str_catf(str, ":%d", line);
00091 rb_str_cat2(str, ": ");
00092 }
00093 if (pre) rb_str_cat2(str, pre);
00094 rb_str_vcatf(str, fmt, args);
00095 return str;
00096 }
00097
00098 static void
00099 compile_err_append(VALUE mesg)
00100 {
00101 rb_thread_t *th = GET_THREAD();
00102 VALUE err = th->errinfo;
00103 rb_block_t *prev_base_block = th->base_block;
00104 th->base_block = 0;
00105
00106
00107
00108 if (th->mild_compile_error) {
00109 if (RTEST(err)) {
00110 VALUE str = rb_obj_as_string(err);
00111
00112 rb_str_cat2(str, "\n");
00113 rb_str_append(str, mesg);
00114 mesg = str;
00115 }
00116 err = rb_exc_new3(rb_eSyntaxError, mesg);
00117 th->errinfo = err;
00118 }
00119 else {
00120 if (!RTEST(err)) {
00121 err = rb_exc_new2(rb_eSyntaxError, "compile error");
00122 th->errinfo = err;
00123 }
00124 rb_str_cat2(mesg, "\n");
00125 rb_write_error_str(mesg);
00126 }
00127
00128
00129 th->base_block = prev_base_block;
00130 }
00131
00132 void
00133 rb_compile_error_with_enc(const char *file, int line, void *enc, const char *fmt, ...)
00134 {
00135 va_list args;
00136 VALUE str;
00137
00138 va_start(args, fmt);
00139 str = compile_snprintf(enc, NULL, file, line, fmt, args);
00140 va_end(args);
00141 compile_err_append(str);
00142 }
00143
00144 void
00145 rb_compile_error(const char *file, int line, const char *fmt, ...)
00146 {
00147 va_list args;
00148 VALUE str;
00149
00150 va_start(args, fmt);
00151 str = compile_snprintf(NULL, NULL, file, line, fmt, args);
00152 va_end(args);
00153 compile_err_append(str);
00154 }
00155
00156 void
00157 rb_compile_error_append(const char *fmt, ...)
00158 {
00159 va_list args;
00160 VALUE str;
00161
00162 va_start(args, fmt);
00163 str = rb_vsprintf(fmt, args);
00164 va_end(args);
00165 compile_err_append(str);
00166 }
00167
00168 static void
00169 compile_warn_print(const char *file, int line, const char *fmt, va_list args)
00170 {
00171 VALUE str;
00172
00173 str = compile_snprintf(NULL, "warning: ", file, line, fmt, args);
00174 rb_str_cat2(str, "\n");
00175 rb_write_error_str(str);
00176 }
00177
00178 void
00179 rb_compile_warn(const char *file, int line, const char *fmt, ...)
00180 {
00181 va_list args;
00182
00183 if (NIL_P(ruby_verbose)) return;
00184
00185 va_start(args, fmt);
00186 compile_warn_print(file, line, fmt, args);
00187 va_end(args);
00188 }
00189
00190
00191 void
00192 rb_compile_warning(const char *file, int line, const char *fmt, ...)
00193 {
00194 va_list args;
00195
00196 if (!RTEST(ruby_verbose)) return;
00197
00198 va_start(args, fmt);
00199 compile_warn_print(file, line, fmt, args);
00200 va_end(args);
00201 }
00202
00203 static void
00204 warn_print(const char *fmt, va_list args)
00205 {
00206 VALUE str = rb_str_new(0, 0);
00207 VALUE file = rb_sourcefilename();
00208
00209 if (!NIL_P(file)) {
00210 int line = rb_sourceline();
00211 str = rb_str_append(str, file);
00212 if (line) rb_str_catf(str, ":%d", line);
00213 rb_str_cat2(str, ": ");
00214 }
00215
00216 rb_str_cat2(str, "warning: ");
00217 rb_str_vcatf(str, fmt, args);
00218 rb_str_cat2(str, "\n");
00219 rb_write_error_str(str);
00220 }
00221
00222 void
00223 rb_warn(const char *fmt, ...)
00224 {
00225 va_list args;
00226
00227 if (NIL_P(ruby_verbose)) return;
00228
00229 va_start(args, fmt);
00230 warn_print(fmt, args);
00231 va_end(args);
00232 }
00233
00234
00235 void
00236 rb_warning(const char *fmt, ...)
00237 {
00238 va_list args;
00239
00240 if (!RTEST(ruby_verbose)) return;
00241
00242 va_start(args, fmt);
00243 warn_print(fmt, args);
00244 va_end(args);
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 static VALUE
00264 rb_warn_m(int argc, VALUE *argv, VALUE exc)
00265 {
00266 if (!NIL_P(ruby_verbose) && argc > 0) {
00267 rb_io_puts(argc, argv, rb_stderr);
00268 }
00269 return Qnil;
00270 }
00271
00272 #define MAX_BUG_REPORTERS 0x100
00273
00274 static struct bug_reporters {
00275 void (*func)(FILE *out, void *data);
00276 void *data;
00277 } bug_reporters[MAX_BUG_REPORTERS];
00278
00279 static int bug_reporters_size;
00280
00281 int
00282 rb_bug_reporter_add(void (*func)(FILE *, void *), void *data)
00283 {
00284 struct bug_reporters *reporter;
00285 if (bug_reporters_size >= MAX_BUG_REPORTERS) {
00286 return 0;
00287 }
00288 reporter = &bug_reporters[bug_reporters_size++];
00289 reporter->func = func;
00290 reporter->data = data;
00291
00292 return 1;
00293 }
00294
00295 static void
00296 report_bug(const char *file, int line, const char *fmt, va_list args)
00297 {
00298
00299 char buf[256];
00300 FILE *out = stderr;
00301 int len = err_position_0(buf, 256, file, line);
00302
00303 if ((ssize_t)fwrite(buf, 1, len, out) == (ssize_t)len ||
00304 (ssize_t)fwrite(buf, 1, len, (out = stdout)) == (ssize_t)len) {
00305
00306 fputs("[BUG] ", out);
00307 vsnprintf(buf, 256, fmt, args);
00308 fputs(buf, out);
00309 snprintf(buf, 256, "\n%s\n\n", ruby_description);
00310 fputs(buf, out);
00311
00312 rb_vm_bugreport();
00313
00314
00315 {
00316 int i;
00317 for (i=0; i<bug_reporters_size; i++) {
00318 struct bug_reporters *reporter = &bug_reporters[i];
00319 (*reporter->func)(out, reporter->data);
00320 }
00321 }
00322 fprintf(out, REPORTBUG_MSG);
00323 }
00324 }
00325
00326 void
00327 rb_bug(const char *fmt, ...)
00328 {
00329 va_list args;
00330 const char *file = NULL;
00331 int line = 0;
00332
00333 if (GET_THREAD()) {
00334 file = rb_sourcefile();
00335 line = rb_sourceline();
00336 }
00337
00338 va_start(args, fmt);
00339 report_bug(file, line, fmt, args);
00340 va_end(args);
00341
00342 #if defined(_WIN32) && defined(RUBY_MSVCRT_VERSION) && RUBY_MSVCRT_VERSION >= 80
00343 _set_abort_behavior( 0, _CALL_REPORTFAULT);
00344 #endif
00345
00346 abort();
00347 }
00348
00349 void
00350 rb_bug_errno(const char *mesg, int errno_arg)
00351 {
00352 if (errno_arg == 0)
00353 rb_bug("%s: errno == 0 (NOERROR)", mesg);
00354 else {
00355 const char *errno_str = rb_strerrno(errno_arg);
00356 if (errno_str)
00357 rb_bug("%s: %s (%s)", mesg, strerror(errno_arg), errno_str);
00358 else
00359 rb_bug("%s: %s (%d)", mesg, strerror(errno_arg), errno_arg);
00360 }
00361 }
00362
00363
00364
00365
00366
00367 #define write_or_abort(fd, str, len) (write((fd), (str), (len)) < 0 ? abort() : (void)0)
00368 #define WRITE_CONST(fd,str) write_or_abort((fd),(str),sizeof(str) - 1)
00369
00370 void
00371 rb_async_bug_errno(const char *mesg, int errno_arg)
00372 {
00373 WRITE_CONST(2, "[ASYNC BUG] ");
00374 write_or_abort(2, mesg, strlen(mesg));
00375 WRITE_CONST(2, "\n");
00376
00377 if (errno_arg == 0) {
00378 WRITE_CONST(2, "errno == 0 (NOERROR)\n");
00379 }
00380 else {
00381 const char *errno_str = rb_strerrno(errno_arg);
00382
00383 if (!errno_str)
00384 errno_str = "undefined errno";
00385 write_or_abort(2, errno_str, strlen(errno_str));
00386 }
00387 WRITE_CONST(2, "\n\n");
00388 write_or_abort(2, ruby_description, strlen(ruby_description));
00389 WRITE_CONST(2, "\n\n");
00390 WRITE_CONST(2, REPORTBUG_MSG);
00391 abort();
00392 }
00393
00394 void
00395 rb_compile_bug(const char *file, int line, const char *fmt, ...)
00396 {
00397 va_list args;
00398
00399 va_start(args, fmt);
00400 report_bug(file, line, fmt, args);
00401 va_end(args);
00402
00403 abort();
00404 }
00405
00406 static const char builtin_types[][10] = {
00407 "",
00408 "Object",
00409 "Class",
00410 "Module",
00411 "Float",
00412 "String",
00413 "Regexp",
00414 "Array",
00415 "Hash",
00416 "Struct",
00417 "Bignum",
00418 "File",
00419 "Data",
00420 "MatchData",
00421 "Complex",
00422 "Rational",
00423 "",
00424 "nil",
00425 "true",
00426 "false",
00427 "Symbol",
00428 "Fixnum",
00429 "",
00430 "",
00431 "",
00432 "",
00433 "",
00434 "undef",
00435 "Node",
00436 "iClass",
00437 };
00438
00439 const char *
00440 rb_builtin_type_name(int t)
00441 {
00442 const char *name;
00443 if ((unsigned int)t >= numberof(builtin_types)) return 0;
00444 name = builtin_types[t];
00445 if (*name) return name;
00446 return 0;
00447 }
00448
00449 #define builtin_class_name rb_builtin_class_name
00450 const char *
00451 rb_builtin_class_name(VALUE x)
00452 {
00453 const char *etype;
00454
00455 if (NIL_P(x)) {
00456 etype = "nil";
00457 }
00458 else if (FIXNUM_P(x)) {
00459 etype = "Fixnum";
00460 }
00461 else if (SYMBOL_P(x)) {
00462 etype = "Symbol";
00463 }
00464 else if (RB_TYPE_P(x, T_TRUE)) {
00465 etype = "true";
00466 }
00467 else if (RB_TYPE_P(x, T_FALSE)) {
00468 etype = "false";
00469 }
00470 else {
00471 etype = rb_obj_classname(x);
00472 }
00473 return etype;
00474 }
00475
00476 void
00477 rb_check_type(VALUE x, int t)
00478 {
00479 int xt;
00480
00481 if (x == Qundef) {
00482 rb_bug("undef leaked to the Ruby space");
00483 }
00484
00485 xt = TYPE(x);
00486 if (xt != t || (xt == T_DATA && RTYPEDDATA_P(x))) {
00487 const char *tname = rb_builtin_type_name(t);
00488 if (tname) {
00489 rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
00490 builtin_class_name(x), tname);
00491 }
00492 if (xt > T_MASK && xt <= 0x3f) {
00493 rb_fatal("unknown type 0x%x (0x%x given, probably comes from extension library for ruby 1.8)", t, xt);
00494 }
00495 rb_bug("unknown type 0x%x (0x%x given)", t, xt);
00496 }
00497 }
00498
00499 int
00500 rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent)
00501 {
00502 while (child) {
00503 if (child == parent) return 1;
00504 child = child->parent;
00505 }
00506 return 0;
00507 }
00508
00509 int
00510 rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
00511 {
00512 if (!RB_TYPE_P(obj, T_DATA) ||
00513 !RTYPEDDATA_P(obj) || !rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) {
00514 return 0;
00515 }
00516 return 1;
00517 }
00518
00519 void *
00520 rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
00521 {
00522 const char *etype;
00523 static const char mesg[] = "wrong argument type %s (expected %s)";
00524
00525 if (!RB_TYPE_P(obj, T_DATA)) {
00526 etype = builtin_class_name(obj);
00527 rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name);
00528 }
00529 if (!RTYPEDDATA_P(obj)) {
00530 etype = rb_obj_classname(obj);
00531 rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name);
00532 }
00533 else if (!rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) {
00534 etype = RTYPEDDATA_TYPE(obj)->wrap_struct_name;
00535 rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name);
00536 }
00537 return DATA_PTR(obj);
00538 }
00539
00540
00541 VALUE rb_eException;
00542 VALUE rb_eSystemExit;
00543 VALUE rb_eInterrupt;
00544 VALUE rb_eSignal;
00545 VALUE rb_eFatal;
00546 VALUE rb_eStandardError;
00547 VALUE rb_eRuntimeError;
00548 VALUE rb_eTypeError;
00549 VALUE rb_eArgError;
00550 VALUE rb_eIndexError;
00551 VALUE rb_eKeyError;
00552 VALUE rb_eRangeError;
00553 VALUE rb_eNameError;
00554 VALUE rb_eEncodingError;
00555 VALUE rb_eEncCompatError;
00556 VALUE rb_eNoMethodError;
00557 VALUE rb_eSecurityError;
00558 VALUE rb_eNotImpError;
00559 VALUE rb_eNoMemError;
00560 VALUE rb_cNameErrorMesg;
00561
00562 VALUE rb_eScriptError;
00563 VALUE rb_eSyntaxError;
00564 VALUE rb_eLoadError;
00565
00566 VALUE rb_eSystemCallError;
00567 VALUE rb_mErrno;
00568 static VALUE rb_eNOERROR;
00569
00570 #undef rb_exc_new_cstr
00571
00572 VALUE
00573 rb_exc_new(VALUE etype, const char *ptr, long len)
00574 {
00575 return rb_funcall(etype, rb_intern("new"), 1, rb_str_new(ptr, len));
00576 }
00577
00578 VALUE
00579 rb_exc_new_cstr(VALUE etype, const char *s)
00580 {
00581 return rb_exc_new(etype, s, strlen(s));
00582 }
00583
00584 VALUE
00585 rb_exc_new_str(VALUE etype, VALUE str)
00586 {
00587 StringValue(str);
00588 return rb_funcall(etype, rb_intern("new"), 1, str);
00589 }
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 static VALUE
00600 exc_initialize(int argc, VALUE *argv, VALUE exc)
00601 {
00602 VALUE arg;
00603
00604 rb_scan_args(argc, argv, "01", &arg);
00605 rb_iv_set(exc, "mesg", arg);
00606 rb_iv_set(exc, "bt", Qnil);
00607
00608 return exc;
00609 }
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 static VALUE
00625 exc_exception(int argc, VALUE *argv, VALUE self)
00626 {
00627 VALUE exc;
00628
00629 if (argc == 0) return self;
00630 if (argc == 1 && self == argv[0]) return self;
00631 exc = rb_obj_clone(self);
00632 exc_initialize(argc, argv, exc);
00633
00634 return exc;
00635 }
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 static VALUE
00646 exc_to_s(VALUE exc)
00647 {
00648 VALUE mesg = rb_attr_get(exc, rb_intern("mesg"));
00649
00650 if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc));
00651 return rb_String(mesg);
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664 static VALUE
00665 exc_message(VALUE exc)
00666 {
00667 return rb_funcall(exc, rb_intern("to_s"), 0, 0);
00668 }
00669
00670
00671
00672
00673
00674
00675
00676
00677 static VALUE
00678 exc_inspect(VALUE exc)
00679 {
00680 VALUE str, klass;
00681
00682 klass = CLASS_OF(exc);
00683 exc = rb_obj_as_string(exc);
00684 if (RSTRING_LEN(exc) == 0) {
00685 return rb_str_dup(rb_class_name(klass));
00686 }
00687
00688 str = rb_str_buf_new2("#<");
00689 klass = rb_class_name(klass);
00690 rb_str_buf_append(str, klass);
00691 rb_str_buf_cat(str, ": ", 2);
00692 rb_str_buf_append(str, exc);
00693 rb_str_buf_cat(str, ">", 1);
00694
00695 return str;
00696 }
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727 static VALUE
00728 exc_backtrace(VALUE exc)
00729 {
00730 ID bt;
00731 VALUE obj;
00732
00733 CONST_ID(bt, "bt");
00734 obj = rb_attr_get(exc, bt);
00735
00736 if (rb_backtrace_p(obj)) {
00737 obj = rb_backtrace_to_str_ary(obj);
00738
00739 }
00740
00741 return obj;
00742 }
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 static VALUE
00755 exc_backtrace_locations(VALUE exc)
00756 {
00757 ID bt_locations;
00758 VALUE obj;
00759
00760 CONST_ID(bt_locations, "bt_locations");
00761 obj = rb_attr_get(exc, bt_locations);
00762 if (!NIL_P(obj)) {
00763 obj = rb_backtrace_to_location_ary(obj);
00764 }
00765 return obj;
00766 }
00767
00768 VALUE
00769 rb_check_backtrace(VALUE bt)
00770 {
00771 long i;
00772 static const char err[] = "backtrace must be Array of String";
00773
00774 if (!NIL_P(bt)) {
00775 if (RB_TYPE_P(bt, T_STRING)) return rb_ary_new3(1, bt);
00776 if (rb_backtrace_p(bt)) return bt;
00777 if (!RB_TYPE_P(bt, T_ARRAY)) {
00778 rb_raise(rb_eTypeError, err);
00779 }
00780 for (i=0;i<RARRAY_LEN(bt);i++) {
00781 VALUE e = RARRAY_AREF(bt, i);
00782 if (!RB_TYPE_P(e, T_STRING)) {
00783 rb_raise(rb_eTypeError, err);
00784 }
00785 }
00786 }
00787 return bt;
00788 }
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800 static VALUE
00801 exc_set_backtrace(VALUE exc, VALUE bt)
00802 {
00803 return rb_iv_set(exc, "bt", rb_check_backtrace(bt));
00804 }
00805
00806 VALUE
00807 rb_exc_set_backtrace(VALUE exc, VALUE bt)
00808 {
00809 return exc_set_backtrace(exc, bt);
00810 }
00811
00812 VALUE
00813 exc_cause(VALUE exc)
00814 {
00815 ID id_cause;
00816 CONST_ID(id_cause, "cause");
00817 return rb_attr_get(exc, id_cause);
00818 }
00819
00820 static VALUE
00821 try_convert_to_exception(VALUE obj)
00822 {
00823 ID id_exception;
00824 CONST_ID(id_exception, "exception");
00825 return rb_check_funcall(obj, id_exception, 0, 0);
00826 }
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837 static VALUE
00838 exc_equal(VALUE exc, VALUE obj)
00839 {
00840 VALUE mesg, backtrace;
00841 ID id_mesg;
00842
00843 if (exc == obj) return Qtrue;
00844 CONST_ID(id_mesg, "mesg");
00845
00846 if (rb_obj_class(exc) != rb_obj_class(obj)) {
00847 int status = 0;
00848 ID id_message, id_backtrace;
00849 CONST_ID(id_message, "message");
00850 CONST_ID(id_backtrace, "backtrace");
00851
00852 obj = rb_protect(try_convert_to_exception, obj, &status);
00853 if (status || obj == Qundef) {
00854 rb_set_errinfo(Qnil);
00855 return Qfalse;
00856 }
00857 if (rb_obj_class(exc) != rb_obj_class(obj)) return Qfalse;
00858 mesg = rb_check_funcall(obj, id_message, 0, 0);
00859 if (mesg == Qundef) return Qfalse;
00860 backtrace = rb_check_funcall(obj, id_backtrace, 0, 0);
00861 if (backtrace == Qundef) return Qfalse;
00862 }
00863 else {
00864 mesg = rb_attr_get(obj, id_mesg);
00865 backtrace = exc_backtrace(obj);
00866 }
00867
00868 if (!rb_equal(rb_attr_get(exc, id_mesg), mesg))
00869 return Qfalse;
00870 if (!rb_equal(exc_backtrace(exc), backtrace))
00871 return Qfalse;
00872 return Qtrue;
00873 }
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887 static VALUE
00888 exit_initialize(int argc, VALUE *argv, VALUE exc)
00889 {
00890 VALUE status;
00891 if (argc > 0) {
00892 status = *argv;
00893
00894 switch (status) {
00895 case Qtrue:
00896 status = INT2FIX(EXIT_SUCCESS);
00897 ++argv;
00898 --argc;
00899 break;
00900 case Qfalse:
00901 status = INT2FIX(EXIT_FAILURE);
00902 ++argv;
00903 --argc;
00904 break;
00905 default:
00906 status = rb_check_to_int(status);
00907 if (NIL_P(status)) {
00908 status = INT2FIX(EXIT_SUCCESS);
00909 }
00910 else {
00911 #if EXIT_SUCCESS != 0
00912 if (status == INT2FIX(0))
00913 status = INT2FIX(EXIT_SUCCESS);
00914 #endif
00915 ++argv;
00916 --argc;
00917 }
00918 break;
00919 }
00920 }
00921 else {
00922 status = INT2FIX(EXIT_SUCCESS);
00923 }
00924 rb_call_super(argc, argv);
00925 rb_iv_set(exc, "status", status);
00926 return exc;
00927 }
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937 static VALUE
00938 exit_status(VALUE exc)
00939 {
00940 return rb_attr_get(exc, rb_intern("status"));
00941 }
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951 static VALUE
00952 exit_success_p(VALUE exc)
00953 {
00954 VALUE status_val = rb_attr_get(exc, rb_intern("status"));
00955 int status;
00956
00957 if (NIL_P(status_val))
00958 return Qtrue;
00959 status = NUM2INT(status_val);
00960 if (WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS)
00961 return Qtrue;
00962
00963 return Qfalse;
00964 }
00965
00966 void
00967 rb_name_error(ID id, const char *fmt, ...)
00968 {
00969 VALUE exc, argv[2];
00970 va_list args;
00971
00972 va_start(args, fmt);
00973 argv[0] = rb_vsprintf(fmt, args);
00974 va_end(args);
00975
00976 argv[1] = ID2SYM(id);
00977 exc = rb_class_new_instance(2, argv, rb_eNameError);
00978 rb_exc_raise(exc);
00979 }
00980
00981 void
00982 rb_name_error_str(VALUE str, const char *fmt, ...)
00983 {
00984 VALUE exc, argv[2];
00985 va_list args;
00986
00987 va_start(args, fmt);
00988 argv[0] = rb_vsprintf(fmt, args);
00989 va_end(args);
00990
00991 argv[1] = str;
00992 exc = rb_class_new_instance(2, argv, rb_eNameError);
00993 rb_exc_raise(exc);
00994 }
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005 static VALUE
01006 name_err_initialize(int argc, VALUE *argv, VALUE self)
01007 {
01008 VALUE name;
01009
01010 name = (argc > 1) ? argv[--argc] : Qnil;
01011 rb_call_super(argc, argv);
01012 rb_iv_set(self, "name", name);
01013 return self;
01014 }
01015
01016
01017
01018
01019
01020
01021
01022
01023 static VALUE
01024 name_err_name(VALUE self)
01025 {
01026 return rb_attr_get(self, rb_intern("name"));
01027 }
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039 static VALUE
01040 nometh_err_initialize(int argc, VALUE *argv, VALUE self)
01041 {
01042 VALUE args = (argc > 2) ? argv[--argc] : Qnil;
01043 name_err_initialize(argc, argv, self);
01044 rb_iv_set(self, "args", args);
01045 return self;
01046 }
01047
01048
01049 #define NAME_ERR_MESG_COUNT 3
01050
01051 static void
01052 name_err_mesg_mark(void *p)
01053 {
01054 VALUE *ptr = p;
01055 rb_gc_mark_locations(ptr, ptr+NAME_ERR_MESG_COUNT);
01056 }
01057
01058 #define name_err_mesg_free RUBY_TYPED_DEFAULT_FREE
01059
01060 static size_t
01061 name_err_mesg_memsize(const void *p)
01062 {
01063 return p ? (NAME_ERR_MESG_COUNT * sizeof(VALUE)) : 0;
01064 }
01065
01066 static const rb_data_type_t name_err_mesg_data_type = {
01067 "name_err_mesg",
01068 {
01069 name_err_mesg_mark,
01070 name_err_mesg_free,
01071 name_err_mesg_memsize,
01072 },
01073 NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
01074 };
01075
01076
01077 VALUE
01078 rb_name_err_mesg_new(VALUE obj, VALUE mesg, VALUE recv, VALUE method)
01079 {
01080 VALUE *ptr = ALLOC_N(VALUE, NAME_ERR_MESG_COUNT);
01081 VALUE result;
01082
01083 ptr[0] = mesg;
01084 ptr[1] = recv;
01085 ptr[2] = method;
01086 result = TypedData_Wrap_Struct(rb_cNameErrorMesg, &name_err_mesg_data_type, ptr);
01087 RB_GC_GUARD(mesg);
01088 RB_GC_GUARD(recv);
01089 RB_GC_GUARD(method);
01090 return result;
01091 }
01092
01093
01094 static VALUE
01095 name_err_mesg_equal(VALUE obj1, VALUE obj2)
01096 {
01097 VALUE *ptr1, *ptr2;
01098 int i;
01099
01100 if (obj1 == obj2) return Qtrue;
01101 if (rb_obj_class(obj2) != rb_cNameErrorMesg)
01102 return Qfalse;
01103
01104 TypedData_Get_Struct(obj1, VALUE, &name_err_mesg_data_type, ptr1);
01105 TypedData_Get_Struct(obj2, VALUE, &name_err_mesg_data_type, ptr2);
01106 for (i=0; i<NAME_ERR_MESG_COUNT; i++) {
01107 if (!rb_equal(ptr1[i], ptr2[i]))
01108 return Qfalse;
01109 }
01110 return Qtrue;
01111 }
01112
01113
01114 static VALUE
01115 name_err_mesg_to_str(VALUE obj)
01116 {
01117 VALUE *ptr, mesg;
01118 TypedData_Get_Struct(obj, VALUE, &name_err_mesg_data_type, ptr);
01119
01120 mesg = ptr[0];
01121 if (NIL_P(mesg)) return Qnil;
01122 else {
01123 const char *desc = 0;
01124 VALUE d = 0, args[NAME_ERR_MESG_COUNT];
01125 int state = 0;
01126
01127 obj = ptr[1];
01128 switch (obj) {
01129 case Qnil:
01130 desc = "nil";
01131 break;
01132 case Qtrue:
01133 desc = "true";
01134 break;
01135 case Qfalse:
01136 desc = "false";
01137 break;
01138 default:
01139 d = rb_protect(rb_inspect, obj, &state);
01140 if (state)
01141 rb_set_errinfo(Qnil);
01142 if (NIL_P(d) || RSTRING_LEN(d) > 65) {
01143 d = rb_any_to_s(obj);
01144 }
01145 desc = RSTRING_PTR(d);
01146 break;
01147 }
01148 if (desc && desc[0] != '#') {
01149 d = d ? rb_str_dup(d) : rb_str_new2(desc);
01150 rb_str_cat2(d, ":");
01151 rb_str_append(d, rb_class_name(CLASS_OF(obj)));
01152 }
01153 args[0] = mesg;
01154 args[1] = ptr[2];
01155 args[2] = d;
01156 mesg = rb_f_sprintf(NAME_ERR_MESG_COUNT, args);
01157 }
01158 return mesg;
01159 }
01160
01161
01162 static VALUE
01163 name_err_mesg_dump(VALUE obj, VALUE limit)
01164 {
01165 return name_err_mesg_to_str(obj);
01166 }
01167
01168
01169 static VALUE
01170 name_err_mesg_load(VALUE klass, VALUE str)
01171 {
01172 return str;
01173 }
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183 static VALUE
01184 nometh_err_args(VALUE self)
01185 {
01186 return rb_attr_get(self, rb_intern("args"));
01187 }
01188
01189 void
01190 rb_invalid_str(const char *str, const char *type)
01191 {
01192 VALUE s = rb_str_new2(str);
01193
01194 rb_raise(rb_eArgError, "invalid value for %s: %+"PRIsVALUE, type, s);
01195 }
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228 static st_table *syserr_tbl;
01229
01230 static VALUE
01231 set_syserr(int n, const char *name)
01232 {
01233 st_data_t error;
01234
01235 if (!st_lookup(syserr_tbl, n, &error)) {
01236 error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError);
01237
01238
01239 switch (n) {
01240 case EAGAIN:
01241 rb_eEAGAIN = error;
01242
01243 #if EAGAIN != EWOULDBLOCK
01244 break;
01245 case EWOULDBLOCK:
01246 #endif
01247
01248 rb_eEWOULDBLOCK = error;
01249 break;
01250 case EINPROGRESS:
01251 rb_eEINPROGRESS = error;
01252 break;
01253 }
01254
01255 rb_define_const(error, "Errno", INT2NUM(n));
01256 st_add_direct(syserr_tbl, n, error);
01257 }
01258 else {
01259 rb_define_const(rb_mErrno, name, error);
01260 }
01261 return error;
01262 }
01263
01264 static VALUE
01265 get_syserr(int n)
01266 {
01267 st_data_t error;
01268
01269 if (!st_lookup(syserr_tbl, n, &error)) {
01270 char name[8];
01271
01272 snprintf(name, sizeof(name), "E%03d", n);
01273 error = set_syserr(n, name);
01274 }
01275 return error;
01276 }
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289 static VALUE
01290 syserr_initialize(int argc, VALUE *argv, VALUE self)
01291 {
01292 #if !defined(_WIN32)
01293 char *strerror();
01294 #endif
01295 const char *err;
01296 VALUE mesg, error, func;
01297 VALUE klass = rb_obj_class(self);
01298
01299 if (klass == rb_eSystemCallError) {
01300 st_data_t data = (st_data_t)klass;
01301 rb_scan_args(argc, argv, "12", &mesg, &error, &func);
01302 if (argc == 1 && FIXNUM_P(mesg)) {
01303 error = mesg; mesg = Qnil;
01304 }
01305 if (!NIL_P(error) && st_lookup(syserr_tbl, NUM2LONG(error), &data)) {
01306 klass = (VALUE)data;
01307
01308 if (!RB_TYPE_P(self, T_OBJECT)) {
01309 rb_raise(rb_eTypeError, "invalid instance type");
01310 }
01311 RBASIC_SET_CLASS(self, klass);
01312 }
01313 }
01314 else {
01315 rb_scan_args(argc, argv, "02", &mesg, &func);
01316 error = rb_const_get(klass, rb_intern("Errno"));
01317 }
01318 if (!NIL_P(error)) err = strerror(NUM2INT(error));
01319 else err = "unknown error";
01320 if (!NIL_P(mesg)) {
01321 rb_encoding *le = rb_locale_encoding();
01322 VALUE str = StringValue(mesg);
01323 rb_encoding *me = rb_enc_get(mesg);
01324
01325 if (NIL_P(func))
01326 mesg = rb_sprintf("%s - %"PRIsVALUE, err, mesg);
01327 else
01328 mesg = rb_sprintf("%s @ %"PRIsVALUE" - %"PRIsVALUE, err, func, mesg);
01329 if (le != me && rb_enc_asciicompat(me)) {
01330 le = me;
01331 }
01332 OBJ_INFECT(mesg, str);
01333 rb_enc_associate(mesg, le);
01334 }
01335 else {
01336 mesg = rb_str_new2(err);
01337 rb_enc_associate(mesg, rb_locale_encoding());
01338 }
01339 rb_call_super(1, &mesg);
01340 rb_iv_set(self, "errno", error);
01341 return self;
01342 }
01343
01344
01345
01346
01347
01348
01349
01350
01351 static VALUE
01352 syserr_errno(VALUE self)
01353 {
01354 return rb_attr_get(self, rb_intern("errno"));
01355 }
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365 static VALUE
01366 syserr_eqq(VALUE self, VALUE exc)
01367 {
01368 VALUE num, e;
01369 ID en;
01370
01371 CONST_ID(en, "errno");
01372
01373 if (!rb_obj_is_kind_of(exc, rb_eSystemCallError)) {
01374 if (!rb_respond_to(exc, en)) return Qfalse;
01375 }
01376 else if (self == rb_eSystemCallError) return Qtrue;
01377
01378 num = rb_attr_get(exc, rb_intern("errno"));
01379 if (NIL_P(num)) {
01380 num = rb_funcall(exc, en, 0, 0);
01381 }
01382 e = rb_const_get(self, rb_intern("Errno"));
01383 if (FIXNUM_P(num) ? num == e : rb_equal(num, e))
01384 return Qtrue;
01385 return Qfalse;
01386 }
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772 void
01773 Init_Exception(void)
01774 {
01775 rb_eException = rb_define_class("Exception", rb_cObject);
01776 rb_define_singleton_method(rb_eException, "exception", rb_class_new_instance, -1);
01777 rb_define_method(rb_eException, "exception", exc_exception, -1);
01778 rb_define_method(rb_eException, "initialize", exc_initialize, -1);
01779 rb_define_method(rb_eException, "==", exc_equal, 1);
01780 rb_define_method(rb_eException, "to_s", exc_to_s, 0);
01781 rb_define_method(rb_eException, "message", exc_message, 0);
01782 rb_define_method(rb_eException, "inspect", exc_inspect, 0);
01783 rb_define_method(rb_eException, "backtrace", exc_backtrace, 0);
01784 rb_define_method(rb_eException, "backtrace_locations", exc_backtrace_locations, 0);
01785 rb_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1);
01786 rb_define_method(rb_eException, "cause", exc_cause, 0);
01787
01788 rb_eSystemExit = rb_define_class("SystemExit", rb_eException);
01789 rb_define_method(rb_eSystemExit, "initialize", exit_initialize, -1);
01790 rb_define_method(rb_eSystemExit, "status", exit_status, 0);
01791 rb_define_method(rb_eSystemExit, "success?", exit_success_p, 0);
01792
01793 rb_eFatal = rb_define_class("fatal", rb_eException);
01794 rb_eSignal = rb_define_class("SignalException", rb_eException);
01795 rb_eInterrupt = rb_define_class("Interrupt", rb_eSignal);
01796
01797 rb_eStandardError = rb_define_class("StandardError", rb_eException);
01798 rb_eTypeError = rb_define_class("TypeError", rb_eStandardError);
01799 rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError);
01800 rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
01801 rb_eKeyError = rb_define_class("KeyError", rb_eIndexError);
01802 rb_eRangeError = rb_define_class("RangeError", rb_eStandardError);
01803
01804 rb_eScriptError = rb_define_class("ScriptError", rb_eException);
01805 rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
01806
01807 rb_eLoadError = rb_define_class("LoadError", rb_eScriptError);
01808
01809 rb_attr(rb_eLoadError, rb_intern("path"), 1, 0, Qfalse);
01810
01811 rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError);
01812
01813 rb_eNameError = rb_define_class("NameError", rb_eStandardError);
01814 rb_define_method(rb_eNameError, "initialize", name_err_initialize, -1);
01815 rb_define_method(rb_eNameError, "name", name_err_name, 0);
01816 rb_cNameErrorMesg = rb_define_class_under(rb_eNameError, "message", rb_cData);
01817 rb_define_singleton_method(rb_cNameErrorMesg, "!", rb_name_err_mesg_new, NAME_ERR_MESG_COUNT);
01818 rb_define_method(rb_cNameErrorMesg, "==", name_err_mesg_equal, 1);
01819 rb_define_method(rb_cNameErrorMesg, "to_str", name_err_mesg_to_str, 0);
01820 rb_define_method(rb_cNameErrorMesg, "_dump", name_err_mesg_dump, 1);
01821 rb_define_singleton_method(rb_cNameErrorMesg, "_load", name_err_mesg_load, 1);
01822 rb_eNoMethodError = rb_define_class("NoMethodError", rb_eNameError);
01823 rb_define_method(rb_eNoMethodError, "initialize", nometh_err_initialize, -1);
01824 rb_define_method(rb_eNoMethodError, "args", nometh_err_args, 0);
01825
01826 rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
01827 rb_eSecurityError = rb_define_class("SecurityError", rb_eException);
01828 rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException);
01829 rb_eEncodingError = rb_define_class("EncodingError", rb_eStandardError);
01830 rb_eEncCompatError = rb_define_class_under(rb_cEncoding, "CompatibilityError", rb_eEncodingError);
01831
01832 syserr_tbl = st_init_numtable();
01833 rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError);
01834 rb_define_method(rb_eSystemCallError, "initialize", syserr_initialize, -1);
01835 rb_define_method(rb_eSystemCallError, "errno", syserr_errno, 0);
01836 rb_define_singleton_method(rb_eSystemCallError, "===", syserr_eqq, 1);
01837
01838 rb_mErrno = rb_define_module("Errno");
01839
01840 rb_define_global_function("warn", rb_warn_m, -1);
01841 }
01842
01843 void
01844 rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
01845 {
01846 va_list args;
01847 VALUE mesg;
01848
01849 va_start(args, fmt);
01850 mesg = rb_enc_vsprintf(enc, fmt, args);
01851 va_end(args);
01852
01853 rb_exc_raise(rb_exc_new3(exc, mesg));
01854 }
01855
01856 void
01857 rb_raise(VALUE exc, const char *fmt, ...)
01858 {
01859 va_list args;
01860 VALUE mesg;
01861
01862 va_start(args, fmt);
01863 mesg = rb_vsprintf(fmt, args);
01864 va_end(args);
01865 rb_exc_raise(rb_exc_new3(exc, mesg));
01866 }
01867
01868 NORETURN(static void raise_loaderror(VALUE path, VALUE mesg));
01869
01870 static void
01871 raise_loaderror(VALUE path, VALUE mesg)
01872 {
01873 VALUE err = rb_exc_new3(rb_eLoadError, mesg);
01874 rb_ivar_set(err, rb_intern("@path"), path);
01875 rb_exc_raise(err);
01876 }
01877
01878 void
01879 rb_loaderror(const char *fmt, ...)
01880 {
01881 va_list args;
01882 VALUE mesg;
01883
01884 va_start(args, fmt);
01885 mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args);
01886 va_end(args);
01887 raise_loaderror(Qnil, mesg);
01888 }
01889
01890 void
01891 rb_loaderror_with_path(VALUE path, const char *fmt, ...)
01892 {
01893 va_list args;
01894 VALUE mesg;
01895
01896 va_start(args, fmt);
01897 mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args);
01898 va_end(args);
01899 raise_loaderror(path, mesg);
01900 }
01901
01902 void
01903 rb_notimplement(void)
01904 {
01905 rb_raise(rb_eNotImpError,
01906 "%s() function is unimplemented on this machine",
01907 rb_id2name(rb_frame_this_func()));
01908 }
01909
01910 void
01911 rb_fatal(const char *fmt, ...)
01912 {
01913 va_list args;
01914 VALUE mesg;
01915
01916 va_start(args, fmt);
01917 mesg = rb_vsprintf(fmt, args);
01918 va_end(args);
01919
01920 rb_exc_fatal(rb_exc_new3(rb_eFatal, mesg));
01921 }
01922
01923 static VALUE
01924 make_errno_exc(const char *mesg)
01925 {
01926 int n = errno;
01927
01928 errno = 0;
01929 if (n == 0) {
01930 rb_bug("rb_sys_fail(%s) - errno == 0", mesg ? mesg : "");
01931 }
01932 return rb_syserr_new(n, mesg);
01933 }
01934
01935 static VALUE
01936 make_errno_exc_str(VALUE mesg)
01937 {
01938 int n = errno;
01939
01940 errno = 0;
01941 if (!mesg) mesg = Qnil;
01942 if (n == 0) {
01943 const char *s = !NIL_P(mesg) ? RSTRING_PTR(mesg) : "";
01944 rb_bug("rb_sys_fail_str(%s) - errno == 0", s);
01945 }
01946 return rb_syserr_new_str(n, mesg);
01947 }
01948
01949 VALUE
01950 rb_syserr_new(int n, const char *mesg)
01951 {
01952 VALUE arg;
01953 arg = mesg ? rb_str_new2(mesg) : Qnil;
01954 return rb_syserr_new_str(n, arg);
01955 }
01956
01957 VALUE
01958 rb_syserr_new_str(int n, VALUE arg)
01959 {
01960 return rb_class_new_instance(1, &arg, get_syserr(n));
01961 }
01962
01963 void
01964 rb_syserr_fail(int e, const char *mesg)
01965 {
01966 rb_exc_raise(rb_syserr_new(e, mesg));
01967 }
01968
01969 void
01970 rb_syserr_fail_str(int e, VALUE mesg)
01971 {
01972 rb_exc_raise(rb_syserr_new_str(e, mesg));
01973 }
01974
01975 void
01976 rb_sys_fail(const char *mesg)
01977 {
01978 rb_exc_raise(make_errno_exc(mesg));
01979 }
01980
01981 void
01982 rb_sys_fail_str(VALUE mesg)
01983 {
01984 rb_exc_raise(make_errno_exc_str(mesg));
01985 }
01986
01987 #ifdef RUBY_FUNCTION_NAME_STRING
01988 void
01989 rb_sys_fail_path_in(const char *func_name, VALUE path)
01990 {
01991 int n = errno;
01992
01993 errno = 0;
01994 rb_syserr_fail_path_in(func_name, n, path);
01995 }
01996
01997 void
01998 rb_syserr_fail_path_in(const char *func_name, int n, VALUE path)
01999 {
02000 VALUE args[2];
02001
02002 if (!path) path = Qnil;
02003 if (n == 0) {
02004 const char *s = !NIL_P(path) ? RSTRING_PTR(path) : "";
02005 if (!func_name) func_name = "(null)";
02006 rb_bug("rb_sys_fail_path_in(%s, %s) - errno == 0",
02007 func_name, s);
02008 }
02009 args[0] = path;
02010 args[1] = rb_str_new_cstr(func_name);
02011 rb_exc_raise(rb_class_new_instance(2, args, get_syserr(n)));
02012 }
02013 #endif
02014
02015 void
02016 rb_mod_sys_fail(VALUE mod, const char *mesg)
02017 {
02018 VALUE exc = make_errno_exc(mesg);
02019 rb_extend_object(exc, mod);
02020 rb_exc_raise(exc);
02021 }
02022
02023 void
02024 rb_mod_sys_fail_str(VALUE mod, VALUE mesg)
02025 {
02026 VALUE exc = make_errno_exc_str(mesg);
02027 rb_extend_object(exc, mod);
02028 rb_exc_raise(exc);
02029 }
02030
02031 void
02032 rb_mod_syserr_fail(VALUE mod, int e, const char *mesg)
02033 {
02034 VALUE exc = rb_syserr_new(e, mesg);
02035 rb_extend_object(exc, mod);
02036 rb_exc_raise(exc);
02037 }
02038
02039 void
02040 rb_mod_syserr_fail_str(VALUE mod, int e, VALUE mesg)
02041 {
02042 VALUE exc = rb_syserr_new_str(e, mesg);
02043 rb_extend_object(exc, mod);
02044 rb_exc_raise(exc);
02045 }
02046
02047 void
02048 rb_sys_warning(const char *fmt, ...)
02049 {
02050 char buf[BUFSIZ];
02051 va_list args;
02052 int errno_save;
02053
02054 errno_save = errno;
02055
02056 if (!RTEST(ruby_verbose)) return;
02057
02058 snprintf(buf, BUFSIZ, "warning: %s", fmt);
02059 snprintf(buf+strlen(buf), BUFSIZ-strlen(buf), ": %s", strerror(errno_save));
02060
02061 va_start(args, fmt);
02062 warn_print(buf, args);
02063 va_end(args);
02064 errno = errno_save;
02065 }
02066
02067 void
02068 rb_load_fail(VALUE path, const char *err)
02069 {
02070 VALUE mesg = rb_str_buf_new_cstr(err);
02071 rb_str_cat2(mesg, " -- ");
02072 rb_str_append(mesg, path);
02073 raise_loaderror(path, mesg);
02074 }
02075
02076 void
02077 rb_error_frozen(const char *what)
02078 {
02079 rb_raise(rb_eRuntimeError, "can't modify frozen %s", what);
02080 }
02081
02082 #undef rb_check_frozen
02083 void
02084 rb_check_frozen(VALUE obj)
02085 {
02086 rb_check_frozen_internal(obj);
02087 }
02088
02089 void
02090 rb_error_untrusted(VALUE obj)
02091 {
02092 }
02093
02094 #undef rb_check_trusted
02095 void
02096 rb_check_trusted(VALUE obj)
02097 {
02098 }
02099
02100 void
02101 rb_check_copyable(VALUE obj, VALUE orig)
02102 {
02103 if (!FL_ABLE(obj)) return;
02104 rb_check_frozen_internal(obj);
02105 if (!FL_ABLE(orig)) return;
02106 if ((~RBASIC(obj)->flags & RBASIC(orig)->flags) & FL_TAINT) {
02107 if (rb_safe_level() > 0) {
02108 rb_raise(rb_eSecurityError, "Insecure: can't modify %"PRIsVALUE,
02109 RBASIC(obj)->klass);
02110 }
02111 }
02112 }
02113
02114 void
02115 Init_syserr(void)
02116 {
02117 rb_eNOERROR = set_syserr(0, "NOERROR");
02118 #define defined_error(name, num) set_syserr((num), (name));
02119 #define undefined_error(name) set_syserr(0, (name));
02120 #include "known_errors.inc"
02121 #undef defined_error
02122 #undef undefined_error
02123 }
02124