PageRenderTime 60ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/platform/shared/ruby/error.c

http://github.com/rhomobile/rhodes
C | 2394 lines | 1450 code | 310 blank | 634 comment | 193 complexity | 429ae0f3aa2b20c076b7c31ecf9549f1 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, MIT, Apache-2.0, LGPL-2.1, GPL-2.0, MPL-2.0-no-copyleft-exception
  1. /**********************************************************************
  2. error.c -
  3. $Author$
  4. created at: Mon Aug 9 16:11:34 JST 1993
  5. Copyright (C) 1993-2007 Yukihiro Matsumoto
  6. **********************************************************************/
  7. #include "internal.h"
  8. #include "ruby/st.h"
  9. #include "vm_core.h"
  10. #include <stdio.h>
  11. #include <stdarg.h>
  12. #ifdef HAVE_STDLIB_H
  13. #include <stdlib.h>
  14. #endif
  15. #include <errno.h>
  16. #ifdef HAVE_UNISTD_H
  17. #include <unistd.h>
  18. #endif
  19. #include "posixnames.h"
  20. #ifndef EXIT_SUCCESS
  21. #define EXIT_SUCCESS 0
  22. #endif
  23. #ifndef WIFEXITED
  24. #define WIFEXITED(status) 1
  25. #endif
  26. #ifndef WEXITSTATUS
  27. #define WEXITSTATUS(status) (status)
  28. #endif
  29. VALUE rb_iseqw_local_variables(VALUE iseqval);
  30. VALUE rb_iseqw_new(const rb_iseq_t *);
  31. VALUE rb_eEAGAIN;
  32. VALUE rb_eEWOULDBLOCK;
  33. VALUE rb_eEINPROGRESS;
  34. extern const char ruby_description[];
  35. #ifdef OS_ANDROID
  36. #endif
  37. //RHO
  38. #include "logging/RhoLog.h"
  39. int rhoRubyFPrintf(FILE *, const char *, ...);
  40. int rhoRubyVFPrintf(FILE *, const char *, va_list);
  41. #ifndef USE_STD_PRINTF
  42. #define fprintf rhoRubyFPrintf
  43. #define vfprintf rhoRubyVFPrintf
  44. #endif
  45. //RHO
  46. static const char REPORTBUG_MSG[] =
  47. "[NOTE]\n" \
  48. "You may have encountered a bug in the Ruby interpreter" \
  49. " or extension libraries.\n" \
  50. "Bug reports are welcome.\n" \
  51. ""
  52. "For details: https://www.ruby-lang.org/bugreport.html\n\n" \
  53. ;
  54. static const char *
  55. rb_strerrno(int err)
  56. {
  57. #define defined_error(name, num) if (err == (num)) return (name);
  58. #define undefined_error(name)
  59. #include "known_errors.inc"
  60. #undef defined_error
  61. #undef undefined_error
  62. return NULL;
  63. }
  64. static int
  65. err_position_0(char *buf, long len, const char *file, int line)
  66. {
  67. if (!file) {
  68. return 0;
  69. }
  70. else if (line == 0) {
  71. return snprintf(buf, len, "%s: ", file);
  72. }
  73. else {
  74. return snprintf(buf, len, "%s:%d: ", file, line);
  75. }
  76. }
  77. static VALUE
  78. compile_snprintf(rb_encoding *enc, const char *pre, const char *file, int line, const char *fmt, va_list args)
  79. {
  80. VALUE str = rb_enc_str_new(0, 0, enc);
  81. if (file) {
  82. rb_str_cat2(str, file);
  83. if (line) rb_str_catf(str, ":%d", line);
  84. rb_str_cat2(str, ": ");
  85. }
  86. if (pre) rb_str_cat2(str, pre);
  87. rb_str_vcatf(str, fmt, args);
  88. return str;
  89. }
  90. static void
  91. compile_err_append(VALUE mesg)
  92. {
  93. rb_thread_t *th = GET_THREAD();
  94. VALUE err = th->errinfo;
  95. rb_block_t *prev_base_block = th->base_block;
  96. th->base_block = 0;
  97. /* base_block should be zero while normal Ruby execution */
  98. /* after this line, any Ruby code *can* run */
  99. if (th->mild_compile_error) {
  100. if (RTEST(err)) {
  101. VALUE str = rb_obj_as_string(err);
  102. rb_str_cat2(str, "\n");
  103. rb_str_append(str, mesg);
  104. mesg = str;
  105. }
  106. err = rb_exc_new3(rb_eSyntaxError, mesg);
  107. th->errinfo = err;
  108. }
  109. else {
  110. if (!RTEST(err)) {
  111. err = rb_exc_new2(rb_eSyntaxError, "compile error");
  112. th->errinfo = err;
  113. }
  114. rb_str_cat2(mesg, "\n");
  115. rb_write_error_str(mesg);
  116. }
  117. /* returned to the parser world */
  118. th->base_block = prev_base_block;
  119. }
  120. void
  121. rb_compile_error_with_enc(const char *file, int line, void *enc, const char *fmt, ...)
  122. {
  123. va_list args;
  124. VALUE str;
  125. va_start(args, fmt);
  126. str = compile_snprintf(enc, NULL, file, line, fmt, args);
  127. va_end(args);
  128. compile_err_append(str);
  129. }
  130. void
  131. rb_compile_error(const char *file, int line, const char *fmt, ...)
  132. {
  133. va_list args;
  134. VALUE str;
  135. va_start(args, fmt);
  136. str = compile_snprintf(NULL, NULL, file, line, fmt, args);
  137. va_end(args);
  138. compile_err_append(str);
  139. }
  140. void
  141. rb_compile_error_str(VALUE file, int line, void *enc, const char *fmt, ...)
  142. {
  143. va_list args;
  144. VALUE str;
  145. va_start(args, fmt);
  146. str = compile_snprintf(enc, NULL,
  147. NIL_P(file) ? NULL : RSTRING_PTR(file), line,
  148. fmt, args);
  149. va_end(args);
  150. compile_err_append(str);
  151. }
  152. void
  153. rb_compile_error_append(const char *fmt, ...)
  154. {
  155. va_list args;
  156. VALUE str;
  157. va_start(args, fmt);
  158. str = rb_vsprintf(fmt, args);
  159. va_end(args);
  160. compile_err_append(str);
  161. }
  162. static void
  163. compile_warn_print(const char *file, int line, const char *fmt, va_list args)
  164. {
  165. VALUE str;
  166. str = compile_snprintf(NULL, "warning: ", file, line, fmt, args);
  167. rb_str_cat2(str, "\n");
  168. rb_write_error_str(str);
  169. }
  170. void
  171. rb_compile_warn(const char *file, int line, const char *fmt, ...)
  172. {
  173. va_list args;
  174. if (NIL_P(ruby_verbose)) return;
  175. va_start(args, fmt);
  176. compile_warn_print(file, line, fmt, args);
  177. va_end(args);
  178. }
  179. /* rb_compile_warning() reports only in verbose mode */
  180. void
  181. rb_compile_warning(const char *file, int line, const char *fmt, ...)
  182. {
  183. va_list args;
  184. if (!RTEST(ruby_verbose)) return;
  185. va_start(args, fmt);
  186. compile_warn_print(file, line, fmt, args);
  187. va_end(args);
  188. }
  189. static VALUE
  190. warning_string(rb_encoding *enc, const char *fmt, va_list args)
  191. {
  192. VALUE str = rb_enc_str_new(0, 0, enc);
  193. int line;
  194. VALUE file = rb_source_location(&line);
  195. if (!NIL_P(file)) {
  196. str = rb_str_append(str, file);
  197. if (line) rb_str_catf(str, ":%d", line);
  198. rb_str_cat2(str, ": ");
  199. }
  200. rb_str_cat2(str, "warning: ");
  201. rb_str_vcatf(str, fmt, args);
  202. rb_str_cat2(str, "\n");
  203. return str;
  204. }
  205. void
  206. rb_warn(const char *fmt, ...)
  207. {
  208. VALUE mesg;
  209. va_list args;
  210. if (NIL_P(ruby_verbose)) return;
  211. va_start(args, fmt);
  212. mesg = warning_string(0, fmt, args);
  213. va_end(args);
  214. rb_write_error_str(mesg);
  215. }
  216. void
  217. rb_enc_warn(rb_encoding *enc, const char *fmt, ...)
  218. {
  219. VALUE mesg;
  220. va_list args;
  221. if (NIL_P(ruby_verbose)) return;
  222. va_start(args, fmt);
  223. mesg = warning_string(enc, fmt, args);
  224. va_end(args);
  225. rb_write_error_str(mesg);
  226. }
  227. /* rb_warning() reports only in verbose mode */
  228. void
  229. rb_warning(const char *fmt, ...)
  230. {
  231. VALUE mesg;
  232. va_list args;
  233. if (!RTEST(ruby_verbose)) return;
  234. va_start(args, fmt);
  235. mesg = warning_string(0, fmt, args);
  236. va_end(args);
  237. rb_write_error_str(mesg);
  238. }
  239. #if 0
  240. void
  241. rb_enc_warning(rb_encoding *enc, const char *fmt, ...)
  242. {
  243. VALUE mesg;
  244. va_list args;
  245. if (!RTEST(ruby_verbose)) return;
  246. va_start(args, fmt);
  247. mesg = warning_string(enc, fmt, args);
  248. va_end(args);
  249. rb_write_error_str(mesg);
  250. }
  251. #endif
  252. /*
  253. * call-seq:
  254. * warn(msg, ...) -> nil
  255. *
  256. * Displays each of the given messages followed by a record separator on
  257. * STDERR unless warnings have been disabled (for example with the
  258. * <code>-W0</code> flag).
  259. *
  260. * warn("warning 1", "warning 2")
  261. *
  262. * <em>produces:</em>
  263. *
  264. * warning 1
  265. * warning 2
  266. */
  267. static VALUE
  268. rb_warn_m(int argc, VALUE *argv, VALUE exc)
  269. {
  270. if (!NIL_P(ruby_verbose) && argc > 0) {
  271. rb_io_puts(argc, argv, rb_stderr);
  272. }
  273. return Qnil;
  274. }
  275. #define MAX_BUG_REPORTERS 0x100
  276. static struct bug_reporters {
  277. void (*func)(FILE *out, void *data);
  278. void *data;
  279. } bug_reporters[MAX_BUG_REPORTERS];
  280. static int bug_reporters_size;
  281. int
  282. rb_bug_reporter_add(void (*func)(FILE *, void *), void *data)
  283. {
  284. struct bug_reporters *reporter;
  285. if (bug_reporters_size >= MAX_BUG_REPORTERS) {
  286. return 0; /* failed to register */
  287. }
  288. reporter = &bug_reporters[bug_reporters_size++];
  289. reporter->func = func;
  290. reporter->data = data;
  291. return 1;
  292. }
  293. /* SIGSEGV handler might have a very small stack. Thus we need to use it carefully. */
  294. #define REPORT_BUG_BUFSIZ 256
  295. static FILE *
  296. bug_report_file(const char *file, int line)
  297. {
  298. char buf[REPORT_BUG_BUFSIZ];
  299. FILE *out = stderr;
  300. int len = err_position_0(buf, sizeof(buf), file, line);
  301. if ((ssize_t)fwrite(buf, 1, len, out) == (ssize_t)len ||
  302. (ssize_t)fwrite(buf, 1, len, (out = stdout)) == (ssize_t)len) {
  303. return out;
  304. }
  305. return NULL;
  306. }
  307. static void
  308. bug_report_begin(FILE *out, const char *fmt, va_list args)
  309. {
  310. char buf[REPORT_BUG_BUFSIZ];
  311. fputs("[BUG] ", out);
  312. vsnprintf(buf, sizeof(buf), fmt, args);
  313. fputs(buf, out);
  314. snprintf(buf, sizeof(buf), "\n%s\n\n", ruby_description);
  315. fputs(buf, out);
  316. }
  317. #define bug_report_begin(out, fmt) do { \
  318. va_list args; \
  319. va_start(args, fmt); \
  320. bug_report_begin(out, fmt, args); \
  321. va_end(args); \
  322. } while (0)
  323. static void
  324. bug_report_end(FILE *out)
  325. {
  326. /* call additional bug reporters */
  327. {
  328. int i;
  329. for (i=0; i<bug_reporters_size; i++) {
  330. struct bug_reporters *reporter = &bug_reporters[i];
  331. (*reporter->func)(out, reporter->data);
  332. }
  333. }
  334. fprintf(out, REPORTBUG_MSG);
  335. }
  336. #define report_bug(file, line, fmt, ctx) do { \
  337. FILE *out = bug_report_file(file, line); \
  338. if (out) { \
  339. bug_report_begin(out, fmt); \
  340. rb_vm_bugreport(ctx); \
  341. bug_report_end(out); \
  342. } \
  343. } while (0) \
  344. NORETURN(static void die(void));
  345. static void
  346. die(void)
  347. {
  348. #if defined(_WIN32) && defined(RUBY_MSVCRT_VERSION) && RUBY_MSVCRT_VERSION >= 80
  349. _set_abort_behavior( 0, _CALL_REPORTFAULT);
  350. #endif
  351. abort();
  352. }
  353. void
  354. rb_bug(const char *fmt, ...)
  355. {
  356. const char *file = NULL;
  357. int line = 0;
  358. if (GET_THREAD()) {
  359. file = rb_source_loc(&line);
  360. }
  361. report_bug(file, line, fmt, NULL);
  362. die();
  363. }
  364. void
  365. rb_bug_context(const void *ctx, const char *fmt, ...)
  366. {
  367. const char *file = NULL;
  368. int line = 0;
  369. if (GET_THREAD()) {
  370. file = rb_source_loc(&line);
  371. }
  372. report_bug(file, line, fmt, ctx);
  373. die();
  374. }
  375. void
  376. rb_bug_errno(const char *mesg, int errno_arg)
  377. {
  378. if (errno_arg == 0)
  379. rb_bug("%s: errno == 0 (NOERROR)", mesg);
  380. else {
  381. const char *errno_str = rb_strerrno(errno_arg);
  382. if (errno_str)
  383. rb_bug("%s: %s (%s)", mesg, strerror(errno_arg), errno_str);
  384. else
  385. rb_bug("%s: %s (%d)", mesg, strerror(errno_arg), errno_arg);
  386. }
  387. }
  388. /*
  389. * this is safe to call inside signal handler and timer thread
  390. * (which isn't a Ruby Thread object)
  391. */
  392. #define write_or_abort(fd, str, len) (fpwrite((fd), (str), (len)) < 0 ? abort() : (void)0)
  393. #define WRITE_CONST(fd,str) write_or_abort((fd),(str),sizeof(str) - 1)
  394. void
  395. rb_async_bug_errno(const char *mesg, int errno_arg)
  396. {
  397. WRITE_CONST(2, "[ASYNC BUG] ");
  398. write_or_abort(2, mesg, strlen(mesg));
  399. WRITE_CONST(2, "\n");
  400. if (errno_arg == 0) {
  401. WRITE_CONST(2, "errno == 0 (NOERROR)\n");
  402. }
  403. else {
  404. const char *errno_str = rb_strerrno(errno_arg);
  405. if (!errno_str)
  406. errno_str = "undefined errno";
  407. write_or_abort(2, errno_str, strlen(errno_str));
  408. }
  409. WRITE_CONST(2, "\n\n");
  410. write_or_abort(2, ruby_description, strlen(ruby_description));
  411. WRITE_CONST(2, "\n\n");
  412. WRITE_CONST(2, REPORTBUG_MSG);
  413. abort();
  414. }
  415. void
  416. rb_compile_bug(const char *file, int line, const char *fmt, ...)
  417. {
  418. report_bug(file, line, fmt, NULL);
  419. abort();
  420. }
  421. void
  422. rb_compile_bug_str(VALUE file, int line, const char *fmt, ...)
  423. {
  424. report_bug(RSTRING_PTR(file), line, fmt, NULL);
  425. abort();
  426. }
  427. static const char builtin_types[][10] = {
  428. "", /* 0x00, */
  429. "Object",
  430. "Class",
  431. "Module",
  432. "Float",
  433. "String",
  434. "Regexp",
  435. "Array",
  436. "Hash",
  437. "Struct",
  438. "Bignum",
  439. "File",
  440. "Data", /* internal use: wrapped C pointers */
  441. "MatchData", /* data of $~ */
  442. "Complex",
  443. "Rational",
  444. "", /* 0x10 */
  445. "nil",
  446. "true",
  447. "false",
  448. "Symbol", /* :symbol */
  449. "Fixnum",
  450. "undef", /* internal use: #undef; should not happen */
  451. "", /* 0x17 */
  452. "", /* 0x18 */
  453. "", /* 0x19 */
  454. "Memo", /* internal use: general memo */
  455. "Node", /* internal use: syntax tree node */
  456. "iClass", /* internal use: mixed-in module holder */
  457. };
  458. const char *
  459. rb_builtin_type_name(int t)
  460. {
  461. const char *name;
  462. if ((unsigned int)t >= numberof(builtin_types)) return 0;
  463. name = builtin_types[t];
  464. if (*name) return name;
  465. return 0;
  466. }
  467. static const char *
  468. builtin_class_name(VALUE x)
  469. {
  470. const char *etype;
  471. if (NIL_P(x)) {
  472. etype = "nil";
  473. }
  474. else if (FIXNUM_P(x)) {
  475. etype = "Fixnum";
  476. }
  477. else if (SYMBOL_P(x)) {
  478. etype = "Symbol";
  479. }
  480. else if (RB_TYPE_P(x, T_TRUE)) {
  481. etype = "true";
  482. }
  483. else if (RB_TYPE_P(x, T_FALSE)) {
  484. etype = "false";
  485. }
  486. else {
  487. etype = NULL;
  488. }
  489. return etype;
  490. }
  491. const char *
  492. rb_builtin_class_name(VALUE x)
  493. {
  494. const char *etype = builtin_class_name(x);
  495. if (!etype) {
  496. etype = rb_obj_classname(x);
  497. }
  498. return etype;
  499. }
  500. void
  501. rb_check_type(VALUE x, int t)
  502. {
  503. int xt;
  504. if (x == Qundef) {
  505. rb_bug("undef leaked to the Ruby space");
  506. }
  507. xt = TYPE(x);
  508. if (xt != t || (xt == T_DATA && RTYPEDDATA_P(x))) {
  509. const char *tname = rb_builtin_type_name(t);
  510. if (tname) {
  511. const char *cname = builtin_class_name(x);
  512. if (cname)
  513. rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
  514. cname, tname);
  515. else
  516. rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected %s)",
  517. rb_obj_class(x), tname);
  518. }
  519. if (xt > T_MASK && xt <= 0x3f) {
  520. rb_fatal("unknown type 0x%x (0x%x given, probably comes from extension library for ruby 1.8)", t, xt);
  521. }
  522. rb_bug("unknown type 0x%x (0x%x given)", t, xt);
  523. }
  524. }
  525. int
  526. rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent)
  527. {
  528. while (child) {
  529. if (child == parent) return 1;
  530. child = child->parent;
  531. }
  532. return 0;
  533. }
  534. int
  535. rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
  536. {
  537. if (!RB_TYPE_P(obj, T_DATA) ||
  538. !RTYPEDDATA_P(obj) || !rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) {
  539. return 0;
  540. }
  541. return 1;
  542. }
  543. void *
  544. rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
  545. {
  546. const char *etype;
  547. if (!RB_TYPE_P(obj, T_DATA)) {
  548. wrong_type:
  549. etype = builtin_class_name(obj);
  550. if (!etype)
  551. rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected %s)",
  552. rb_obj_class(obj), data_type->wrap_struct_name);
  553. wrong_datatype:
  554. rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
  555. etype, data_type->wrap_struct_name);
  556. }
  557. if (!RTYPEDDATA_P(obj)) {
  558. goto wrong_type;
  559. }
  560. else if (!rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) {
  561. etype = RTYPEDDATA_TYPE(obj)->wrap_struct_name;
  562. goto wrong_datatype;
  563. }
  564. return DATA_PTR(obj);
  565. }
  566. /* exception classes */
  567. VALUE rb_eException;
  568. VALUE rb_eSystemExit;
  569. VALUE rb_eInterrupt;
  570. VALUE rb_eSignal;
  571. VALUE rb_eFatal;
  572. VALUE rb_eStandardError;
  573. VALUE rb_eRuntimeError;
  574. VALUE rb_eTypeError;
  575. VALUE rb_eArgError;
  576. VALUE rb_eIndexError;
  577. VALUE rb_eKeyError;
  578. VALUE rb_eRangeError;
  579. VALUE rb_eNameError;
  580. VALUE rb_eEncodingError;
  581. VALUE rb_eEncCompatError;
  582. VALUE rb_eNoMethodError;
  583. VALUE rb_eSecurityError;
  584. VALUE rb_eNotImpError;
  585. VALUE rb_eNoMemError;
  586. VALUE rb_cNameErrorMesg;
  587. VALUE rb_eScriptError;
  588. VALUE rb_eSyntaxError;
  589. VALUE rb_eLoadError;
  590. VALUE rb_eSystemCallError;
  591. VALUE rb_mErrno;
  592. static VALUE rb_eNOERROR;
  593. static ID id_new, id_cause, id_message, id_backtrace;
  594. static ID id_name, id_args, id_Errno, id_errno, id_i_path;
  595. static ID id_receiver, id_iseq, id_local_variables;
  596. extern ID ruby_static_id_status;
  597. #define id_bt idBt
  598. #define id_bt_locations idBt_locations
  599. #define id_mesg idMesg
  600. #define id_status ruby_static_id_status
  601. #undef rb_exc_new_cstr
  602. VALUE
  603. rb_exc_new(VALUE etype, const char *ptr, long len)
  604. {
  605. return rb_funcall(etype, id_new, 1, rb_str_new(ptr, len));
  606. }
  607. VALUE
  608. rb_exc_new_cstr(VALUE etype, const char *s)
  609. {
  610. return rb_exc_new(etype, s, strlen(s));
  611. }
  612. VALUE
  613. rb_exc_new_str(VALUE etype, VALUE str)
  614. {
  615. StringValue(str);
  616. return rb_funcall(etype, id_new, 1, str);
  617. }
  618. /*
  619. * call-seq:
  620. * Exception.new(msg = nil) -> exception
  621. *
  622. * Construct a new Exception object, optionally passing in
  623. * a message.
  624. */
  625. static VALUE
  626. exc_initialize(int argc, VALUE *argv, VALUE exc)
  627. {
  628. VALUE arg;
  629. rb_scan_args(argc, argv, "01", &arg);
  630. rb_ivar_set(exc, id_mesg, arg);
  631. rb_ivar_set(exc, id_bt, Qnil);
  632. return exc;
  633. }
  634. /*
  635. * Document-method: exception
  636. *
  637. * call-seq:
  638. * exc.exception(string) -> an_exception or exc
  639. *
  640. * With no argument, or if the argument is the same as the receiver,
  641. * return the receiver. Otherwise, create a new
  642. * exception object of the same class as the receiver, but with a
  643. * message equal to <code>string.to_str</code>.
  644. *
  645. */
  646. static VALUE
  647. exc_exception(int argc, VALUE *argv, VALUE self)
  648. {
  649. VALUE exc;
  650. if (argc == 0) return self;
  651. if (argc == 1 && self == argv[0]) return self;
  652. exc = rb_obj_clone(self);
  653. exc_initialize(argc, argv, exc);
  654. return exc;
  655. }
  656. /*
  657. * call-seq:
  658. * exception.to_s -> string
  659. *
  660. * Returns exception's message (or the name of the exception if
  661. * no message is set).
  662. */
  663. static VALUE
  664. exc_to_s(VALUE exc)
  665. {
  666. VALUE mesg = rb_attr_get(exc, idMesg);
  667. if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc));
  668. return rb_String(mesg);
  669. }
  670. /*
  671. * call-seq:
  672. * exception.message -> string
  673. *
  674. * Returns the result of invoking <code>exception.to_s</code>.
  675. * Normally this returns the exception's message or name. By
  676. * supplying a to_str method, exceptions are agreeing to
  677. * be used where Strings are expected.
  678. */
  679. static VALUE
  680. exc_message(VALUE exc)
  681. {
  682. return rb_funcallv(exc, idTo_s, 0, 0);
  683. }
  684. /*
  685. * call-seq:
  686. * exception.inspect -> string
  687. *
  688. * Return this exception's class name and message
  689. */
  690. static VALUE
  691. exc_inspect(VALUE exc)
  692. {
  693. VALUE str, klass;
  694. klass = CLASS_OF(exc);
  695. exc = rb_obj_as_string(exc);
  696. if (RSTRING_LEN(exc) == 0) {
  697. return rb_str_dup(rb_class_name(klass));
  698. }
  699. str = rb_str_buf_new2("#<");
  700. klass = rb_class_name(klass);
  701. rb_str_buf_append(str, klass);
  702. rb_str_buf_cat(str, ": ", 2);
  703. rb_str_buf_append(str, exc);
  704. rb_str_buf_cat(str, ">", 1);
  705. return str;
  706. }
  707. /*
  708. * call-seq:
  709. * exception.backtrace -> array
  710. *
  711. * Returns any backtrace associated with the exception. The backtrace
  712. * is an array of strings, each containing either ``filename:lineNo: in
  713. * `method''' or ``filename:lineNo.''
  714. *
  715. * def a
  716. * raise "boom"
  717. * end
  718. *
  719. * def b
  720. * a()
  721. * end
  722. *
  723. * begin
  724. * b()
  725. * rescue => detail
  726. * print detail.backtrace.join("\n")
  727. * end
  728. *
  729. * <em>produces:</em>
  730. *
  731. * prog.rb:2:in `a'
  732. * prog.rb:6:in `b'
  733. * prog.rb:10
  734. */
  735. static VALUE
  736. exc_backtrace(VALUE exc)
  737. {
  738. VALUE obj;
  739. obj = rb_attr_get(exc, id_bt);
  740. if (rb_backtrace_p(obj)) {
  741. obj = rb_backtrace_to_str_ary(obj);
  742. /* rb_ivar_set(exc, id_bt, obj); */
  743. }
  744. return obj;
  745. }
  746. VALUE
  747. rb_get_backtrace(VALUE exc)
  748. {
  749. ID mid = id_backtrace;
  750. if (rb_method_basic_definition_p(CLASS_OF(exc), id_backtrace)) {
  751. VALUE info, klass = rb_eException;
  752. rb_thread_t *th = GET_THREAD();
  753. if (NIL_P(exc))
  754. return Qnil;
  755. EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, exc, mid, klass, Qundef);
  756. info = exc_backtrace(exc);
  757. EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, exc, mid, klass, info);
  758. if (NIL_P(info))
  759. return Qnil;
  760. return rb_check_backtrace(info);
  761. }
  762. return rb_funcall(exc, mid, 0, 0);
  763. }
  764. /*
  765. * call-seq:
  766. * exception.backtrace_locations -> array
  767. *
  768. * Returns any backtrace associated with the exception. This method is
  769. * similar to Exception#backtrace, but the backtrace is an array of
  770. * Thread::Backtrace::Location.
  771. *
  772. * Now, this method is not affected by Exception#set_backtrace().
  773. */
  774. static VALUE
  775. exc_backtrace_locations(VALUE exc)
  776. {
  777. VALUE obj;
  778. obj = rb_attr_get(exc, id_bt_locations);
  779. if (!NIL_P(obj)) {
  780. obj = rb_backtrace_to_location_ary(obj);
  781. }
  782. return obj;
  783. }
  784. VALUE
  785. rb_check_backtrace(VALUE bt)
  786. {
  787. long i;
  788. static const char err[] = "backtrace must be Array of String";
  789. if (!NIL_P(bt)) {
  790. if (RB_TYPE_P(bt, T_STRING)) return rb_ary_new3(1, bt);
  791. if (rb_backtrace_p(bt)) return bt;
  792. if (!RB_TYPE_P(bt, T_ARRAY)) {
  793. rb_raise(rb_eTypeError, err);
  794. }
  795. for (i=0;i<RARRAY_LEN(bt);i++) {
  796. VALUE e = RARRAY_AREF(bt, i);
  797. if (!RB_TYPE_P(e, T_STRING)) {
  798. rb_raise(rb_eTypeError, err);
  799. }
  800. }
  801. }
  802. return bt;
  803. }
  804. /*
  805. * call-seq:
  806. * exc.set_backtrace(backtrace) -> array
  807. *
  808. * Sets the backtrace information associated with +exc+. The +backtrace+ must
  809. * be an array of String objects or a single String in the format described
  810. * in Exception#backtrace.
  811. *
  812. */
  813. static VALUE
  814. exc_set_backtrace(VALUE exc, VALUE bt)
  815. {
  816. return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt));
  817. }
  818. VALUE
  819. rb_exc_set_backtrace(VALUE exc, VALUE bt)
  820. {
  821. return exc_set_backtrace(exc, bt);
  822. }
  823. /*
  824. * call-seq:
  825. * exception.cause -> an_exception or nil
  826. *
  827. * Returns the previous exception ($!) at the time this exception was raised.
  828. * This is useful for wrapping exceptions and retaining the original exception
  829. * information.
  830. */
  831. static VALUE
  832. exc_cause(VALUE exc)
  833. {
  834. return rb_attr_get(exc, id_cause);
  835. }
  836. static VALUE
  837. try_convert_to_exception(VALUE obj)
  838. {
  839. return rb_check_funcall(obj, idException, 0, 0);
  840. }
  841. /*
  842. * call-seq:
  843. * exc == obj -> true or false
  844. *
  845. * Equality---If <i>obj</i> is not an <code>Exception</code>, returns
  846. * <code>false</code>. Otherwise, returns <code>true</code> if <i>exc</i> and
  847. * <i>obj</i> share same class, messages, and backtrace.
  848. */
  849. static VALUE
  850. exc_equal(VALUE exc, VALUE obj)
  851. {
  852. VALUE mesg, backtrace;
  853. if (exc == obj) return Qtrue;
  854. if (rb_obj_class(exc) != rb_obj_class(obj)) {
  855. int status = 0;
  856. obj = rb_protect(try_convert_to_exception, obj, &status);
  857. if (status || obj == Qundef) {
  858. rb_set_errinfo(Qnil);
  859. return Qfalse;
  860. }
  861. if (rb_obj_class(exc) != rb_obj_class(obj)) return Qfalse;
  862. mesg = rb_check_funcall(obj, id_message, 0, 0);
  863. if (mesg == Qundef) return Qfalse;
  864. backtrace = rb_check_funcall(obj, id_backtrace, 0, 0);
  865. if (backtrace == Qundef) return Qfalse;
  866. }
  867. else {
  868. mesg = rb_attr_get(obj, id_mesg);
  869. backtrace = exc_backtrace(obj);
  870. }
  871. if (!rb_equal(rb_attr_get(exc, id_mesg), mesg))
  872. return Qfalse;
  873. if (!rb_equal(exc_backtrace(exc), backtrace))
  874. return Qfalse;
  875. return Qtrue;
  876. }
  877. /*
  878. * call-seq:
  879. * SystemExit.new -> system_exit
  880. * SystemExit.new(status) -> system_exit
  881. * SystemExit.new(status, msg) -> system_exit
  882. * SystemExit.new(msg) -> system_exit
  883. *
  884. * Create a new +SystemExit+ exception with the given status and message.
  885. * Status is true, false, or an integer.
  886. * If status is not given, true is used.
  887. */
  888. static VALUE
  889. exit_initialize(int argc, VALUE *argv, VALUE exc)
  890. {
  891. VALUE status;
  892. if (argc > 0) {
  893. status = *argv;
  894. switch (status) {
  895. case Qtrue:
  896. status = INT2FIX(EXIT_SUCCESS);
  897. ++argv;
  898. --argc;
  899. break;
  900. case Qfalse:
  901. status = INT2FIX(EXIT_FAILURE);
  902. ++argv;
  903. --argc;
  904. break;
  905. default:
  906. status = rb_check_to_int(status);
  907. if (NIL_P(status)) {
  908. status = INT2FIX(EXIT_SUCCESS);
  909. }
  910. else {
  911. #if EXIT_SUCCESS != 0
  912. if (status == INT2FIX(0))
  913. status = INT2FIX(EXIT_SUCCESS);
  914. #endif
  915. ++argv;
  916. --argc;
  917. }
  918. break;
  919. }
  920. }
  921. else {
  922. status = INT2FIX(EXIT_SUCCESS);
  923. }
  924. rb_call_super(argc, argv);
  925. rb_ivar_set(exc, id_status, status);
  926. return exc;
  927. }
  928. /*
  929. * call-seq:
  930. * system_exit.status -> fixnum
  931. *
  932. * Return the status value associated with this system exit.
  933. */
  934. static VALUE
  935. exit_status(VALUE exc)
  936. {
  937. return rb_attr_get(exc, id_status);
  938. }
  939. /*
  940. * call-seq:
  941. * system_exit.success? -> true or false
  942. *
  943. * Returns +true+ if exiting successful, +false+ if not.
  944. */
  945. static VALUE
  946. exit_success_p(VALUE exc)
  947. {
  948. VALUE status_val = rb_attr_get(exc, id_status);
  949. int status;
  950. if (NIL_P(status_val))
  951. return Qtrue;
  952. status = NUM2INT(status_val);
  953. if (WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS)
  954. return Qtrue;
  955. return Qfalse;
  956. }
  957. void
  958. rb_name_error(ID id, const char *fmt, ...)
  959. {
  960. VALUE exc, argv[2];
  961. va_list args;
  962. va_start(args, fmt);
  963. argv[0] = rb_vsprintf(fmt, args);
  964. va_end(args);
  965. argv[1] = ID2SYM(id);
  966. exc = rb_class_new_instance(2, argv, rb_eNameError);
  967. rb_exc_raise(exc);
  968. }
  969. void
  970. rb_name_error_str(VALUE str, const char *fmt, ...)
  971. {
  972. VALUE exc, argv[2];
  973. va_list args;
  974. va_start(args, fmt);
  975. argv[0] = rb_vsprintf(fmt, args);
  976. va_end(args);
  977. argv[1] = str;
  978. exc = rb_class_new_instance(2, argv, rb_eNameError);
  979. rb_exc_raise(exc);
  980. }
  981. /*
  982. * call-seq:
  983. * NameError.new(msg [, name]) -> name_error
  984. *
  985. * Construct a new NameError exception. If given the <i>name</i>
  986. * parameter may subsequently be examined using the <code>NameError.name</code>
  987. * method.
  988. */
  989. static VALUE
  990. name_err_initialize(int argc, VALUE *argv, VALUE self)
  991. {
  992. VALUE name;
  993. VALUE iseqw = Qnil;
  994. name = (argc > 1) ? argv[--argc] : Qnil;
  995. rb_call_super(argc, argv);
  996. rb_ivar_set(self, id_name, name);
  997. {
  998. rb_thread_t *th = GET_THREAD();
  999. rb_control_frame_t *cfp =
  1000. rb_vm_get_ruby_level_next_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp));
  1001. if (cfp) iseqw = rb_iseqw_new(cfp->iseq);
  1002. }
  1003. rb_ivar_set(self, id_iseq, iseqw);
  1004. return self;
  1005. }
  1006. /*
  1007. * call-seq:
  1008. * name_error.name -> string or nil
  1009. *
  1010. * Return the name associated with this NameError exception.
  1011. */
  1012. static VALUE
  1013. name_err_name(VALUE self)
  1014. {
  1015. return rb_attr_get(self, id_name);
  1016. }
  1017. /*
  1018. * call-seq:
  1019. * name_error.local_variables -> array
  1020. *
  1021. * Return a list of the local variable names defined where this
  1022. * NameError exception was raised.
  1023. *
  1024. * Internal use only.
  1025. */
  1026. static VALUE
  1027. name_err_local_variables(VALUE self)
  1028. {
  1029. VALUE vars = rb_attr_get(self, id_local_variables);
  1030. if (NIL_P(vars)) {
  1031. VALUE iseqw = rb_attr_get(self, id_iseq);
  1032. if (!NIL_P(iseqw)) vars = rb_iseqw_local_variables(iseqw);
  1033. if (NIL_P(vars)) vars = rb_ary_new();
  1034. rb_ivar_set(self, id_local_variables, vars);
  1035. }
  1036. return vars;
  1037. }
  1038. /*
  1039. * call-seq:
  1040. * NoMethodError.new(msg, name [, args]) -> no_method_error
  1041. *
  1042. * Construct a NoMethodError exception for a method of the given name
  1043. * called with the given arguments. The name may be accessed using
  1044. * the <code>#name</code> method on the resulting object, and the
  1045. * arguments using the <code>#args</code> method.
  1046. */
  1047. static VALUE
  1048. nometh_err_initialize(int argc, VALUE *argv, VALUE self)
  1049. {
  1050. VALUE args = (argc > 2) ? argv[--argc] : Qnil;
  1051. name_err_initialize(argc, argv, self);
  1052. rb_ivar_set(self, id_args, args);
  1053. return self;
  1054. }
  1055. /* :nodoc: */
  1056. enum {
  1057. NAME_ERR_MESG__MESG,
  1058. NAME_ERR_MESG__RECV,
  1059. NAME_ERR_MESG__NAME,
  1060. NAME_ERR_MESG_COUNT
  1061. };
  1062. static void
  1063. name_err_mesg_mark(void *p)
  1064. {
  1065. VALUE *ptr = p;
  1066. rb_gc_mark_locations(ptr, ptr+NAME_ERR_MESG_COUNT);
  1067. }
  1068. #define name_err_mesg_free RUBY_TYPED_DEFAULT_FREE
  1069. static size_t
  1070. name_err_mesg_memsize(const void *p)
  1071. {
  1072. return NAME_ERR_MESG_COUNT * sizeof(VALUE);
  1073. }
  1074. static const rb_data_type_t name_err_mesg_data_type = {
  1075. "name_err_mesg",
  1076. {
  1077. name_err_mesg_mark,
  1078. name_err_mesg_free,
  1079. name_err_mesg_memsize,
  1080. },
  1081. 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
  1082. };
  1083. /* :nodoc: */
  1084. VALUE
  1085. rb_name_err_mesg_new(VALUE mesg, VALUE recv, VALUE method)
  1086. {
  1087. VALUE result = TypedData_Wrap_Struct(rb_cNameErrorMesg, &name_err_mesg_data_type, 0);
  1088. VALUE *ptr = ALLOC_N(VALUE, NAME_ERR_MESG_COUNT);
  1089. ptr[NAME_ERR_MESG__MESG] = mesg;
  1090. ptr[NAME_ERR_MESG__RECV] = recv;
  1091. ptr[NAME_ERR_MESG__NAME] = method;
  1092. RTYPEDDATA_DATA(result) = ptr;
  1093. return result;
  1094. }
  1095. VALUE
  1096. rb_name_err_new(VALUE mesg, VALUE recv, VALUE method)
  1097. {
  1098. VALUE exc = rb_obj_alloc(rb_eNameError);
  1099. rb_ivar_set(exc, id_mesg, rb_name_err_mesg_new(mesg, recv, method));
  1100. rb_ivar_set(exc, id_bt, Qnil);
  1101. rb_ivar_set(exc, id_name, method);
  1102. rb_ivar_set(exc, id_receiver, recv);
  1103. return exc;
  1104. }
  1105. /* :nodoc: */
  1106. static VALUE
  1107. name_err_mesg_equal(VALUE obj1, VALUE obj2)
  1108. {
  1109. VALUE *ptr1, *ptr2;
  1110. int i;
  1111. if (obj1 == obj2) return Qtrue;
  1112. if (rb_obj_class(obj2) != rb_cNameErrorMesg)
  1113. return Qfalse;
  1114. TypedData_Get_Struct(obj1, VALUE, &name_err_mesg_data_type, ptr1);
  1115. TypedData_Get_Struct(obj2, VALUE, &name_err_mesg_data_type, ptr2);
  1116. for (i=0; i<NAME_ERR_MESG_COUNT; i++) {
  1117. if (!rb_equal(ptr1[i], ptr2[i]))
  1118. return Qfalse;
  1119. }
  1120. return Qtrue;
  1121. }
  1122. /* :nodoc: */
  1123. static VALUE
  1124. name_err_mesg_to_str(VALUE obj)
  1125. {
  1126. VALUE *ptr, mesg;
  1127. TypedData_Get_Struct(obj, VALUE, &name_err_mesg_data_type, ptr);
  1128. mesg = ptr[NAME_ERR_MESG__MESG];
  1129. if (NIL_P(mesg)) return Qnil;
  1130. else {
  1131. struct RString s_str, d_str;
  1132. VALUE c, s, d = 0, args[4];
  1133. int state = 0, singleton = 0;
  1134. rb_encoding *usascii = rb_usascii_encoding();
  1135. #define FAKE_CSTR(v, str) rb_setup_fake_str((v), (str), rb_strlen_lit(str), usascii)
  1136. obj = ptr[NAME_ERR_MESG__RECV];
  1137. switch (obj) {
  1138. case Qnil:
  1139. d = FAKE_CSTR(&d_str, "nil");
  1140. break;
  1141. case Qtrue:
  1142. d = FAKE_CSTR(&d_str, "true");
  1143. break;
  1144. case Qfalse:
  1145. d = FAKE_CSTR(&d_str, "false");
  1146. break;
  1147. default:
  1148. d = rb_protect(rb_inspect, obj, &state);
  1149. if (state)
  1150. rb_set_errinfo(Qnil);
  1151. if (NIL_P(d) || RSTRING_LEN(d) > 65) {
  1152. d = rb_any_to_s(obj);
  1153. }
  1154. singleton = (RSTRING_LEN(d) > 0 && RSTRING_PTR(d)[0] == '#');
  1155. d = QUOTE(d);
  1156. break;
  1157. }
  1158. if (!singleton) {
  1159. s = FAKE_CSTR(&s_str, ":");
  1160. c = rb_class_name(CLASS_OF(obj));
  1161. }
  1162. else {
  1163. c = s = FAKE_CSTR(&s_str, "");
  1164. }
  1165. args[0] = QUOTE(rb_obj_as_string(ptr[NAME_ERR_MESG__NAME]));
  1166. args[1] = d;
  1167. args[2] = s;
  1168. args[3] = c;
  1169. mesg = rb_str_format(4, args, mesg);
  1170. }
  1171. return mesg;
  1172. }
  1173. /* :nodoc: */
  1174. static VALUE
  1175. name_err_mesg_dump(VALUE obj, VALUE limit)
  1176. {
  1177. return name_err_mesg_to_str(obj);
  1178. }
  1179. /* :nodoc: */
  1180. static VALUE
  1181. name_err_mesg_load(VALUE klass, VALUE str)
  1182. {
  1183. return str;
  1184. }
  1185. /*
  1186. * call-seq:
  1187. * name_error.receiver -> object
  1188. *
  1189. * Return the receiver associated with this NameError exception.
  1190. */
  1191. static VALUE
  1192. name_err_receiver(VALUE self)
  1193. {
  1194. VALUE *ptr, recv, mesg;
  1195. recv = rb_ivar_lookup(self, id_receiver, Qundef);
  1196. if (recv != Qundef) return recv;
  1197. mesg = rb_attr_get(self, id_mesg);
  1198. if (!rb_typeddata_is_kind_of(mesg, &name_err_mesg_data_type)) {
  1199. rb_raise(rb_eArgError, "no receiver is available");
  1200. }
  1201. ptr = DATA_PTR(mesg);
  1202. return ptr[NAME_ERR_MESG__RECV];
  1203. }
  1204. /*
  1205. * call-seq:
  1206. * no_method_error.args -> obj
  1207. *
  1208. * Return the arguments passed in as the third parameter to
  1209. * the constructor.
  1210. */
  1211. static VALUE
  1212. nometh_err_args(VALUE self)
  1213. {
  1214. return rb_attr_get(self, id_args);
  1215. }
  1216. void
  1217. rb_invalid_str(const char *str, const char *type)
  1218. {
  1219. VALUE s = rb_str_new2(str);
  1220. rb_raise(rb_eArgError, "invalid value for %s: %+"PRIsVALUE, type, s);
  1221. }
  1222. /*
  1223. * Document-module: Errno
  1224. *
  1225. * Ruby exception objects are subclasses of <code>Exception</code>.
  1226. * However, operating systems typically report errors using plain
  1227. * integers. Module <code>Errno</code> is created dynamically to map
  1228. * these operating system errors to Ruby classes, with each error
  1229. * number generating its own subclass of <code>SystemCallError</code>.
  1230. * As the subclass is created in module <code>Errno</code>, its name
  1231. * will start <code>Errno::</code>.
  1232. *
  1233. * The names of the <code>Errno::</code> classes depend on
  1234. * the environment in which Ruby runs. On a typical Unix or Windows
  1235. * platform, there are <code>Errno</code> classes such as
  1236. * <code>Errno::EACCES</code>, <code>Errno::EAGAIN</code>,
  1237. * <code>Errno::EINTR</code>, and so on.
  1238. *
  1239. * The integer operating system error number corresponding to a
  1240. * particular error is available as the class constant
  1241. * <code>Errno::</code><em>error</em><code>::Errno</code>.
  1242. *
  1243. * Errno::EACCES::Errno #=> 13
  1244. * Errno::EAGAIN::Errno #=> 11
  1245. * Errno::EINTR::Errno #=> 4
  1246. *
  1247. * The full list of operating system errors on your particular platform
  1248. * are available as the constants of <code>Errno</code>.
  1249. *
  1250. * Errno.constants #=> :E2BIG, :EACCES, :EADDRINUSE, :EADDRNOTAVAIL, ...
  1251. */
  1252. static st_table *syserr_tbl;
  1253. static VALUE
  1254. set_syserr(int n, const char *name)
  1255. {
  1256. st_data_t error;
  1257. if (!st_lookup(syserr_tbl, n, &error)) {
  1258. error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError);
  1259. /* capture nonblock errnos for WaitReadable/WaitWritable subclasses */
  1260. switch (n) {
  1261. case EAGAIN:
  1262. rb_eEAGAIN = error;
  1263. #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
  1264. break;
  1265. case EWOULDBLOCK:
  1266. #endif
  1267. rb_eEWOULDBLOCK = error;
  1268. break;
  1269. case EINPROGRESS:
  1270. rb_eEINPROGRESS = error;
  1271. break;
  1272. }
  1273. rb_define_const(error, "Errno", INT2NUM(n));
  1274. st_add_direct(syserr_tbl, n, error);
  1275. }
  1276. else {
  1277. rb_define_const(rb_mErrno, name, error);
  1278. }
  1279. return error;
  1280. }
  1281. static VALUE
  1282. get_syserr(int n)
  1283. {
  1284. st_data_t error;
  1285. if (!st_lookup(syserr_tbl, n, &error)) {
  1286. char name[8]; /* some Windows' errno have 5 digits. */
  1287. snprintf(name, sizeof(name), "E%03d", n);
  1288. error = set_syserr(n, name);
  1289. }
  1290. return error;
  1291. }
  1292. /*
  1293. * call-seq:
  1294. * SystemCallError.new(msg, errno) -> system_call_error_subclass
  1295. *
  1296. * If _errno_ corresponds to a known system error code, constructs
  1297. * the appropriate <code>Errno</code> class for that error, otherwise
  1298. * constructs a generic <code>SystemCallError</code> object. The
  1299. * error number is subsequently available via the <code>errno</code>
  1300. * method.
  1301. */
  1302. static VALUE
  1303. syserr_initialize(int argc, VALUE *argv, VALUE self)
  1304. {
  1305. #if !defined(_WIN32)
  1306. char *strerror();
  1307. #endif
  1308. const char *err;
  1309. VALUE mesg, error, func, errmsg;
  1310. VALUE klass = rb_obj_class(self);
  1311. if (klass == rb_eSystemCallError) {
  1312. st_data_t data = (st_data_t)klass;
  1313. rb_scan_args(argc, argv, "12", &mesg, &error, &func);
  1314. if (argc == 1 && FIXNUM_P(mesg)) {
  1315. error = mesg; mesg = Qnil;
  1316. }
  1317. if (!NIL_P(error) && st_lookup(syserr_tbl, NUM2LONG(error), &data)) {
  1318. klass = (VALUE)data;
  1319. /* change class */
  1320. if (!RB_TYPE_P(self, T_OBJECT)) { /* insurance to avoid type crash */
  1321. rb_raise(rb_eTypeError, "invalid instance type");
  1322. }
  1323. RBASIC_SET_CLASS(self, klass);
  1324. }
  1325. }
  1326. else {
  1327. rb_scan_args(argc, argv, "02", &mesg, &func);
  1328. error = rb_const_get(klass, id_Errno);
  1329. }
  1330. if (!NIL_P(error)) err = strerror(NUM2INT(error));
  1331. else err = "unknown error";
  1332. errmsg = rb_enc_str_new_cstr(err, rb_locale_encoding());
  1333. if (!NIL_P(mesg)) {
  1334. VALUE str = StringValue(mesg);
  1335. if (!NIL_P(func)) rb_str_catf(errmsg, " @ %"PRIsVALUE, func);
  1336. rb_str_catf(errmsg, " - %"PRIsVALUE, str);
  1337. OBJ_INFECT(errmsg, mesg);
  1338. }
  1339. mesg = errmsg;
  1340. rb_call_super(1, &mesg);
  1341. rb_ivar_set(self, id_errno, error);
  1342. return self;
  1343. }
  1344. /*
  1345. * call-seq:
  1346. * system_call_error.errno -> fixnum
  1347. *
  1348. * Return this SystemCallError's error number.
  1349. */
  1350. static VALUE
  1351. syserr_errno(VALUE self)
  1352. {
  1353. return rb_attr_get(self, id_errno);
  1354. }
  1355. /*
  1356. * call-seq:
  1357. * system_call_error === other -> true or false
  1358. *
  1359. * Return +true+ if the receiver is a generic +SystemCallError+, or
  1360. * if the error numbers +self+ and _other_ are the same.
  1361. */
  1362. static VALUE
  1363. syserr_eqq(VALUE self, VALUE exc)
  1364. {
  1365. VALUE num, e;
  1366. if (!rb_obj_is_kind_of(exc, rb_eSystemCallError)) {
  1367. if (!rb_respond_to(exc, id_errno)) return Qfalse;
  1368. }
  1369. else if (self == rb_eSystemCallError) return Qtrue;
  1370. num = rb_attr_get(exc, id_errno);
  1371. if (NIL_P(num)) {
  1372. num = rb_funcallv(exc, id_errno, 0, 0);
  1373. }
  1374. e = rb_const_get(self, id_Errno);
  1375. if (FIXNUM_P(num) ? num == e : rb_equal(num, e))
  1376. return Qtrue;
  1377. return Qfalse;
  1378. }
  1379. /*
  1380. * Document-class: StandardError
  1381. *
  1382. * The most standard error types are subclasses of StandardError. A
  1383. * rescue clause without an explicit Exception class will rescue all
  1384. * StandardErrors (and only those).
  1385. *
  1386. * def foo
  1387. * raise "Oups"
  1388. * end
  1389. * foo rescue "Hello" #=> "Hello"
  1390. *
  1391. * On the other hand:
  1392. *
  1393. * require 'does/not/exist' rescue "Hi"
  1394. *
  1395. * <em>raises the exception:</em>
  1396. *
  1397. * LoadError: no such file to load -- does/not/exist
  1398. *
  1399. */
  1400. /*
  1401. * Document-class: SystemExit
  1402. *
  1403. * Raised by +exit+ to initiate the termination of the script.
  1404. */
  1405. /*
  1406. * Document-class: SignalException
  1407. *
  1408. * Raised when a signal is received.
  1409. *
  1410. * begin
  1411. * Process.kill('HUP',Process.pid)
  1412. * sleep # wait for receiver to handle signal sent by Process.kill
  1413. * rescue SignalException => e
  1414. * puts "received Exception #{e}"
  1415. * end
  1416. *
  1417. * <em>produces:</em>
  1418. *
  1419. * received Exception SIGHUP
  1420. */
  1421. /*
  1422. * Document-class: Interrupt
  1423. *
  1424. * Raised with the interrupt signal is received, typically because the
  1425. * user pressed on Control-C (on most posix platforms). As such, it is a
  1426. * subclass of +SignalException+.
  1427. *
  1428. * begin
  1429. * puts "Press ctrl-C when you get bored"
  1430. * loop {}
  1431. * rescue Interrupt => e
  1432. * puts "Note: You will typically use Signal.trap instead."
  1433. * end
  1434. *
  1435. * <em>produces:</em>
  1436. *
  1437. * Press ctrl-C when you get bored
  1438. *
  1439. * <em>then waits until it is interrupted with Control-C and then prints:</em>
  1440. *
  1441. * Note: You will typically use Signal.trap instead.
  1442. */
  1443. /*
  1444. * Document-class: TypeError
  1445. *
  1446. * Raised when encountering an object that is not of the expected type.
  1447. *
  1448. * [1, 2, 3].first("two")
  1449. *
  1450. * <em>raises the exception:</em>
  1451. *
  1452. * TypeError: no implicit conversion of String into Integer
  1453. *
  1454. */
  1455. /*
  1456. * Document-class: ArgumentError
  1457. *
  1458. * Raised when the arguments are wrong and there isn't a more specific
  1459. * Exception class.
  1460. *
  1461. * Ex: passing the wrong number of arguments
  1462. *
  1463. * [1, 2, 3].first(4, 5)
  1464. *
  1465. * <em>raises the exception:</em>
  1466. *
  1467. * ArgumentError: wrong number of arguments (given 2, expected 1)
  1468. *
  1469. * Ex: passing an argument that is not acceptable:
  1470. *
  1471. * [1, 2, 3].first(-4)
  1472. *
  1473. * <em>raises the exception:</em>
  1474. *
  1475. * ArgumentError: negative array size
  1476. */
  1477. /*
  1478. * Document-class: IndexError
  1479. *
  1480. * Raised when the given index is invalid.
  1481. *
  1482. * a = [:foo, :bar]
  1483. * a.fetch(0) #=> :foo
  1484. * a[4] #=> nil
  1485. * a.fetch(4) #=> IndexError: index 4 outside of array bounds: -2...2
  1486. *
  1487. */
  1488. /*
  1489. * Document-class: KeyError
  1490. *
  1491. * Raised when the specified key is not found. It is a subclass of
  1492. * IndexError.
  1493. *
  1494. * h = {"foo" => :bar}
  1495. * h.fetch("foo") #=> :bar
  1496. * h.fetch("baz") #=> KeyError: key not found: "baz"
  1497. *
  1498. */
  1499. /*
  1500. * Document-class: RangeError
  1501. *
  1502. * Raised when a given numerical value is out of range.
  1503. *
  1504. * [1, 2, 3].drop(1 << 100)
  1505. *
  1506. * <em>raises the exception:</em>
  1507. *
  1508. * RangeError: bignum too big to convert into `long'
  1509. */
  1510. /*
  1511. * Document-class: ScriptError
  1512. *
  1513. * ScriptError is the superclass for errors raised when a script
  1514. * can not be executed because of a +LoadError+,
  1515. * +NotImplementedError+ or a +SyntaxError+. Note these type of
  1516. * +ScriptErrors+ are not +StandardError+ and will not be
  1517. * rescued unless it is specified explicitly (or its ancestor
  1518. * +Exception+).
  1519. */
  1520. /*
  1521. * Document-class: SyntaxError
  1522. *
  1523. * Raised when encountering Ruby code with an invalid syntax.
  1524. *
  1525. * eval("1+1=2")
  1526. *
  1527. * <em>raises the exception:</em>
  1528. *
  1529. * SyntaxError: (eval):1: syntax error, unexpected '=', expecting $end
  1530. */
  1531. /*
  1532. * Document-class: LoadError
  1533. *
  1534. * Raised when a file required (a Ruby script, extension library, ...)
  1535. * fails to load.
  1536. *
  1537. * require 'this/file/does/not/exist'
  1538. *
  1539. * <em>raises the exception:</em>
  1540. *
  1541. * LoadError: no such file to load -- this/file/does/not/exist
  1542. */
  1543. /*
  1544. * Document-class: NotImplementedError
  1545. *
  1546. * Raised when a feature is not implemented on the current platform. For
  1547. * example, methods depending on the +fsync+ or +fork+ system calls may
  1548. * raise this exception if the underlying operating system or Ruby
  1549. * runtime does not support them.
  1550. *
  1551. * Note that if +fork+ raises a +NotImplementedError+, then
  1552. * <code>respond_to?(:fork)</code> returns +false+.
  1553. */
  1554. /*
  1555. * Document-class: NameError
  1556. *
  1557. * Raised when a given name is invalid or undefined.
  1558. *
  1559. * puts foo
  1560. *
  1561. * <em>raises the exception:</em>
  1562. *
  1563. * NameError: undefined local variable or method `foo' for main:Object
  1564. *
  1565. * Since constant names must start with a capital:
  1566. *
  1567. * Fixnum.const_set :answer, 42
  1568. *
  1569. * <em>raises the exception:</em>
  1570. *
  1571. * NameError: wrong constant name answer
  1572. */
  1573. /*
  1574. * Document-class: NoMethodError
  1575. *
  1576. * Raised when a method is called on a receiver which doesn't have it
  1577. * defined and also fails to respond with +method_missing+.
  1578. *
  1579. * "hello".to_ary
  1580. *
  1581. * <em>raises the exception:</em>
  1582. *
  1583. * NoMethodError: undefined method `to_ary' for "hello":String
  1584. */
  1585. /*
  1586. * Document-class: RuntimeError
  1587. *
  1588. * A generic error class raised when an invalid operation is attempted.
  1589. *
  1590. * [1, 2, 3].freeze << 4
  1591. *
  1592. * <em>raises the exception:</em>
  1593. *
  1594. * RuntimeError: can't modify frozen Array
  1595. *
  1596. * Kernel.raise will raise a RuntimeError if no Exception class is
  1597. * specified.
  1598. *
  1599. * raise "ouch"
  1600. *
  1601. * <em>raises the exception:</em>
  1602. *
  1603. * RuntimeError: ouch
  1604. */
  1605. /*
  1606. * Document-class: SecurityError
  1607. *
  1608. * Raised when attempting a potential unsafe operation, typically when
  1609. * the $SAFE level is raised above 0.
  1610. *
  1611. * foo = "bar"
  1612. * proc = Proc.new do
  1613. * $SAFE = 3
  1614. * foo.untaint
  1615. * end
  1616. * proc.call
  1617. *
  1618. * <em>raises the exception:</em>
  1619. *
  1620. * SecurityError: Insecure: Insecure operation `untaint' at level 3
  1621. */
  1622. /*
  1623. * Document-class: NoMemoryError
  1624. *
  1625. * Raised when memory allocation fails.
  1626. */
  1627. /*
  1628. * Document-class: SystemCallError
  1629. *
  1630. * SystemCallError is the base class for all low-level
  1631. * platform-dependent errors.
  1632. *
  1633. * The errors available on the current platform are subclasses of
  1634. * SystemCallError and are defined in the Errno module.
  1635. *
  1636. * File.open("does/not/exist")
  1637. *
  1638. * <em>raises the exception:</em>
  1639. *
  1640. * Errno::ENOENT: No such file or directory - does/not/exist
  1641. */
  1642. /*
  1643. * Document-class: EncodingError
  1644. *
  1645. * EncodingError is the base class for encoding errors.
  1646. */
  1647. /*
  1648. * Document-class: Encoding::CompatibilityError
  1649. *
  1650. * Raised by Encoding and String methods when the source encoding is
  1651. * incompatible with the target encoding.
  1652. */
  1653. /*
  1654. * Document-class: fatal
  1655. *
  1656. * fatal is an Exception that is raised when ruby has encountered a fatal
  1657. * error and must exit. You are not able to rescue fatal.
  1658. */
  1659. /*
  1660. * Document-class: NameError::message
  1661. * :nodoc:
  1662. */
  1663. /*
  1664. * Descendants of class Exception are used to communicate between
  1665. * Kernel#raise and +rescue+ statements in <code>begin ... end</code> blocks.
  1666. * Exception objects carry information about the exception -- its type (the
  1667. * exception's class name), an optional descriptive string, and optional
  1668. * traceback information. Exception subclasses may add additional
  1669. * information like NameError#name.
  1670. *
  1671. * Programs may make subclasses of Exception, typically of StandardError or
  1672. * RuntimeError, to provide custom classes and add additional information.
  1673. * See the subclass list below for defaults for +raise+ and +rescue+.
  1674. *
  1675. * When an exception has been raised but not yet handled (in +rescue+,
  1676. * +ensure+, +at_exit+ and +END+ blocks) the global variable <code>$!</code>
  1677. * will contain the current exception and <code>$@</code> contains the
  1678. * current exception's backtrace.
  1679. *
  1680. * It is recommended that a library should have one subclass of StandardError
  1681. * or RuntimeError and have specific exception types inherit from it. This
  1682. * allows the user to rescue a generic exception type to catch all exceptions
  1683. * the library may raise even if future versions of the library add new
  1684. * exception subclasses.
  1685. *
  1686. * For example:
  1687. *
  1688. * class MyLibrary
  1689. * class Error < RuntimeError
  1690. * end
  1691. *
  1692. * class WidgetError < Error
  1693. * end
  1694. *
  1695. * class FrobError < Error
  1696. * end
  1697. *
  1698. * end
  1699. *
  1700. * To handle both WidgetError and FrobError the library user can rescue
  1701. * MyLibrary::Error.
  1702. *
  1703. * The built-in subclasses of Exception are:
  1704. *
  1705. * * NoMemoryError
  1706. * * ScriptError
  1707. * * LoadError
  1708. * * NotImplementedError
  1709. * * SyntaxError
  1710. * * SecurityError
  1711. * * SignalException
  1712. * * Interrupt
  1713. * * StandardError -- default for +rescue+
  1714. * * ArgumentError
  1715. * * UncaughtThrowError
  1716. * * EncodingError
  1717. * * FiberError
  1718. * * IOError
  1719. * * EOFError
  1720. * * IndexError
  1721. * * KeyError
  1722. * * StopIteration
  1723. * * LocalJumpError
  1724. * * NameError
  1725. * * NoMethodError
  1726. * * RangeError
  1727. * * FloatDomainError
  1728. * * RegexpError
  1729. * * RuntimeError -- default for +raise+
  1730. * * SystemCallError
  1731. * * Errno::*
  1732. * * ThreadError
  1733. * * TypeError
  1734. * * ZeroDivisionError
  1735. * * SystemExit
  1736. * * SystemStackError
  1737. * * fatal -- impossible to rescue
  1738. */
  1739. void
  1740. Init_Exception(void)
  1741. {
  1742. rb_eException = rb_define_class("Exception", rb_cObject);
  1743. rb_define_singleton_method(rb_eException, "exception", rb_class_new_instance, -1);
  1744. rb_define_method(rb_eException, "exception", exc_exception, -1);
  1745. rb_define_method(rb_eException, "initialize", exc_initialize, -1);
  1746. rb_define_method(rb_eException, "==", exc_equal, 1);
  1747. rb_define_method(rb_eException, "to_s", exc_to_s, 0);
  1748. rb_define_method(rb_eException, "message", exc_message, 0);
  1749. rb_define_method(rb_eException, "inspect", exc_inspect, 0);
  1750. rb_define_method(rb_eException, "backtrace", exc_backtrace, 0);
  1751. rb_define_method(rb_eException, "backtrace_locations", exc_backtrace_locations, 0);
  1752. rb_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1);
  1753. rb_define_method(rb_eException, "cause", exc_cause, 0);
  1754. rb_eSystemExit = rb_define_class("SystemExit", rb_eException);
  1755. rb_define_method(rb_eSystemExit, "initialize", exit_initialize, -1);
  1756. rb_define_method(rb_eSystemExit, "status", exit_status, 0);
  1757. rb_define_method(rb_eSystemExit, "success?", exit_success_p, 0);
  1758. rb_eFatal = rb_define_class("fatal", rb_eException);
  1759. rb_eSignal = rb_define_class("SignalException", rb_eException);
  1760. rb_eInterrupt = rb_define_class("Interrupt", rb_eSignal);
  1761. rb_eStandardError = rb_define_class("StandardError", rb_eException);
  1762. rb_eTypeError = rb_define_class("TypeError", rb_eStandardError);
  1763. rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError);
  1764. rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
  1765. rb_eKeyError = rb_define_class("KeyError", rb_eIndexError);
  1766. rb_eRangeError = rb_define_class("RangeError", rb_eStandardError);
  1767. rb_eScriptError = rb_define_class("ScriptError", rb_eException);
  1768. rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
  1769. rb_eLoadError = rb_define_class("LoadError", rb_eScriptError);
  1770. /* the path failed to load */
  1771. rb_attr(rb_eLoadError, rb_intern_const("path"), 1, 0, Qfalse);
  1772. rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError);
  1773. rb_eNameError = rb_define_class("NameError", rb_eStandardError);
  1774. rb_define_method(rb_eNameError, "initialize", name_err_initialize, -1);
  1775. rb_define_method(rb_eNameError, "name", name_err_name, 0);
  1776. rb_define_method(rb_eNameError, "receiver", name_err_receiver, 0);
  1777. rb_define_method(rb_eNameError, "local_variables", name_err_local_variables, 0);
  1778. rb_cNameErrorMesg = rb_define_class_under(rb_eNameError, "message", rb_cData);
  1779. rb_define_method(rb_cNameErrorMesg, "==", name_err_mesg_equal, 1);
  1780. rb_define_method(rb_cNameErrorMesg, "to_str", name_err_mesg_to_str, 0);
  1781. rb_define_method(rb_cNameErrorMesg, "_dump", name_err_mesg_dump, 1);
  1782. rb_define_singleton_method(rb_cNameErrorMesg, "_load", name_err_mesg_load, 1);
  1783. rb_eNoMethodError = rb_define_class("NoMethodError", rb_eNameError);
  1784. rb_define_method(rb_eNoMethodError, "initialize", nometh_err_initialize, -1);
  1785. rb_define_method(rb_eNoMethodError, "args", nometh_err_args, 0);
  1786. rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
  1787. rb_eSecurityError = rb_define_class("SecurityError", rb_eException);
  1788. rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException);
  1789. rb_eEncodingError = rb_define_class("EncodingError", rb_eStandardError);
  1790. rb_eEncCompatError = rb_define_class_under(rb_cEncoding, "CompatibilityError", rb_eEncodingError);
  1791. syserr_tbl = st_init_numtable();
  1792. rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError);
  1793. rb_define_method(rb_eSystemCallError, "initialize", syserr_initialize, -1);
  1794. rb_define_method(rb_eSystemCallError, "errno", syserr_errno, 0);
  1795. rb_define_singleton_method(rb_eSystemCallError, "===", syserr_eqq, 1);
  1796. rb_mErrno = rb_define_module("Errno");
  1797. rb_define_global_function("warn", rb_warn_m, -1);
  1798. id_new = rb_intern_const("new");
  1799. id_cause = rb_intern_const("cause");
  1800. id_message = rb_intern_const("message");
  1801. id_backtrace = rb_intern_const("backtrace");
  1802. id_name = rb_intern_const("name");
  1803. id_args = rb_intern_const("args");
  1804. id_receiver = rb_intern_const("receiver");
  1805. id_local_variables = rb_intern_const("local_variables");
  1806. id_Errno = rb_intern_const("Errno");
  1807. id_errno = rb_intern_const("errno");
  1808. id_i_path = rb_intern_const("@path");
  1809. id_iseq = rb_make_internal_id();
  1810. }
  1811. void
  1812. rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
  1813. {
  1814. va_list args;
  1815. VALUE mesg;
  1816. va_start(args, fmt);
  1817. mesg = rb_enc_vsprintf(enc, fmt, args);
  1818. va_end(args);
  1819. rb_exc_raise(rb_exc_new3(exc, mesg));
  1820. }
  1821. void
  1822. rb_raise(VALUE exc, const char *fmt, ...)
  1823. {
  1824. va_list args;
  1825. VALUE mesg;
  1826. va_start(args, fmt);
  1827. mesg = rb_vsprintf(fmt, args);
  1828. va_end(args);
  1829. rb_exc_raise(rb_exc_new3(exc, mesg));
  1830. }
  1831. NORETURN(static void raise_loaderror(VALUE path, VALUE mesg));
  1832. static void
  1833. raise_loaderror(VALUE path, VALUE mesg)
  1834. {
  1835. VALUE err = rb_exc_new3(rb_eLoadError, mesg);
  1836. rb_ivar_set(err, id_i_path, path);
  1837. rb_exc_raise(err);
  1838. }
  1839. void
  1840. rb_loaderror(const char *fmt, ...)
  1841. {
  1842. va_list args;
  1843. VALUE mesg;
  1844. va_start(args, fmt);
  1845. mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args);
  1846. va_end(args);
  1847. raise_loaderror(Qnil, mesg);
  1848. }
  1849. void
  1850. rb_loaderror_with_path(VALUE path, const char *fmt, ...)
  1851. {
  1852. va_list args;
  1853. VALUE mesg;
  1854. va_start(args, fmt);
  1855. mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args);
  1856. va_end(args);
  1857. raise_loaderror(path, mesg);
  1858. }
  1859. void
  1860. rb_notimplement(void)
  1861. {
  1862. rb_raise(rb_eNotImpError,
  1863. "%"PRIsVALUE"() function is unimplemented on this machine",
  1864. rb_id2str(rb_frame_this_func()));
  1865. }
  1866. void
  1867. rb_fatal(const char *fmt, ...)
  1868. {
  1869. va_list args;
  1870. VALUE mesg;
  1871. va_start(args, fmt);
  1872. mesg = rb_vsprintf(fmt, args);
  1873. va_end(args);
  1874. rb_exc_fatal(rb_exc_new3(rb_eFatal, mesg));
  1875. }
  1876. static VALUE
  1877. make_errno_exc(const char *mesg)
  1878. {
  1879. int n = errno;
  1880. errno = 0;
  1881. if (n == 0) {
  1882. rb_bug("rb_sys_fail(%s) - errno == 0", mesg ? mesg : "");
  1883. }
  1884. return rb_syserr_new(n, mesg);
  1885. }
  1886. static VALUE
  1887. make_errno_exc_str(VALUE mesg)
  1888. {
  1889. int n = errno;
  1890. errno = 0;
  1891. if (!mesg) mesg = Qnil;
  1892. if (n == 0) {
  1893. const char *s = !NIL_P(mesg) ? RSTRING_PTR(mesg) : "";
  1894. rb_bug("rb_sys_fail_str(%s) - errno == 0", s);
  1895. }
  1896. return rb_syserr_new_str(n, mesg);
  1897. }
  1898. VALUE
  1899. rb_syserr_new(int n, const char *mesg)
  1900. {
  1901. VALUE arg;
  1902. arg = mesg ? rb_str_new2(mesg) : Qnil;
  1903. return rb_syserr_new_str(n, arg);
  1904. }
  1905. VALUE
  1906. rb_syserr_new_str(int n, VALUE arg)
  1907. {
  1908. return rb_class_new_instance(1, &arg, get_syserr(n));
  1909. }
  1910. void
  1911. rb_syserr_fail(int e, const char *mesg)
  1912. {
  1913. rb_exc_raise(rb_syserr_new(e, mesg));
  1914. }
  1915. void
  1916. rb_syserr_fail_str(int e, VALUE mesg)
  1917. {
  1918. rb_exc_raise(rb_syserr_new_str(e, mesg));
  1919. }
  1920. void
  1921. rb_sys_fail(const char *mesg)
  1922. {
  1923. rb_exc_raise(make_errno_exc(mesg));
  1924. }
  1925. void
  1926. rb_sys_fail_str(VALUE mesg)
  1927. {
  1928. rb_exc_raise(make_errno_exc_str(mesg));
  1929. }
  1930. #ifdef RUBY_FUNCTION_NAME_STRING
  1931. void
  1932. rb_sys_fail_path_in(const char *func_name, VALUE path)
  1933. {
  1934. int n = errno;
  1935. errno = 0;
  1936. rb_syserr_fail_path_in(func_name, n, path);
  1937. }
  1938. void
  1939. rb_syserr_fail_path_in(const char *func_name, int n, VALUE path)
  1940. {
  1941. VALUE args[2];
  1942. if (!path) path = Qnil;
  1943. if (n == 0) {
  1944. const char *s = !NIL_P(path) ? RSTRING_PTR(path) : "";
  1945. if (!func_name) func_name = "(null)";
  1946. rb_bug("rb_sys_fail_path_in(%s, %s) - errno == 0",
  1947. func_name, s);
  1948. }
  1949. args[0] = path;
  1950. args[1] = rb_str_new_cstr(func_name);
  1951. rb_exc_raise(rb_class_new_instance(2, args, get_syserr(n)));
  1952. }
  1953. #endif
  1954. void
  1955. rb_mod_sys_fail(VALUE mod, const char *mesg)
  1956. {
  1957. VALUE exc = make_errno_exc(mesg);
  1958. rb_extend_object(exc, mod);
  1959. rb_exc_raise(exc);
  1960. }
  1961. void
  1962. rb_mod_sys_fail_str(VALUE mod, VALUE mesg)
  1963. {
  1964. VALUE exc = make_errno_exc_str(mesg);
  1965. rb_extend_object(exc, mod);
  1966. rb_exc_raise(exc);
  1967. }
  1968. void
  1969. rb_mod_syserr_fail(VALUE mod, int e, const char *mesg)
  1970. {
  1971. VALUE exc = rb_syserr_new(e, mesg);
  1972. rb_extend_object(exc, mod);
  1973. rb_exc_raise(exc);
  1974. }
  1975. void
  1976. rb_mod_syserr_fail_str(VALUE mod, int e, VALUE mesg)
  1977. {
  1978. VALUE exc = rb_syserr_new_str(e, mesg);
  1979. rb_extend_object(exc, mod);
  1980. rb_exc_raise(exc);
  1981. }
  1982. void
  1983. rb_sys_warning(const char *fmt, ...)
  1984. {
  1985. VALUE mesg;
  1986. va_list args;
  1987. int errno_save;
  1988. errno_save = errno;
  1989. if (!RTEST(ruby_verbose)) return;
  1990. va_start(args, fmt);
  1991. mesg = warning_string(0, fmt, args);
  1992. va_end(args);
  1993. rb_str_set_len(mesg, RSTRING_LEN(mesg)-1);
  1994. rb_str_catf(mesg, ": %s\n", strerror(errno_save));
  1995. rb_write_error_str(mesg);
  1996. errno = errno_save;
  1997. }
  1998. void
  1999. rb_sys_enc_warning(rb_encoding *enc, const char *fmt, ...)
  2000. {
  2001. VALUE mesg;
  2002. va_list args;
  2003. int errno_save;
  2004. errno_save = errno;
  2005. if (!RTEST(ruby_verbose)) return;
  2006. va_start(args, fmt);
  2007. mesg = warning_string(enc, fmt, args);
  2008. va_end(args);
  2009. rb_str_set_len(mesg, RSTRING_LEN(mesg)-1);
  2010. rb_str_catf(mesg, ": %s\n", strerror(errno_save));
  2011. rb_write_error_str(mesg);
  2012. errno = errno_save;
  2013. }
  2014. void
  2015. rb_load_fail(VALUE path, const char *err)
  2016. {
  2017. VALUE mesg = rb_str_buf_new_cstr(err);
  2018. rb_str_cat2(mesg, " -- ");
  2019. rb_str_append(mesg, path); /* should be ASCII compatible */
  2020. raise_loaderror(path, mesg);
  2021. }
  2022. void
  2023. rb_error_frozen(const char *what)
  2024. {
  2025. rb_raise(rb_eRuntimeError, "can't modify frozen %s", what);
  2026. }
  2027. void
  2028. rb_error_frozen_object(VALUE frozen_obj)
  2029. {
  2030. VALUE debug_info;
  2031. const ID created_info = id_debug_created_info;
  2032. if (!NIL_P(debug_info = rb_attr_get(frozen_obj, created_info))) {
  2033. VALUE path = rb_ary_entry(debug_info, 0);
  2034. VALUE line = rb_ary_entry(debug_info, 1);
  2035. rb_raise(rb_eRuntimeError, "can't modify frozen %"PRIsVALUE", created at %"PRIsVALUE":%"PRIsVALUE,
  2036. CLASS_OF(frozen_obj), path, line);
  2037. }
  2038. else {
  2039. rb_raise(rb_eRuntimeError, "can't modify frozen %"PRIsVALUE,
  2040. CLASS_OF(frozen_obj));
  2041. }
  2042. }
  2043. #undef rb_check_frozen
  2044. void
  2045. rb_check_frozen(VALUE obj)
  2046. {
  2047. rb_check_frozen_internal(obj);
  2048. }
  2049. void
  2050. rb_error_untrusted(VALUE obj)
  2051. {
  2052. }
  2053. #undef rb_check_trusted
  2054. void
  2055. rb_check_trusted(VALUE obj)
  2056. {
  2057. }
  2058. void
  2059. rb_check_copyable(VALUE obj, VALUE orig)
  2060. {
  2061. if (!FL_ABLE(obj)) return;
  2062. rb_check_frozen_internal(obj);
  2063. if (!FL_ABLE(orig)) return;
  2064. if ((~RBASIC(obj)->flags & RBASIC(orig)->flags) & FL_TAINT) {
  2065. if (rb_safe_level() > 0) {
  2066. rb_raise(rb_eSecurityError, "Insecure: can't modify %"PRIsVALUE,
  2067. RBASIC(obj)->klass);
  2068. }
  2069. }
  2070. }
  2071. void
  2072. Init_syserr(void)
  2073. {
  2074. rb_eNOERROR = set_syserr(0, "NOERROR");
  2075. #define defined_error(name, num) set_syserr((num), (name));
  2076. #define undefined_error(name) set_syserr(0, (name));
  2077. #include "known_errors.inc"
  2078. #undef defined_error
  2079. #undef undefined_error
  2080. }