static mrb_value mrb_file_s_rename(mrb_state *mrb, mrb_value obj) { mrb_value from, to; char *src, *dst; mrb_get_args(mrb, "SS", &from, &to); src = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &from), -1); dst = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &to), -1); if (rename(src, dst) < 0) { #if defined(_WIN32) || defined(_WIN64) if (CHMOD(dst, 0666) == 0 && UNLINK(dst) == 0 && rename(src, dst) == 0) { mrb_locale_free(src); mrb_locale_free(dst); return mrb_fixnum_value(0); } #endif mrb_locale_free(src); mrb_locale_free(dst); mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to))); } mrb_locale_free(src); mrb_locale_free(dst); return mrb_fixnum_value(0); }
static mrb_value mrb_file_s_symlink(mrb_state *mrb, mrb_value klass) { #if defined(_WIN32) || defined(_WIN64) mrb_raise(mrb, E_NOTIMP_ERROR, "symlink is not supported on this platform"); #else mrb_value from, to; const char *src, *dst; int ai = mrb_gc_arena_save(mrb); mrb_get_args(mrb, "SS", &from, &to); src = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, from), -1); dst = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, to), -1); if (symlink(src, dst) == -1) { mrb_locale_free(src); mrb_locale_free(dst); mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to))); } mrb_locale_free(src); mrb_locale_free(dst); mrb_gc_arena_restore(mrb, ai); #endif return mrb_fixnum_value(0); }
static void argnum_error(mrb_state *mrb, mrb_int num) { mrb_value exc; mrb_value str; if (mrb->c->ci->mid) { str = mrb_format(mrb, "'%S': wrong number of arguments (%S for %S)", mrb_sym2str(mrb, mrb->c->ci->mid), mrb_fixnum_value(mrb->c->ci->argc), mrb_fixnum_value(num)); } else { str = mrb_format(mrb, "wrong number of arguments (%S for %S)", mrb_fixnum_value(mrb->c->ci->argc), mrb_fixnum_value(num)); } exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str); mrb->exc = mrb_obj_ptr(exc); }
static mrb_value eval_context_compile(mrb_state *mrb, mrb_value self) { char *script; mrb_int script_length; mrbc_context* compile_ctx; struct mrb_parser_state *parser; struct RProc *proc; mrb_get_args(mrb, "s", &script, &script_length); compile_ctx = mrbc_context_new(mrb); if (!compile_ctx) { mrb_raise(mrb, E_RUNTIME_ERROR, "[mruby][eval][compile] failed to allocate context"); } compile_ctx->capture_errors = TRUE; parser = mrb_parse_nstring(mrb, script, script_length, compile_ctx); if (!parser) { mrbc_context_free(mrb, compile_ctx); mrb_raise(mrb, E_RUNTIME_ERROR, "[mruby][eval][compile] failed to allocate parser"); } if (parser->nerr > 0) { struct mrb_parser_message *error = &(parser->error_buffer[0]); mrb_value new_args[1]; mrb_value exception; new_args[0] = mrb_format(mrb, "line %S:%S: %S", mrb_fixnum_value(error->lineno), mrb_fixnum_value(error->column), mrb_str_new_cstr(mrb, error->message)); exception = mrb_obj_new(mrb, E_SYNTAX_ERROR, 1, new_args); mrb_parser_free(parser); mrbc_context_free(mrb, compile_ctx); mrb_exc_raise(mrb, exception); } proc = mrb_generate_code(mrb, parser); { mrb_code *iseq = proc->body.irep->iseq; while (GET_OPCODE(*iseq) != OP_STOP) { iseq++; } *iseq = MKOP_AB(OP_RETURN, 1, OP_R_NORMAL); } mrb_parser_free(parser); mrbc_context_free(mrb, compile_ctx); return mrb_obj_value(proc); }
static mrb_value mrb_file_s_rename(mrb_state *mrb, mrb_value obj) { mrb_value from, to; const char *src, *dst; mrb_get_args(mrb, "SS", &from, &to); src = mrb_string_value_cstr(mrb, &from); dst = mrb_string_value_cstr(mrb, &to); if (rename(src, dst) < 0) { if (CHMOD(dst, 0666) == 0 && UNLINK(dst) == 0 && rename(src, dst) == 0) { return mrb_fixnum_value(0); } mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to))); } return mrb_fixnum_value(0); }
int mrb_cloexec_open(mrb_state *mrb, const char *pathname, mrb_int flags, mrb_int mode) { mrb_value emsg; int fd, retry = FALSE; char* fname = mrb_locale_from_utf8(pathname, -1); #ifdef O_CLOEXEC /* O_CLOEXEC is available since Linux 2.6.23. Linux 2.6.18 silently ignore it. */ flags |= O_CLOEXEC; #elif defined O_NOINHERIT flags |= O_NOINHERIT; #endif reopen: fd = open(fname, (int)flags, (fmode_t)mode); if (fd == -1) { if (!retry) { switch (errno) { case ENFILE: case EMFILE: mrb_garbage_collect(mrb); retry = TRUE; goto reopen; } } emsg = mrb_format(mrb, "open %S", mrb_str_new_cstr(mrb, pathname)); mrb_str_modify(mrb, mrb_str_ptr(emsg)); mrb_sys_fail(mrb, RSTRING_PTR(emsg)); } mrb_locale_free(fname); if (fd <= 2) { mrb_fd_cloexec(mrb, fd); } return fd; }
static struct RProc* create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line) { mrbc_context *cxt; struct mrb_parser_state *p; struct RProc *proc; struct REnv *e; mrb_callinfo *ci = &mrb->c->ci[-1]; /* callinfo of eval caller */ struct RClass *target_class = NULL; int bidx; if (!mrb_nil_p(binding)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "Binding of eval must be nil."); } cxt = mrbc_context_new(mrb); cxt->lineno = (short)line; mrbc_filename(mrb, cxt, file ? file : "(eval)"); cxt->capture_errors = TRUE; cxt->no_optimize = TRUE; p = mrb_parse_nstring(mrb, s, len, cxt); /* only occur when memory ran out */ if (!p) { mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state."); } if (0 < p->nerr) { /* parse error */ mrb_value str; if (file) { str = mrb_format(mrb, " file %S line %S: %S", mrb_str_new_cstr(mrb, file), mrb_fixnum_value(p->error_buffer[0].lineno), mrb_str_new_cstr(mrb, p->error_buffer[0].message)); } else { str = mrb_format(mrb, " line %S: %S", mrb_fixnum_value(p->error_buffer[0].lineno), mrb_str_new_cstr(mrb, p->error_buffer[0].message)); } mrb_parser_free(p); mrbc_context_free(mrb, cxt); mrb_exc_raise(mrb, mrb_exc_new_str(mrb, E_SYNTAX_ERROR, str)); } proc = mrb_generate_code(mrb, p); if (proc == NULL) { /* codegen error */ mrb_parser_free(p); mrbc_context_free(mrb, cxt); mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error"); } target_class = MRB_PROC_TARGET_CLASS(ci->proc); if (!MRB_PROC_CFUNC_P(ci->proc)) { if (ci->env) { e = ci->env; } else { e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)target_class); e->mid = ci->mid; e->stack = ci[1].stackent; e->cxt = mrb->c; MRB_ENV_SET_STACK_LEN(e, ci->proc->body.irep->nlocals); bidx = ci->argc; if (ci->argc < 0) bidx = 2; else bidx += 1; MRB_ENV_SET_BIDX(e, bidx); ci->env = e; } proc->e.env = e; proc->flags |= MRB_PROC_ENVSET; mrb_field_write_barrier(mrb, (struct RBasic*)proc, (struct RBasic*)e); } proc->upper = ci->proc; mrb->c->ci->target_class = target_class; patch_irep(mrb, proc->body.irep, 0, proc->body.irep); /* mrb_codedump_all(mrb, proc); */ mrb_parser_free(p); mrbc_context_free(mrb, cxt); return proc; }