/* * call-seq: * int.next -> integer * int.succ -> integer * * Returns the <code>Integer</code> equal to <i>int</i> + 1. * * 1.next #=> 2 * (-1).next #=> 0 */ static mrb_value int_succ(mrb_state *mrb, mrb_value num) { if (mrb_fixnum_p(num)) return fix_succ(mrb, num); return mrb_funcall(mrb, num, "+", 1, mrb_fixnum_value(1)); }
static mrb_value find_file_check(mrb_state *mrb, mrb_value path, mrb_value fname, mrb_value ext) { FILE *fp; char fpath[MAXPATHLEN]; mrb_value filepath = mrb_str_dup(mrb, path); #ifdef _WIN32 if (RSTRING_PTR(fname)[1] == ':') { #else if (RSTRING_PTR(fname)[0] == '/') { #endif /* when absolute path */ mrb_funcall(mrb, filepath, "replace", 1, fname); } else { mrb_str_cat2(mrb, filepath, "/"); mrb_str_buf_append(mrb, filepath, fname); } if (!mrb_string_p(filepath)) { return mrb_nil_value(); } if (mrb_string_p(ext)) { mrb_str_buf_append(mrb, filepath, ext); } debug("filepath: %s\n", RSTRING_PTR(filepath)); if (realpath(RSTRING_PTR(filepath), fpath) == NULL) { return mrb_nil_value(); } debug("fpath: %s\n", fpath); fp = fopen(fpath, "r"); if (fp == NULL) { return mrb_nil_value(); } fclose(fp); return mrb_str_new_cstr(mrb, fpath); } static mrb_value find_file(mrb_state *mrb, mrb_value filename, int comp) { char *ext, *ptr, *tmp; mrb_value exts; int i, j; char *fname = RSTRING_PTR(filename); mrb_value filepath = mrb_nil_value(); mrb_value load_path = mrb_obj_dup(mrb, mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$:"))); load_path = mrb_check_array_type(mrb, load_path); if(mrb_nil_p(load_path)) { mrb_raise(mrb, E_RUNTIME_ERROR, "invalid $:"); return mrb_undef_value(); } tmp = ptr = fname; while (tmp) { if ((tmp = strchr(ptr, '/')) || (tmp = strchr(ptr, '\\'))) { ptr = tmp + 1; } } ext = strrchr(ptr, '.'); exts = mrb_ary_new(mrb); if (ext == NULL && comp) { mrb_ary_push(mrb, exts, mrb_str_new_cstr(mrb, ".rb")); mrb_ary_push(mrb, exts, mrb_str_new_cstr(mrb, ".mrb")); mrb_ary_push(mrb, exts, mrb_str_new_cstr(mrb, ".so")); } else { mrb_ary_push(mrb, exts, mrb_nil_value()); } /* when a filename start with '.', $: = ['.'] */ if (*fname == '.') { load_path = mrb_ary_new(mrb); mrb_ary_push(mrb, load_path, mrb_str_new_cstr(mrb, ".")); } for (i = 0; i < RARRAY_LEN(load_path); i++) { for (j = 0; j < RARRAY_LEN(exts); j++) { filepath = find_file_check( mrb, mrb_ary_entry(load_path, i), filename, mrb_ary_entry(exts, j)); if (!mrb_nil_p(filepath)) { return filepath; } } } mrb_load_fail(mrb, filename, "cannot load such file"); return mrb_nil_value(); }
static mrb_value mrb_grn_expr_code_inspect(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_expr_code *code; mrb_value inspected; code = DATA_PTR(self); inspected = mrb_str_buf_new(mrb, 48); mrb_str_cat_lit(mrb, inspected, "#<"); mrb_str_cat_cstr(mrb, inspected, mrb_obj_classname(mrb, self)); mrb_str_cat_lit(mrb, inspected, ":"); mrb_str_concat(mrb, inspected, mrb_ptr_to_str(mrb, mrb_cptr(self))); { int32_t weight; uint32_t offset; weight = grn_expr_code_get_weight(ctx, DATA_PTR(self), &offset); mrb_str_cat_lit(mrb, inspected, " weight="); mrb_str_concat(mrb, inspected, mrb_funcall(mrb, mrb_fixnum_value(weight), "inspect", 0)); mrb_str_cat_lit(mrb, inspected, ", offset="); mrb_str_concat(mrb, inspected, mrb_funcall(mrb, mrb_fixnum_value(offset), "inspect", 0)); } mrb_str_cat_lit(mrb, inspected, ", n_args="); mrb_str_concat(mrb, inspected, mrb_funcall(mrb, mrb_fixnum_value(code->nargs), "inspect", 0)); mrb_str_cat_lit(mrb, inspected, ", modify="); mrb_str_concat(mrb, inspected, mrb_funcall(mrb, mrb_fixnum_value(code->modify), "inspect", 0)); mrb_str_cat_lit(mrb, inspected, ", op="); mrb_str_concat(mrb, inspected, mrb_funcall(mrb, grn_mrb_value_from_operator(mrb, code->op), "inspect", 0)); mrb_str_cat_lit(mrb, inspected, ", flags="); mrb_str_concat(mrb, inspected, mrb_funcall(mrb, mrb_fixnum_value(code->flags), "inspect", 0)); mrb_str_cat_lit(mrb, inspected, ", value="); mrb_str_concat(mrb, inspected, mrb_funcall(mrb, grn_mrb_value_from_grn_obj(mrb, code->value), "inspect", 0)); mrb_str_cat_lit(mrb, inspected, ">"); return inspected; }
static mrb_value exc_message(mrb_state *mrb, mrb_value exc) { return mrb_funcall(mrb, exc, "to_s", 0); }
mrb_value mrb_exc_new3(mrb_state *mrb, struct RClass* c, mrb_value str) { mrb_string_value(mrb, &str); return mrb_funcall(mrb, mrb_obj_value(c), "new", 1, str); }
int main(int argc, char const *argv[]) { #ifdef _MEM_PROFILER uint8_t checkpoint_set = 0; #endif fd_set rfds; char buffer[PIPE_BUFFER_SIZE]; int i, n; Plugin plugins[MAX_PLUGINS]; int plugins_count = 0; mrb_state *mrb; mrb_value r_output, r_plugins_list; mrb_sym output_gv_sym, plugins_to_load_gv_sym; printf("Version: %s\n", PROBE_VERSION); if( argc != 2 ){ printf("Usage: %s <config_path>\n", argv[0]); exit(1); } #ifdef _MEM_PROFILER init_profiler(); #endif config_path = argv[1]; printf("Initializing core...\n"); mrb = mrb_open_allocf(profiler_allocf, "main"); output_gv_sym = mrb_intern_cstr(mrb, "$output"); plugins_to_load_gv_sym = mrb_intern_cstr(mrb, "$plugins_to_load"); setup_api(mrb); execute_file(mrb, "plugins/main.rb"); execute_file(mrb, config_path); printf("Loading plugins...\n"); r_plugins_list = mrb_gv_get(mrb, plugins_to_load_gv_sym); for(i = 0; i< mrb_ary_len(mrb, r_plugins_list); i++){ char *path, tmp[100]; int ssize; mrb_value r_plugin_name = mrb_ary_ref(mrb, r_plugins_list, i); const char *plugin_name = mrb_string_value_cstr(mrb, &r_plugin_name); snprintf(tmp, sizeof(tmp) - 1, "plugins/%s.rb", plugin_name); ssize = strlen(tmp); path = malloc(ssize + 1); strncpy(path, tmp, ssize); path[ssize] = '\0'; if( access(path, F_OK) == -1 ){ printf("cannot open plugin file \"%s\": %s\n", path, strerror(errno)); exit(1); } init_plugin_from_file(&plugins[plugins_count], path, plugin_name); plugins_count++; } printf("Instanciating output class...\n"); r_output = mrb_gv_get(mrb, output_gv_sym); interval = mrb_fixnum(mrb_funcall(mrb, r_output, "interval", 0)); printf("Interval set to %dms\n", (int)interval); printf("Sending initial report...\n"); mrb_funcall(mrb, r_output, "send_report", 0); if (mrb->exc) { mrb_print_error(mrb); exit(1); } // start all the threads for(i= 0; i< plugins_count; i++){ // printf("== plugin %d\n", i); n = pthread_create(&plugins[i].thread, NULL, plugin_thread, (void *)&plugins[i]); if( n < 0 ){ fprintf(stderr, "create failed\n"); } } if( signal(SIGINT, clean_exit) == SIG_ERR){ perror("signal"); exit(1); } while(running){ int fds[MAX_PLUGINS]; int maxfd = 0, ai; struct timeval tv; mrb_value r_buffer; struct timeval cycle_started_at, cycle_completed_at; gettimeofday(&cycle_started_at, NULL); bzero(fds, sizeof(int) * MAX_PLUGINS); // ask every plugin to send their data for(i= 0; i< plugins_count; i++){ strcpy(buffer, "request"); if( send(plugins[i].host_pipe, buffer, strlen(buffer), 0) == -1 ){ printf("send error when writing in pipe connected to plugin '%s'\n", plugins[i].name); } fds[i] = plugins[i].host_pipe; // printf("sent request to %d\n", i); } // printf("waiting answers...\n"); // and now wait for each answer while(1){ int left = 0; FD_ZERO(&rfds); for(i = 0; i< MAX_PLUGINS; i++){ if( fds[i] != NOPLUGIN_VALUE ){ FD_SET(fds[i], &rfds); left++; if( fds[i] > maxfd ) maxfd = fds[i]; } } // printf("left: %d %d\n", left, left <= 0); if( !running || (0 == left) ) break; // substract 20ms to stay below the loop delay fill_timeout(&tv, cycle_started_at, interval - 20); // printf("before select\n"); n = select(maxfd + 1, &rfds, NULL, NULL, &tv); // printf("after select: %d\n", n); if( n > 0 ){ // find out which pipes have data for(i = 0; i< MAX_PLUGINS; i++){ if( (fds[i] != NOPLUGIN_VALUE) && FD_ISSET(fds[i], &rfds) ){ while (1){ struct timeval answered_at; n = read(fds[i], buffer, sizeof(buffer)); if( n == -1 ){ if( errno != EAGAIN ) perror("read"); break; } if( n == PIPE_BUFFER_SIZE ){ printf("PIPE_BUFFER_SIZE is too small, increase it ! (value: %d)\n", PIPE_BUFFER_SIZE); continue; } gettimeofday(&answered_at, NULL); // printf("received answer from %s in %u ms\n", (const char *) plugins[i].mrb->ud, // (uint32_t)((answered_at.tv_sec - cycle_started_at.tv_sec) * 1000 + // (answered_at.tv_usec - cycle_started_at.tv_usec) / 1000) // ); buffer[n] = 0x00; ai = mrb_gc_arena_save(mrb); r_buffer = mrb_str_buf_new(mrb, n); mrb_str_buf_cat(mrb, r_buffer, buffer, n); // mrb_funcall(mrb, r_output, "tick", 0); mrb_funcall(mrb, r_output, "add", 1, r_buffer); check_exception("add", mrb); // pp(mrb, r_output, 0); mrb_gc_arena_restore(mrb, ai); } fds[i] = 0; } } } else if( n == 0 ) { printf("no responses received from %d plugins.\n", left); break; // timeout } else { perror("select"); } } int idx = mrb_gc_arena_save(mrb); mrb_funcall(mrb, r_output, "flush", 0); check_exception("flush", mrb); mrb_gc_arena_restore(mrb, idx); // and now sleep until the next cycle gettimeofday(&cycle_completed_at, NULL); #ifdef _MEM_PROFILER if( checkpoint_set ){ print_allocations(); } #endif // force a gc run at the end of each cycle mrb_full_gc(mrb); // printf("[main] capa: %d / %d\n", mrb->arena_idx, mrb->arena_capa); // for(i= 0; i< plugins_count; i++){ // printf("[%s] capa: %d / %d\n", plugins[i].name, plugins[i].mrb->arena_idx, plugins[i].mrb->arena_capa); // } #ifdef _MEM_PROFILER checkpoint_set = 1; // and set starting point profiler_set_checkpoint(); #endif #ifdef _MEM_PROFILER_RUBY // dump VMS state dump_state(mrb); for(i= 0; i< plugins_count; i++){ dump_state(plugins[i].mrb); } #endif fflush(stdout); sleep_delay(&cycle_started_at, &cycle_completed_at, interval); } printf("Sending exit signal to all plugins...\n"); strcpy(buffer, "exit"); for(i= 0; i< plugins_count; i++){ C_CHECK("send", send(plugins[i].host_pipe, buffer, strlen(buffer), 0) ); } printf("Giving some time for threads to exit...\n\n"); really_sleep(2000); for(i= 0; i< plugins_count; i++){ int ret = pthread_kill(plugins[i].thread, 0); // if a success is returned then the thread is still alive // which means the thread did not acknoledged the exit message // kill it. if( ret == 0 ){ printf(" - plugin \"%s\" failed to exit properly, killing it...\n", (const char *) plugins[i].mrb->ud); pthread_cancel(plugins[i].thread); } else { printf(" - plugin \"%s\" exited properly.\n", (const char *) plugins[i].mrb->allocf_ud); } if( pthread_join(plugins[i].thread, NULL) < 0){ fprintf(stderr, "join failed\n"); } mrb_close(plugins[i].mrb); } mrb_close(mrb); printf("Exited !\n"); return 0; }
MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj) { return mrb_obj_as_string(mrb, mrb_funcall(mrb, obj, "inspect", 0)); }
static mrb_value ngx_mrb_get_conn_var_server_port(mrb_state *mrb, mrb_value self) { return mrb_funcall(mrb, ngx_mrb_get_request_var(mrb, self), "server_port", 0, NULL); }
static mrb_value num_equal(mrb_state *mrb, mrb_value x, mrb_value y) { if (mrb_obj_equal(mrb, x, y)) return mrb_true_value(); return mrb_funcall(mrb, y, "==", 1, x); }
mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str) { str = mrb_str_to_str(mrb, str); return mrb_funcall(mrb, mrb_obj_value(c), "new", 1, str); }
static mrb_value ngx_mrb_get_conn_var_remote_addr(mrb_state *mrb, mrb_value self) { return mrb_funcall(mrb, ngx_mrb_get_request_var(mrb, self), "remote_addr", 0, NULL); }
int mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2) { return RTEST(mrb_funcall(mrb, obj1, "eql?", 1, obj2)); }
int main(int argc, char *argv[]) { mrb_value s; FILE *fp; DIR *dp; struct dirent *dirst; mrb_state *mrb = mrb_open(); glmrb_sprite_init(mrb); glmrb_input_init(mrb); dp = opendir("./lib"); while((dirst = readdir(dp)) != NULL) { char buf[256]; if (dirst->d_name[0] == '.') continue; strcpy(buf, "./lib/"); strcat(buf, dirst->d_name); fp = fopen(buf, "r"); mrb_load_file(mrb, fp); fclose(fp); } closedir(dp); fp = fopen("main.rb", "r"); s = mrb_load_file(mrb, fp); fclose(fp); /* SDL初期化 */ if (SDL_Init(SDL_INIT_VIDEO) < 0 ) { exit(-1); } /* フレームバッファ作成 */ mWIN = SDL_SetVideoMode(640, 480, 0, 0); if (!mWIN) { SDL_Quit(); exit(-1); } /* キャプション設定 */ SDL_WM_SetCaption("glmruby application",NULL); /* メインループ */ while(quits() != 0) { mrb_funcall(mrb, s, "update", 0); /* 画面消去 */ SDL_FillRect(mWIN, NULL, SDL_MapRGB(mWIN->format, 0, 0, 0)); mrb_funcall(mrb, s, "draw", 0); /* ウェイト処理 */ timer.now = SDL_GetTicks(); timer.wit = timer.now - timer.lev; if (timer.wit < 16) SDL_Delay(16 - timer.wit); timer.lev = SDL_GetTicks(); /* 画面更新 */ SDL_UpdateRect(mWIN, 0, 0, 0, 0); } /* 終了処理 */ SDL_Quit(); return 0; }
/********************************************************* * main *********************************************************/ static mrb_value mrb_value_to_string(mrb_state* mrb, mrb_value value) { mrb_value str; if (mrb_nil_p(value)) { return mrb_str_new_cstr(mrb, "null"); } switch (mrb_type(value)) { case MRB_TT_FIXNUM: case MRB_TT_FLOAT: case MRB_TT_TRUE: case MRB_TT_FALSE: case MRB_TT_UNDEF: str = mrb_funcall(mrb, value, "to_s", 0, NULL); break; case MRB_TT_SYMBOL: value = mrb_funcall(mrb, value, "to_s", 0, NULL); /* FALLTHROUGH */ case MRB_TT_STRING: { int ai = mrb_gc_arena_save(mrb); char* ptr = RSTRING_PTR(value); char* end = RSTRING_END(value); str = mrb_str_new_cstr(mrb, "\""); while (ptr < end && *ptr) { switch (*ptr) { case '\\': str = mrb_str_cat_cstr(mrb, str, "\\\\"); break; case '"': str = mrb_str_cat_cstr(mrb, str, "\\\""); break; case '\b': str = mrb_str_cat_cstr(mrb, str, "\\b"); break; case '\f': str = mrb_str_cat_cstr(mrb, str, "\\f"); break; case '\n': str = mrb_str_cat_cstr(mrb, str, "\\n"); break; case '\r': str = mrb_str_cat_cstr(mrb, str, "\\r"); break; case '\t': str = mrb_str_cat_cstr(mrb, str, "\\t"); break; default: // TODO: handle unicode str = mrb_str_cat(mrb, str, ptr, 1); } ptr++; } mrb_str_cat_cstr(mrb, str, "\""); mrb_gc_arena_restore(mrb, ai); } break; case MRB_TT_HASH: { mrb_value keys; int n, l; str = mrb_str_new_cstr(mrb, "{"); keys = mrb_hash_keys(mrb, value); l = RARRAY_LEN(keys); for (n = 0; n < l; n++) { mrb_value obj; int ai = mrb_gc_arena_save(mrb); mrb_value key = mrb_ary_entry(keys, n); mrb_value enckey = mrb_funcall(mrb, key, "to_s", 0, NULL); enckey = mrb_funcall(mrb, enckey, "inspect", 0, NULL); mrb_str_concat(mrb, str, enckey); mrb_str_cat_cstr(mrb, str, ":"); obj = mrb_hash_get(mrb, value, key); mrb_str_concat(mrb, str, mrb_value_to_string(mrb, obj)); if (n != l - 1) { mrb_str_cat_cstr(mrb, str, ","); } mrb_gc_arena_restore(mrb, ai); } mrb_str_cat_cstr(mrb, str, "}"); break; } case MRB_TT_ARRAY: { int n, l; str = mrb_str_new_cstr(mrb, "["); l = RARRAY_LEN(value); for (n = 0; n < l; n++) { int ai = mrb_gc_arena_save(mrb); mrb_value obj = mrb_ary_entry(value, n); mrb_str_concat(mrb, str, mrb_value_to_string(mrb, obj)); if (n != l - 1) { mrb_str_cat_cstr(mrb, str, ","); } mrb_gc_arena_restore(mrb, ai); } mrb_str_cat_cstr(mrb, str, "]"); break; } default: mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } return str; }
static mrb_value ngx_mrb_get_server_var_realpath_root(mrb_state *mrb, mrb_value self) { return mrb_funcall(mrb, ngx_mrb_get_request_var(mrb, self), "realpath_root", 0, NULL); }
static mrb_value http_request_method(mrb_state *mrb, mrb_value self) { h2o_mruby_generator_t *generator; struct st_h2o_mruby_http_request_context_t *ctx; const char *arg_url; mrb_int arg_url_len; mrb_value arg_hash; h2o_iovec_t method; h2o_url_t url; /* parse args */ arg_hash = mrb_nil_value(); mrb_get_args(mrb, "s|H", &arg_url, &arg_url_len, &arg_hash); /* precond check */ if ((generator = h2o_mruby_current_generator) == NULL || generator->req == NULL) mrb_exc_raise(mrb, create_downstream_closed_exception(mrb)); /* allocate context and initialize */ ctx = h2o_mem_alloc_shared(&generator->req->pool, sizeof(*ctx), on_dispose); memset(ctx, 0, sizeof(*ctx)); ctx->generator = generator; ctx->receiver = mrb_nil_value(); h2o_buffer_init(&ctx->req.buf, &h2o_socket_buffer_prototype); h2o_buffer_init(&ctx->resp.after_closed, &h2o_socket_buffer_prototype); ctx->refs.request = mrb_nil_value(); ctx->refs.input_stream = mrb_nil_value(); /* uri */ if (h2o_url_parse(arg_url, arg_url_len, &url) != 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "invaild URL"); /* method */ method = h2o_iovec_init(H2O_STRLIT("GET")); if (mrb_hash_p(arg_hash)) { mrb_value t = mrb_hash_get(mrb, arg_hash, mrb_symbol_value(generator->ctx->symbols.sym_method)); if (!mrb_nil_p(t)) { t = mrb_str_to_str(mrb, t); method = h2o_iovec_init(RSTRING_PTR(t), RSTRING_LEN(t)); } } /* start building the request */ h2o_buffer_reserve(&ctx->req.buf, method.len + 1); append_to_buffer(&ctx->req.buf, method.base, method.len); append_to_buffer(&ctx->req.buf, H2O_STRLIT(" ")); h2o_buffer_reserve(&ctx->req.buf, url.path.len + url.authority.len + sizeof(" HTTP/1.1\r\nConnection: close\r\nHost: \r\n") - 1); append_to_buffer(&ctx->req.buf, url.path.base, url.path.len); append_to_buffer(&ctx->req.buf, H2O_STRLIT(" HTTP/1.1\r\nConnection: close\r\nHost: ")); append_to_buffer(&ctx->req.buf, url.authority.base, url.authority.len); append_to_buffer(&ctx->req.buf, H2O_STRLIT("\r\n")); /* headers */ if (mrb_hash_p(arg_hash)) { mrb_value headers = mrb_hash_get(mrb, arg_hash, mrb_symbol_value(generator->ctx->symbols.sym_headers)); if (!mrb_nil_p(headers)) { if (h2o_mruby_iterate_headers(generator->ctx, headers, flatten_request_header, ctx) != 0) { mrb_value exc = mrb_obj_value(mrb->exc); mrb->exc = NULL; mrb_exc_raise(mrb, exc); } } } /* body */ if (mrb_hash_p(arg_hash)) { mrb_value body = mrb_hash_get(mrb, arg_hash, mrb_symbol_value(generator->ctx->symbols.sym_body)); if (!mrb_nil_p(body)) { if (mrb_obj_eq(mrb, body, generator->rack_input)) { /* fast path */ mrb_int pos; mrb_input_stream_get_data(mrb, body, NULL, NULL, &pos, NULL, NULL); ctx->req.body = generator->req->entity; ctx->req.body.base += pos; ctx->req.body.len -= pos; } else { if (!mrb_string_p(body)) { body = mrb_funcall(mrb, body, "read", 0); if (!mrb_string_p(body)) mrb_raise(mrb, E_ARGUMENT_ERROR, "body.read did not return string"); } ctx->req.body = h2o_strdup(&ctx->generator->req->pool, RSTRING_PTR(body), RSTRING_LEN(body)); } if (!ctx->req.has_transfer_encoding) { char buf[64]; size_t l = (size_t)sprintf(buf, "content-length: %zu\r\n", ctx->req.body.len); h2o_buffer_reserve(&ctx->req.buf, l); append_to_buffer(&ctx->req.buf, buf, l); } } } h2o_buffer_reserve(&ctx->req.buf, 2); append_to_buffer(&ctx->req.buf, H2O_STRLIT("\r\n")); /* build request and connect */ h2o_http1client_connect(&ctx->client, ctx, &generator->req->conn->ctx->proxy.client_ctx, url.host, h2o_url_get_port(&url), on_connect); ctx->refs.request = h2o_mruby_create_data_instance(mrb, mrb_ary_entry(generator->ctx->constants, H2O_MRUBY_HTTP_REQUEST_CLASS), ctx, &request_type); return ctx->refs.request; }
static mrb_value sysctl_net_list(mrb_state *mrb, mrb_value self) { const char *ifname = NULL; struct ifaddrs *addrs, *curr; mrb_value r_ret; struct RClass *if_class = mrb_class_get(mrb, "NetworkAddress"); mrb_get_args(mrb, "|z", &ifname); if( getifaddrs(&addrs) == -1 ){ mrb_raisef(mrb, E_RUNTIME_ERROR, "getifaddrs: %S", mrb_str_new_cstr(mrb, strerror(errno))); goto ret; } if( ifname ){ r_ret = mrb_ary_new(mrb); } else { r_ret = mrb_hash_new(mrb); } curr = addrs; while( curr != NULL ){ char addr[INET6_ADDRSTRLEN]; char netmask[INET6_ADDRSTRLEN]; if( curr->ifa_netmask != NULL ){ mrb_value r_key, r_addr, r_list; // only return wanted infos if( !ifname || !strcmp(ifname, curr->ifa_name) ){ if( sockaddr_to_string(curr->ifa_addr, addr, sizeof(addr)) == -1) continue; if( sockaddr_to_string(curr->ifa_netmask, netmask, sizeof(netmask)) == -1) continue; r_key = mrb_str_new_cstr(mrb, curr->ifa_name); r_addr = mrb_funcall(mrb, mrb_obj_value(if_class), "new", 2, mrb_str_new_cstr(mrb, addr), mrb_str_new_cstr(mrb, netmask) ); if( ifname ){ mrb_ary_push(mrb, r_ret, r_addr); } else { // check if key exists r_list = mrb_hash_get(mrb, r_ret, r_key); if( mrb_nil_p(r_list) ){ r_list = mrb_ary_new(mrb); } mrb_ary_push(mrb, r_list, r_addr); mrb_hash_set(mrb, r_ret, r_key, r_list); } } } curr = curr->ifa_next; } ret: return r_ret; }
static mrb_value mrb_grn_table_cursor_class_open_raw(mrb_state *mrb, mrb_value klass) { grn_ctx *ctx = (grn_ctx *)mrb->ud; mrb_value mrb_table; mrb_value mrb_options = mrb_nil_value(); grn_table_cursor *table_cursor; grn_obj *table; void *min = NULL; unsigned int min_size = 0; grn_mrb_value_to_raw_data_buffer min_buffer; void *max = NULL; unsigned int max_size = 0; grn_mrb_value_to_raw_data_buffer max_buffer; int offset = 0; int limit = -1; int flags = 0; mrb_get_args(mrb, "o|H", &mrb_table, &mrb_options); table = DATA_PTR(mrb_table); grn_mrb_value_to_raw_data_buffer_init(mrb, &min_buffer); grn_mrb_value_to_raw_data_buffer_init(mrb, &max_buffer); if (!mrb_nil_p(mrb_options)) { grn_id key_domain_id; mrb_value mrb_min; mrb_value mrb_max; mrb_value mrb_flags; if (table->header.type == GRN_DB) { key_domain_id = GRN_DB_SHORT_TEXT; } else { key_domain_id = table->header.domain; } mrb_min = grn_mrb_options_get_lit(mrb, mrb_options, "min"); grn_mrb_value_to_raw_data(mrb, "min", mrb_min, key_domain_id, &min_buffer, &min, &min_size); mrb_max = grn_mrb_options_get_lit(mrb, mrb_options, "max"); grn_mrb_value_to_raw_data(mrb, "max", mrb_max, key_domain_id, &max_buffer, &max, &max_size); mrb_flags = grn_mrb_options_get_lit(mrb, mrb_options, "flags"); if (!mrb_nil_p(mrb_flags)) { flags = mrb_fixnum(mrb_flags); } } table_cursor = grn_table_cursor_open(ctx, table, min, min_size, max, max_size, offset, limit, flags); grn_mrb_value_to_raw_data_buffer_fin(mrb, &min_buffer); grn_mrb_value_to_raw_data_buffer_fin(mrb, &max_buffer); grn_mrb_ctx_check(mrb); { mrb_value mrb_table_cursor; mrb_table_cursor = mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, table_cursor)); mrb_iv_set(mrb, mrb_table_cursor, mrb_intern_lit(mrb, "@table"), mrb_table); return mrb_table_cursor; } }
static mrb_value mrb_curl_send(mrb_state *mrb, mrb_value self) { char error[CURL_ERROR_SIZE] = {0}; CURL* curl; CURLcode res = CURLE_OK; MEMFILE* mf; struct RClass* _class_curl; int ssl_verifypeer; struct curl_slist* headerlist = NULL; mrb_value body; mrb_value method; mrb_value _class_http_request; mrb_value name; mrb_value headers; mrb_value str; struct RClass* _class_http; struct RClass* _class_http_parser; mrb_value parser; mrb_value args[1]; mrb_value url = mrb_nil_value(); mrb_value req = mrb_nil_value(); mrb_value b = mrb_nil_value(); mrb_get_args(mrb, "So&", &url, &req, &b); _class_http_request = mrb_funcall(mrb, req, "class", 0, NULL); name = mrb_funcall(mrb, _class_http_request, "to_s", 0, NULL); if (strcmp(RSTRING_PTR(name), "HTTP::Request")) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } mf = memfopen(); curl = curl_easy_init(); _class_curl = mrb_class_get(mrb, "Curl"); ssl_verifypeer = mrb_fixnum(mrb_const_get(mrb, mrb_obj_value(_class_curl), mrb_intern_cstr(mrb, "SSL_VERIFYPEER"))); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, ssl_verifypeer); curl_easy_setopt(curl, CURLOPT_URL, RSTRING_PTR(url)); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error); method = mrb_funcall(mrb, req, "method", 0, NULL); if (strcmp("GET", RSTRING_PTR(method))) { curl_easy_setopt(curl, CURLOPT_POST, 1); body = mrb_funcall(mrb, req, "body", 0, NULL); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, RSTRING_PTR(body)); } curl_easy_setopt(curl, CURLOPT_WRITEDATA, mf); if (mrb_nil_p(b)) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite); } else { mf->mrb = mrb; mf->proc = b; mf->header = mrb_nil_value(); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite_callback); } curl_easy_setopt(curl, CURLOPT_HEADERDATA, mf); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, memfwrite); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 0); headers = mrb_funcall(mrb, req, "headers", 0, NULL); if (!mrb_nil_p(headers)) { mrb_value keys = mrb_hash_keys(mrb, headers); int i, l = RARRAY_LEN(keys); for (i = 0; i < l; i++) { mrb_value key = mrb_ary_entry(keys, i); mrb_value header = mrb_str_dup(mrb, key); mrb_str_cat2(mrb, header, ": "); mrb_str_concat(mrb, header, mrb_hash_get(mrb, headers, key)); headerlist = curl_slist_append(headerlist, RSTRING_PTR(header)); } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); } res = curl_easy_perform(curl); if (headerlist) curl_slist_free_all(headerlist); curl_easy_cleanup(curl); if (res != CURLE_OK) { mrb_raise(mrb, E_RUNTIME_ERROR, error); } if (!mrb_nil_p(b)) { return mrb_nil_value(); } str = mrb_str_new(mrb, mf->data, mf->size); memfclose(mf); _class_http = mrb_class_get(mrb, "HTTP"); _class_http_parser = mrb_class_ptr(mrb_const_get(mrb, mrb_obj_value(_class_http), mrb_intern_cstr(mrb, "Parser"))); parser = mrb_obj_new(mrb, _class_http_parser, 0, NULL); args[0] = str; return mrb_funcall_argv(mrb, parser, mrb_intern_cstr(mrb, "parse_response"), 1, args); }
mrb_value mruby::make_call(mrb_state* mrb, mrb_value self, const char* fnname) { return mrb_funcall(mrb, self, fnname, 0); }
MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2) { if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE; return mrb_test(mrb_funcall(mrb, obj1, "eql?", 1, obj2)); }
// like Nginx rewrite keywords // used like this: // => http code 3xx location in browser // => internal redirection in nginx static mrb_value ngx_mrb_redirect(mrb_state *mrb, mrb_value self) { int argc; u_char *str; ngx_int_t rc; mrb_value uri, code; ngx_str_t ns; ngx_table_elt_t *location; ngx_http_request_t *r = ngx_mrb_get_request(); argc = mrb_get_args(mrb, "o|oo", &uri, &code); // get status code from args if (argc == 2) { rc = mrb_fixnum(code); } else { rc = NGX_HTTP_MOVED_TEMPORARILY; } // get redirect uri from args if (mrb_type(uri) != MRB_TT_STRING) { uri = mrb_funcall(mrb, uri, "to_s", 0, NULL); } // save location uri to ns ns.len = RSTRING_LEN(uri); if (ns.len == 0) { return mrb_nil_value(); } ns.data = ngx_palloc(r->pool, ns.len); ngx_memcpy(ns.data, RSTRING_PTR(uri), ns.len); // if uri start with scheme prefix // return 3xx for redirect // else generate a internal redirection and response to raw request // request.path is not changed if (ngx_strncmp(ns.data, "http://", sizeof("http://") - 1) == 0 || ngx_strncmp(ns.data, "https://", sizeof("https://") - 1) == 0 || ngx_strncmp(ns.data, "$scheme", sizeof("$scheme") - 1) == 0) { str = ngx_pstrdup(r->pool, &ns); if (str == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } str[ns.len] = '\0'; // build redirect location location = ngx_list_push(&r->headers_out.headers); if (location == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } location->hash = 1; ngx_str_set(&location->key, "Location"); location->value = ns; location->lowcase_key = ngx_pnalloc(r->pool, location->value.len); if (location->lowcase_key == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } ngx_strlow(location->lowcase_key, location->value.data, location->value.len); // set location and response code for hreaders r->headers_out.location = location; r->headers_out.status = rc; } else { ngx_http_internal_redirect(r, &ns, &r->args); ngx_http_finalize_request(r, NGX_DONE); } return self; }
mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, long len) { return mrb_funcall(mrb, mrb_obj_value(c), "new", 1, mrb_str_new(mrb, ptr, len)); }
static mrb_value ngx_mrb_rputs(mrb_state *mrb, mrb_value self) { mrb_value argv; ngx_buf_t *b; ngx_mrb_rputs_chain_list_t *chain; u_char *str; ngx_str_t ns; ngx_http_request_t *r = ngx_mrb_get_request(); ngx_http_mruby_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_mruby_module); mrb_get_args(mrb, "o", &argv); if (mrb_type(argv) != MRB_TT_STRING) { argv = mrb_funcall(mrb, argv, "to_s", 0, NULL); } ns.data = (u_char *)RSTRING_PTR(argv); ns.len = RSTRING_LEN(argv); if (ns.len == 0) { return self; } if (ctx->rputs_chain == NULL) { chain = ngx_pcalloc(r->pool, sizeof(ngx_mrb_rputs_chain_list_t)); if (chain == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } chain->out = ngx_alloc_chain_link(r->pool); if (chain->out == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } chain->last = &chain->out; } else { chain = ctx->rputs_chain; (*chain->last)->next = ngx_alloc_chain_link(r->pool); if ((*chain->last)->next == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } chain->last = &(*chain->last)->next; } b = ngx_calloc_buf(r->pool); if (b == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } (*chain->last)->buf = b; (*chain->last)->next = NULL; str = ngx_pstrdup(r->pool, &ns); if (str == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } str[ns.len] = '\0'; (*chain->last)->buf->pos = str; (*chain->last)->buf->last = str + ns.len; (*chain->last)->buf->memory = 1; ctx->rputs_chain = chain; ngx_http_set_ctx(r, ctx, ngx_http_mruby_module); if (r->headers_out.content_length_n == -1) { r->headers_out.content_length_n += ns.len + 1; } else { r->headers_out.content_length_n += ns.len; } return self; }
static void set_backtrace(mrb_state *mrb, mrb_value info, mrb_value bt) { mrb_funcall(mrb, info, "set_backtrace", 1, bt); }
void dump_state(mrb_state *mrb) { mrb_full_gc(mrb); printf("\nVM: %s\n", (const char *)mrb->ud); mrb_funcall(mrb, mrb_obj_value(mrb->top_self), "print_memory_state", 0); }
/* :nodoc: */ static double double_value(mrb_state *mrb, mrb_value i) { return mrb_nil_p(i) ? 0.0 : mrb_float(mrb_funcall(mrb, i, "to_f", 0)); }
mrb_value regexp_pcre_match(mrb_state *mrb, mrb_value self) { struct mrb_matchdata *mrb_md; int rc; int ccount, matchlen; int *match; struct RClass *c; mrb_value md, str; mrb_int i, pos; pcre_extra extra; struct mrb_regexp_pcre *reg; reg = (struct mrb_regexp_pcre *)mrb_get_datatype(mrb, self, &mrb_regexp_type); if (!reg) return mrb_nil_value(); pos = 0; mrb_get_args(mrb, "S|i", &str, &pos); // XXX: RSTRING_LEN(str) >= pos ... rc = pcre_fullinfo(reg->re, NULL, PCRE_INFO_CAPTURECOUNT, &ccount); if (rc < 0) { /* fullinfo error */ return mrb_nil_value(); } matchlen = ccount + 1; match = mrb_malloc(mrb, sizeof(int) * matchlen * 3); extra.flags = PCRE_EXTRA_MATCH_LIMIT_RECURSION; extra.match_limit_recursion = 1000; rc = pcre_exec(reg->re, &extra, RSTRING_PTR(str), RSTRING_LEN(str), pos, 0, match, matchlen * 3); if (rc < 0) { mrb_free(mrb, match); return mrb_nil_value(); } /* XXX: need current scope */ mrb_obj_iv_set(mrb, (struct RObject *)mrb_class_real(RDATA(self)->c), mrb_intern_lit(mrb, "@last_match"), mrb_nil_value()); c = mrb_class_get(mrb, "MatchData"); md = mrb_funcall(mrb, mrb_obj_value(c), "new", 0); mrb_md = (struct mrb_matchdata *)mrb_get_datatype(mrb, md, &mrb_matchdata_type); mrb_md->ovector = match; mrb_md->length = matchlen; mrb_iv_set(mrb, md, mrb_intern_lit(mrb, "@regexp"), self); mrb_iv_set(mrb, md, mrb_intern_lit(mrb, "@string"), mrb_str_dup(mrb, str)); /* XXX: need current scope */ mrb_obj_iv_set(mrb, (struct RObject *)mrb_class_real(RDATA(self)->c), mrb_intern_lit(mrb, "@last_match"), md); mrb_gv_set(mrb, mrb_intern_lit(mrb, "$~"), md); mrb_gv_set(mrb, mrb_intern_lit(mrb, "$&"), mrb_funcall(mrb, md, "to_s", 0)); mrb_gv_set(mrb, mrb_intern_lit(mrb, "$`"), mrb_funcall(mrb, md, "pre_match", 0)); mrb_gv_set(mrb, mrb_intern_lit(mrb, "$'"), mrb_funcall(mrb, md, "post_match", 0)); for (i = 1; i < 10; i++) { char sym[8]; snprintf(sym, sizeof(sym), "$%d", i); mrb_gv_set(mrb, mrb_intern_cstr(mrb, sym), mrb_funcall(mrb, md, "[]", 1, mrb_fixnum_value(i))); } return md; }
static mrb_value mrb_grn_expression_append_constant(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *expr; mrb_value mrb_constant; mrb_value mrb_op; grn_operator op; mrb_int n_args; expr = DATA_PTR(self); mrb_get_args(mrb, "ooi", &mrb_constant, &mrb_op, &n_args); op = grn_mrb_value_to_operator(mrb, mrb_op); switch (mrb_type(mrb_constant)) { case MRB_TT_FALSE : if (mrb_nil_p(mrb_constant)) { grn_obj constant; GRN_VOID_INIT(&constant); grn_expr_append_const(ctx, expr, &constant, op, n_args); GRN_OBJ_FIN(ctx, &constant); } else { grn_obj constant; GRN_BOOL_INIT(&constant, 0); GRN_BOOL_SET(ctx, &constant, GRN_FALSE); grn_expr_append_const(ctx, expr, &constant, op, n_args); GRN_OBJ_FIN(ctx, &constant); } break; case MRB_TT_TRUE : { grn_obj constant; GRN_BOOL_INIT(&constant, 0); GRN_BOOL_SET(ctx, &constant, GRN_TRUE); grn_expr_append_const(ctx, expr, &constant, op, n_args); GRN_OBJ_FIN(ctx, &constant); } break; case MRB_TT_FIXNUM : grn_expr_append_const_int(ctx, expr, mrb_fixnum(mrb_constant), op, n_args); break; case MRB_TT_SYMBOL : { const char *value; mrb_int value_length; value = mrb_sym2name_len(mrb, mrb_symbol(mrb_constant), &value_length); grn_expr_append_const_str(ctx, expr, value, value_length, op, n_args); } break; case MRB_TT_FLOAT : { grn_obj constant; GRN_FLOAT_INIT(&constant, 0); GRN_FLOAT_SET(ctx, &constant, mrb_float(mrb_constant)); grn_expr_append_const(ctx, expr, &constant, op, n_args); GRN_OBJ_FIN(ctx, &constant); } break; case MRB_TT_STRING : grn_expr_append_const_str(ctx, expr, RSTRING_PTR(mrb_constant), RSTRING_LEN(mrb_constant), op, n_args); break; default : { struct RClass *klass; klass = mrb_class(mrb, mrb_constant); if (klass == ctx->impl->mrb.builtin.time_class) { grn_obj constant; mrb_value mrb_sec; mrb_value mrb_usec; mrb_sec = mrb_funcall(mrb, mrb_constant, "to_i", 0); mrb_usec = mrb_funcall(mrb, mrb_constant, "usec", 0); GRN_TIME_INIT(&constant, 0); GRN_TIME_SET(ctx, &constant, GRN_TIME_PACK(mrb_fixnum(mrb_sec), mrb_fixnum(mrb_usec))); grn_expr_append_const(ctx, expr, &constant, op, n_args); GRN_OBJ_FIN(ctx, &constant); } else { mrb_raisef(mrb, E_ARGUMENT_ERROR, "unsupported constant to append to expression: %S", mrb_constant); } } break; } grn_mrb_ctx_check(mrb); return mrb_nil_value(); }
static std::string return_inspect(mrb_state *mrb, mrb_value obj) { obj = mrb_funcall(mrb, obj, "inspect", 0); return std::string(RSTRING_PTR(obj)); }