From 6477c7b30d2ee4a622b9cdec8058842767c953fd Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Thu, 28 Nov 2019 15:50:48 +0900 Subject: [PATCH 01/13] [WIP] Updates for libuv-1.33 --- .travis.yml | 3 + .travis_config.rb | 17 +++- mrbgem.rake | 6 +- src/fs.c | 204 +++++++++++++++++++++++++++++++++++++++ src/handle.c | 236 +++++++++++++++++++++++++++++++++++++--------- src/mrb_uv.c | 168 +++++++++++++++++++++++++++++++++ src/mrb_uv.h | 2 + src/thread.c | 22 ++++- 8 files changed, 604 insertions(+), 54 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3847529..70df634 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,9 @@ env: - MRUBY_VERSION=1.2.0 - MRUBY_VERSION=1.3.0 - MRUBY_VERSION=1.4.0 + - MRUBY_VERSION=1.4.0 + - MRUBY_VERSION=2.0.0 + - MRUBY_VERSION=2.1.0 before_script: # Add an IPv6 config - see the corresponding Travis issue # https://github.com/travis-ci/travis-ci/issues/8361 diff --git a/.travis_config.rb b/.travis_config.rb index 236ef40..332170b 100644 --- a/.travis_config.rb +++ b/.travis_config.rb @@ -6,5 +6,20 @@ gem :core => 'mruby-print' gem :core => 'mruby-sprintf' gem :core => 'mruby-time' - gem "#{MRUBY_ROOT}/.." + gem "#{MRUBY_ROOT}/.." do |c| + c.bundle_onigmo + end +end + +MRuby::Build.new('libuv-v1.0.0') do |conf| + toolchain :gcc + enable_debug + enable_test + + gem :core => 'mruby-print' + gem :core => 'mruby-sprintf' + gem :core => 'mruby-time' + gem "#{MRUBY_ROOT}/.." do |c| + c.bundle_onigmo '1.0.0' + end end diff --git a/mrbgem.rake b/mrbgem.rake index c89d0f0..761387c 100644 --- a/mrbgem.rake +++ b/mrbgem.rake @@ -13,11 +13,11 @@ MRuby::Gem::Specification.new('mruby-uv') do |spec| def cross?; build.kind_of? MRuby::CrossBuild end - def self.bundle_uv + DEFAULT_UV_VERSION = '1.33.1' + + def self.bundle_uv(version = DEFAULT_UV_VERSION) visualcpp = ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] - # version = '1.0.0' - version = '1.19.1' libuv_dir = "#{build_dir}/libuv-#{version}" libuv_lib = libfile "#{libuv_dir}/.libs/libuv" header = "#{libuv_dir}/include/uv.h" diff --git a/src/fs.c b/src/fs.c index 70f6865..caef875 100644 --- a/src/fs.c +++ b/src/fs.c @@ -102,6 +102,53 @@ mrb_uv_to_fd(mrb_state *mrb, mrb_value v) return ((mrb_uv_file*)mrb_uv_get_ptr(mrb, v, &mrb_uv_file_type))->fd; } +#if MRB_UV_CHECK_VERSION(1, 28, 0) + +static void +mrb_uv_dir_free(mrb_state *mrb, void *p) +{ + uv_fs_t req; + uv_dir_t *dir = (uv_dir_t*)p; + if (!dir) { + return; + } + mrb_uv_check_error(mrb, uv_fs_closedir(uv_default_loop(), &req, dir, NULL)); +} + +static mrb_data_type const mrb_uv_dir_type = { + "UV::Dir", mrb_uv_dir_free, +}; + +static mrb_value +dir_to_mrb(mrb_state *mrb, uv_dir_t *dir) +{ + struct RClass *dir_cls = mrb_class_get_under(mrb, mrb_module_get(mrb, "UV"), "Dir"); + mrb_value ret = mrb_obj_value(mrb_obj_alloc(mrb, MRB_TT_DATA, dir_cls)); + DATA_PTR(ret) = dir; + DATA_TYPE(ret) = &mrb_uv_dir_type; + return ret; +} + +#endif + +#if MRB_UV_CHECK_VERSION(1, 31, 0) + +static mrb_value +statfs_to_mrb(mrb_state *mrb, const uv_statfs_t *stat) +{ + mrb_value ret = mrb_hash_new(mrb); + mrb_hash_set(mrb, ret, mrb_symbol_value(mrb_intern_lit(mrb, "type")), mrb_uv_from_uint64(mrb, stat->f_type)); + mrb_hash_set(mrb, ret, mrb_symbol_value(mrb_intern_lit(mrb, "bsize")), mrb_uv_from_uint64(mrb, stat->f_bsize)); + mrb_hash_set(mrb, ret, mrb_symbol_value(mrb_intern_lit(mrb, "blocks")), mrb_uv_from_uint64(mrb, stat->f_blocks)); + mrb_hash_set(mrb, ret, mrb_symbol_value(mrb_intern_lit(mrb, "bfree")), mrb_uv_from_uint64(mrb, stat->f_bfree)); + mrb_hash_set(mrb, ret, mrb_symbol_value(mrb_intern_lit(mrb, "bavail")), mrb_uv_from_uint64(mrb, stat->f_bavail)); + mrb_hash_set(mrb, ret, mrb_symbol_value(mrb_intern_lit(mrb, "files")), mrb_uv_from_uint64(mrb, stat->f_files)); + mrb_hash_set(mrb, ret, mrb_symbol_value(mrb_intern_lit(mrb, "ffree")), mrb_uv_from_uint64(mrb, stat->f_ffree)); + return ret; +} + +#endif + static mrb_value dirtype_to_sym(mrb_state *mrb, uv_dirent_type_t t) { @@ -187,6 +234,20 @@ _uv_fs_cb(uv_fs_t* uv_req) mrb_uv_req_yield(req, 1, &res); } break; +#if MRB_UV_CHECK_VERSION(1, 28, 0) + case UV_FS_OPENDIR: { + mrb_value const dir = dir_to_mrb(mrb, (uv_dir_t*)uv_req->ptr); + mrb_uv_req_yield(req, 1, &dir); + } break; +#endif + +#if MRB_UV_CHECK_VERSION(1, 31, 0) + case UV_FS_STATFS: { + mrb_value const stat = statfs_to_mrb(mrb, (uv_statfs_t*)uv_req->ptr); + mrb_uv_req_yield(req, 1, &stat); + } break; +#endif + default: { mrb_value const res = mrb_fixnum_value(uv_req->result); mrb_uv_req_yield(req, 1, &res); @@ -793,10 +854,129 @@ mrb_uv_fs_copyfile(mrb_state *mrb, mrb_value self) #endif +#if MRB_UV_CHECK_VERSION(1, 21, 0) + +static mrb_value +mrb_uv_fs_lchown(mrb_state *mrb, mrb_value self) +{ + char const *path; + mrb_value b, ret; + mrb_uv_req_t *req; + int res, uid, gid; + + mrb_get_args(mrb, "&zii", &b, &path, &uid, &gid); + + req = mrb_uv_req_current(mrb, b, &ret); + res = uv_fs_lchown(mrb_uv_current_loop(mrb), &req->req.fs, path, uid, gid, + mrb_nil_p(req->block)? NULL : _uv_fs_cb); + + if (mrb_nil_p(req->block)) { + mrb_value const ret = mrb_str_new_cstr(mrb, req->req.fs.ptr); + mrb_uv_req_clear(req); + return ret; + } + mrb_uv_req_check_error(mrb, req, res); + return ret; +} + +#endif + +#if MRB_UV_CHECK_VERSION(1, 28, 0) + +static mrb_value +mrb_uv_fs_opendir(mrb_state* mrb, mrb_value self) { + const char *path; + mrb_value proc, ret; + mrb_uv_req_t *req; + int res; + + mrb_get_args(mrb, "&z", &proc, &path); + req = mrb_uv_req_current(mrb, proc, &ret); + res = uv_fs_opendir( + mrb_uv_current_loop(mrb), &req->req.fs, path, + mrb_nil_p(req->block)? NULL : _uv_fs_cb); + if (mrb_nil_p(req->block)) { + mrb_uv_req_clear(req); + return mrb_uv_create_status(mrb, res); + } + mrb_uv_req_check_error(mrb, req, res); + return ret; +} + +static mrb_value +mrb_uv_dir_read(mrb_state* mrb, mrb_value self) { + mrb_value proc, ret; + mrb_uv_req_t *req; + int res; + uv_dir_t *dir = (uv_dir_t*)mrb_data_get_ptr(mrb, self, &mrb_uv_dir_type); + + mrb_get_args(mrb, "&", &proc); + req = mrb_uv_req_current(mrb, proc, &ret); + res = uv_fs_readdir( + mrb_uv_current_loop(mrb), &req->req.fs, dir, + mrb_nil_p(req->block)? NULL : _uv_fs_cb); + if (mrb_nil_p(req->block)) { + mrb_uv_req_clear(req); + return mrb_uv_create_status(mrb, res); + } + mrb_uv_req_check_error(mrb, req, res); + return ret; +} + +static mrb_value +mrb_uv_dir_close(mrb_state* mrb, mrb_value self) { + mrb_value proc, ret; + mrb_uv_req_t *req; + int res; + uv_dir_t *dir = (uv_dir_t*)mrb_data_get_ptr(mrb, self, &mrb_uv_dir_type); + + mrb_get_args(mrb, "&", &proc); + req = mrb_uv_req_current(mrb, proc, &ret); + res = uv_fs_closedir( + mrb_uv_current_loop(mrb), &req->req.fs, dir, + mrb_nil_p(req->block)? NULL : _uv_fs_cb); + if (mrb_nil_p(req->block)) { + mrb_uv_req_clear(req); + return mrb_uv_create_status(mrb, res); + } + mrb_uv_req_check_error(mrb, req, res); + return ret; +} + +#endif + +#if MRB_UV_CHECK_VERSION(1, 31, 0) + +static mrb_value +mrb_uv_fs_statfs(mrb_state *mrb, mrb_value self) +{ + char const *path; + mrb_value b, ret; + mrb_uv_req_t *req; + int res; + + mrb_get_args(mrb, "&z", &b, &path); + + req = mrb_uv_req_current(mrb, b, &ret); + res = uv_fs_statfs(mrb_uv_current_loop(mrb), &req->req.fs, path, + mrb_nil_p(req->block)? NULL : _uv_fs_cb); + + if (mrb_nil_p(req->block)) { + mrb_value const ret = statfs_to_mrb(mrb, (uv_statfs_t*)req->req.fs.ptr); + mrb_uv_req_clear(req); + return ret; + } + mrb_uv_req_check_error(mrb, req, res); + return ret; +} + +#endif + void mrb_mruby_uv_gem_init_fs(mrb_state *mrb, struct RClass *UV) { struct RClass *_class_uv_fs; struct RClass *_class_uv_stat; + struct RClass *_class_uv_dir; _class_uv_fs = mrb_define_class_under(mrb, UV, "FS", mrb->object_class); MRB_SET_INSTANCE_TT(_class_uv_fs, MRB_TT_DATA); @@ -823,6 +1003,10 @@ void mrb_mruby_uv_gem_init_fs(mrb_state *mrb, struct RClass *UV) mrb_define_const(mrb, _class_uv_fs, "X_OK", mrb_fixnum_value(X_OK)); #if MRB_UV_CHECK_VERSION(1, 14, 0) mrb_define_const(mrb, _class_uv_fs, "COPYFILE_EXCL", mrb_fixnum_value(UV_FS_COPYFILE_EXCL)); +#endif +#if MRB_UV_CHECK_VERSION(1, 20, 0) + mrb_define_const(mrb, _class_uv_fs, "COPYFILE_FICLONE", mrb_fixnum_value(UV_FS_COPYFILE_FICLONE)); + mrb_define_const(mrb, _class_uv_fs, "COPYFILE_FICLONE_FORCE", mrb_fixnum_value(UV_FS_COPYFILE_FICLONE_FORCE)); #endif mrb_define_method(mrb, _class_uv_fs, "write", mrb_uv_fs_write, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(2)); mrb_define_method(mrb, _class_uv_fs, "read", mrb_uv_fs_read, MRB_ARGS_REQ(0) | MRB_ARGS_OPT(2)); @@ -859,6 +1043,18 @@ void mrb_mruby_uv_gem_init_fs(mrb_state *mrb, struct RClass *UV) #if MRB_UV_CHECK_VERSION(1, 8, 0) mrb_define_class_method(mrb, _class_uv_fs, "realpath", mrb_uv_fs_realpath, MRB_ARGS_REQ(1)); #endif +#if MRB_UV_CHECK_VERSION(1, 21, 0) + mrb_define_class_method(mrb, _class_uv_fs, "lchown", mrb_uv_fs_lchown, MRB_ARGS_REQ(3)); +#endif +#if MRB_UV_CHECK_VERSION(1, 28, 0) + _class_uv_dir = mrb_define_class_under(mrb, UV, "Dir", mrb->object_class); + mrb_define_class_method(mrb, _class_uv_fs, "opendir", mrb_uv_fs_opendir, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, _class_uv_dir, "read", mrb_uv_dir_read, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, _class_uv_dir, "close", mrb_uv_dir_close, MRB_ARGS_BLOCK()); +#endif +#if MRB_UV_CHECK_VERSION(1, 31, 0) + mrb_define_class_method(mrb, _class_uv_fs, "statfs", mrb_uv_fs_statfs, MRB_ARGS_REQ(1)); +#endif /* for compatibility */ mrb_define_class_method(mrb, _class_uv_fs, "readdir", mrb_uv_fs_scandir, MRB_ARGS_REQ(2)); @@ -883,4 +1079,12 @@ void mrb_mruby_uv_gem_init_fs(mrb_state *mrb, struct RClass *UV) mrb_define_method(mrb, _class_uv_stat, "birthtim", mrb_uv_stat_birthtim, MRB_ARGS_NONE()); /* cannot create from mruby side */ mrb_undef_class_method(mrb, _class_uv_stat, "new"); + +#if MRB_UV_CHECK_VERSION(1, 28, 0) + _class_uv_dir = mrb_define_class_under(mrb, UV, "Dir", mrb->object_class); + MRB_SET_INSTANCE_TT(_class_uv_dir, MRB_TT_DATA); + mrb_undef_class_method(mrb, _class_uv_dir, "new"); + mrb_define_method(mrb, _class_uv_dir, "close", mrb_uv_dir_close, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, _class_uv_dir, "readdir", mrb_uv_dir_read, MRB_ARGS_OPT(1)); +#endif } diff --git a/src/handle.c b/src/handle.c index bf0af6f..7044b73 100644 --- a/src/handle.c +++ b/src/handle.c @@ -605,18 +605,11 @@ mrb_uv_tcp_nodelay_set(mrb_state *mrb, mrb_value self) } static mrb_value -mrb_uv_tcp_getpeername(mrb_state *mrb, mrb_value self) +sockaddtr_to_mrb(mrb_state *mrb, struct sockaddr *addr) { - int len; - struct sockaddr_storage addr; - struct RClass* _class_uv; - struct RClass* _class_uv_ipaddr; + struct RClass *class_uv, *_class_uv_ipaddr; struct RData *data; - mrb_value value_data, value_result = mrb_nil_value(); - mrb_uv_handle* context = (mrb_uv_handle*)mrb_uv_get_ptr(mrb, self, &mrb_uv_handle_type); - - len = sizeof(addr); - mrb_uv_check_error(mrb, uv_tcp_getpeername((uv_tcp_t*)&context->handle, (struct sockaddr *)&addr, &len)); + mrb_value value_data, value_result; switch (addr.ss_family) { case AF_INET: case AF_INET6: @@ -639,15 +632,23 @@ mrb_uv_tcp_getpeername(mrb_state *mrb, mrb_value self) return value_result; } +static mrb_value +mrb_uv_tcp_getpeername(mrb_state *mrb, mrb_value self) +{ + int len; + struct sockaddr_storage addr; + mrb_uv_handle* context = (mrb_uv_handle*)mrb_uv_get_ptr(mrb, self, &mrb_uv_handle_type); + + len = sizeof(addr); + mrb_uv_check_error(mrb, uv_tcp_getpeername((uv_tcp_t*)&context->handle, (struct sockaddr *)&addr, &len)); + return sockaddtr_to_mrb(mrb, (struct sockaddr *)&addr); +} + static mrb_value mrb_uv_getsockname(mrb_state *mrb, mrb_value self, int tcp) { int len; struct sockaddr_storage addr; - struct RClass* _class_uv; - struct RClass* _class_uv_ipaddr; - struct RData *data; - mrb_value value_data, value_result = mrb_nil_value(); mrb_uv_handle* context = (mrb_uv_handle*)mrb_uv_get_ptr(mrb, self, &mrb_uv_handle_type); len = sizeof(addr); @@ -657,26 +658,7 @@ mrb_uv_getsockname(mrb_state *mrb, mrb_value self, int tcp) else { mrb_uv_check_error(mrb, uv_udp_getsockname((uv_udp_t*)&context->handle, (struct sockaddr *)&addr, &len)); } - switch (addr.ss_family) { - case AF_INET: - case AF_INET6: - _class_uv = mrb_module_get(mrb, "UV"); - if (addr.ss_family == AF_INET) { - _class_uv_ipaddr = mrb_class_get_under(mrb, _class_uv, "Ip4Addr"); - data = Data_Wrap_Struct(mrb, mrb->object_class, - &mrb_uv_ip4addr_nofree_type, (void *) &addr); - } - else { - _class_uv_ipaddr = mrb_class_get_under(mrb, _class_uv, "Ip6Addr"); - data = Data_Wrap_Struct(mrb, mrb->object_class, - &mrb_uv_ip6addr_nofree_type, (void *) &addr); - } - value_data = mrb_obj_value((void *) data); - value_result = mrb_class_new_instance(mrb, 1, &value_data, - _class_uv_ipaddr); - break; - } - return value_result; + return sockaddr_to_mrb(mrb, (struct sockaddr*)&addr); } static mrb_value @@ -685,6 +667,24 @@ mrb_uv_tcp_getsockname(mrb_state *mrb, mrb_value self) return mrb_uv_getsockname(mrb, self, 1); } +#if MRB_UV_CHECK_VERSION(1, 32, 0) + +static mrb_value +mrb_uv_tcp_close_reset(mrb_state *mrb, mrb_value self) +{ + mrb_uv_handle* context = (mrb_uv_handle*)mrb_uv_get_ptr(mrb, self, &mrb_uv_handle_type); + mrb_value b = mrb_nil_value(); + + mrb_get_args(mrb, "&", &b); + + mrb_iv_set(mrb, context->instance, mrb_intern_lit(mrb, "close_cb"), b); + mrb_uv_check_error(mrb, uv_tcp_close_reset( + (uv_tcp_t*)&context->handle, (uv_connect_cb)_uv_close_cb)); + return mrb_nil_value(); +} + +#endif + /********************************************************* * UV::UDP *********************************************************/ @@ -1000,6 +1000,64 @@ mrb_uv_udp_send_queue_size(mrb_state *mrb, mrb_value self) return mrb_fixnum_value(uv_udp_get_send_queue_size((uv_udp_t*)&ctx->handle)); } +#if MRB_UV_CHECK_VERSION(1, 27, 0) + +static mrb_value +mrb_uv_udp_get_peername(mrb_state *mrb, mrb_value self) +{ + int len; + struct sockaddr_storage addr; + mrb_uv_handle* context = (mrb_uv_handle*)mrb_uv_get_ptr(mrb, self, &mrb_uv_handle_type); + + len = sizeof(addr); + mrb_uv_check_error(mrb, uv_udp_getpeername((uv_udp_t*)&context->handle, (struct sockaddr *)&addr, &len)); + return sockaddr_to_mrb(mrb, (struct sockaddr *)&addr); +} + +static mrb_value +mrb_uv_udp_connect(mrb_state *mrb, mrb_value self) +{ + struct sockaddr* addr; + mrb_value addr_obj; + mrb_uv_handle* context = (mrb_uv_handle*)mrb_uv_get_ptr(mrb, self, &mrb_uv_handle_type); + + mrb_get_args(mrb, "o", &addr_obj); + if (mrb_type(addr_obj) != MRB_TT_DATA) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "Invalid sockaddr: %S", addr_obj); + } + addr = + DATA_PTR(addr_obj) == &mrb_uv_ip4addr_type? (struct sockaddr*)DATA_PTR(addr_obj): + DATA_PTR(addr_obj) == &mrb_uv_ip4addr_nofree_type? (struct sockaddr*)DATA_PTR(addr_obj): + DATA_PTR(addr_obj) == &mrb_uv_ip6addr_type? (struct sockaddr*)DATA_PTR(addr_obj): + DATA_PTR(addr_obj) == &mrb_uv_ip6addr_nofree_type? (struct sockaddr*)DATA_PTR(addr_obj): + NULL; + if (!addr) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "Invalid sockaddr: %S", addr_obj); + } + + mrb_uv_check_error(mrb, uv_udp_connect((uv_udp_t*)&context->handle, addr)); + return self; +} + +#endif + +#if MRB_UV_CHECK_VERSION(1, 32, 0) + +static mrb_value +mrb_uv_udp_set_source_membership(mrb_state *mrb, mrb_value self) +{ + mrb_uv_handle* context = (mrb_uv_handle*)mrb_uv_get_ptr(mrb, self, &mrb_uv_handle_type); + const char *mc, *inf, *src; + mrb_int mem; + + mrb_get_args(mrb, "zzzi", &mc, &inf, &src, &mem); + + mrb_uv_check_error(mrb, uv_udp_set_source_membership((uv_udp_t*)&context->handle, mc, inf, src, mem)); + return self; +} + +#endif + /********************************************************* * UV::Prepare *********************************************************/ @@ -1208,8 +1266,8 @@ _uv_exit_cb(uv_process_t* process, int64_t exit_status, int term_signal) yield_handle_cb((mrb_uv_handle*)process->data, 2, args); } -static mrb_value -get_hash_opt(mrb_state *mrb, mrb_value h, const char *str) +mrb_value +mrb_uv_get_hash_opt(mrb_state *mrb, mrb_value h, const char *str) { mrb_value ret = mrb_hash_get(mrb, h, mrb_symbol_value(mrb_intern_cstr(mrb, str))); if (mrb_nil_p(ret)) { @@ -1242,6 +1300,9 @@ mrb_uv_process_spawn(mrb_state *mrb, mrb_value self) mrb_value arg_file, arg_args, arg_env, arg_cwd, arg_uid, arg_gid, arg_detached, arg_windows_hide, arg_windows_verbatim_arguments, arg_stdio; +#if MRB_UV_CHECK_VERSION(1, 24, 0) + mrb_value arg_windows_hide_console, arg_windows_hide_gui; +#endif mrb_value stdio_pipe[3]; char cwd[PATH_MAX]; size_t cwd_size = sizeof(cwd); @@ -1253,16 +1314,20 @@ mrb_uv_process_spawn(mrb_state *mrb, mrb_value self) uv_loop_t *loop; options = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "options")); - arg_file = get_hash_opt(mrb, options, "file"); - arg_args = get_hash_opt(mrb, options, "args"); - arg_env = get_hash_opt(mrb, options, "env"); - arg_cwd = get_hash_opt(mrb, options, "cwd"); - arg_uid = get_hash_opt(mrb, options, "uid"); - arg_gid = get_hash_opt(mrb, options, "gid"); - arg_detached = get_hash_opt(mrb, options, "detached"); - arg_windows_verbatim_arguments = get_hash_opt(mrb, options, "windows_verbatim_arguments"); - arg_windows_hide = get_hash_opt(mrb, options, "windows_hide"); - arg_stdio = get_hash_opt(mrb, options, "stdio"); + arg_file = mrb_uv_get_hash_opt(mrb, options, "file"); + arg_args = mrb_uv_get_hash_opt(mrb, options, "args"); + arg_env = mrb_uv_get_hash_opt(mrb, options, "env"); + arg_cwd = mrb_uv_get_hash_opt(mrb, options, "cwd"); + arg_uid = mrb_uv_get_hash_opt(mrb, options, "uid"); + arg_gid = mrb_uv_get_hash_opt(mrb, options, "gid"); + arg_detached = mrb_uv_get_hash_opt(mrb, options, "detached"); + arg_windows_verbatim_arguments = mrb_uv_get_hash_opt(mrb, options, "windows_verbatim_arguments"); + arg_windows_hide = mrb_uv_get_hash_opt(mrb, options, "windows_hide"); +#if MRB_UV_CHECK_VERSION(1, 24, 0) + arg_windows_hide_console = mrb_uv_get_hash_opt(mrb, options, "windows_hide_console"); + arg_windows_hide_gui = mrb_uv_get_hash_opt(mrb, options, "windows_hide_gui"); +#endif + arg_stdio = mrb_uv_get_hash_opt(mrb, options, "stdio"); stdio_pipe[0] = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "stdin_pipe")); stdio_pipe[1] = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "stdout_pipe")); stdio_pipe[2] = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "stderr_pipe")); @@ -1363,6 +1428,10 @@ mrb_uv_process_spawn(mrb_state *mrb, mrb_value self) } if (mrb_bool(arg_detached)) { opt.flags |= UV_PROCESS_DETACHED; } if (mrb_bool(arg_windows_hide)) { opt.flags |= UV_PROCESS_WINDOWS_HIDE; } +#if MRB_UV_CHECK_VERSION(1, 24, 0) + if (mrb_bool(arg_windows_hide_console)) { opt.flags |= UV_PROCESS_WINDOWS_HIDE_CONSOLE; } + if (mrb_bool(arg_windows_hide_gui)) { opt.flags |= UV_PROCESS_WINDOWS_HIDE_GUI; } +#endif if (mrb_bool(arg_windows_verbatim_arguments)) { opt.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS; } opt.exit_cb = _uv_exit_cb; @@ -1444,6 +1513,54 @@ mrb_uv_process_stderr_pipe_set(mrb_state *mrb, mrb_value self) return self; } +#define MRB_UV_CHECK_VERSION(1, 23, 0) + +static mrb_value +mrb_uv_process_get_priority(mrb_state *mrb, mrb_value self) +{ + mrb_uv_handle* context = (mrb_uv_handle*)mrb_uv_get_ptr(mrb, self, &mrb_uv_handle_type); + uv_pid_t pid = uv_process_get_pid((uv_process_t*)&context->handle); + int priority; + mrb_uv_check_error(mrb, uv_os_getpriority(pid, &priority)); + return mrb_fixnum_value(priority); +} + +static mrb_value +mrb_uv_process_set_priority(mrb_state *mrb, mrb_value self) +{ + mrb_uv_handle* context = (mrb_uv_handle*)mrb_uv_get_ptr(mrb, self, &mrb_uv_handle_type); + uv_pid_t pid = uv_process_get_pid((uv_process_t*)&context->handle); + int priority; + + mrb_get_args(mrb, "i", &priority); + + mrb_uv_check_error(mrb, uv_os_setpriority(pid, priority)); + return mrb_fixnum_value(priority); +} + +static mrb_value +mrb_uv_get_priority(mrb_state *mrb, mrb_value self) +{ + int priority; + mrb_int pid; + mrb_get_args(mrb, "i", &pid); + mrb_uv_check_error(mrb, uv_os_getpriority(pid, &priority)); + return mrb_fixnum_value(priority); +} + +static mrb_value +mrb_uv_set_priority(mrb_state *mrb, mrb_value self) +{ + mrb_int priority; + mrb_int pid; + mrb_get_args(mrb, "ii", &pid, priority); + + mrb_uv_check_error(mrb, uv_os_setpriority(pid, priority)); + return mrb_fixnum_value(priority); +} + +#endif + /********************************************************* * UV::Timer *********************************************************/ @@ -2092,6 +2209,13 @@ mrb_mruby_uv_gem_init_handle(mrb_state *mrb, struct RClass *UV) mrb_define_method(mrb, _class_uv_udp, "send_queue_size", mrb_uv_udp_send_queue_size, MRB_ARGS_NONE()); mrb_define_const(mrb, _class_uv_udp, "LEAVE_GROUP", mrb_fixnum_value(UV_LEAVE_GROUP)); mrb_define_const(mrb, _class_uv_udp, "JOIN_GROUP", mrb_fixnum_value(UV_JOIN_GROUP)); +#if MRB_UV_CHECK_VERSION(1, 27, 0) + mrb_define_method(mrb, _class_uv_udp, "peername", mrb_uv_udp_get_peername, MRB_ARGS_NONE()); + mrb_define_method(mrb, _class_uv_udp, "connect", mrb_uv_udp_connect, MRB_ARGS_REQ(1)); +#endif +#if MRB_UV_CHECK_VERSION(1, 32, 0) + mrb_define_method(mrb, _class_uv_udp, "set_source_membership", mrb_uv_udp_set_source_membership, MRB_ARGS_REQ(3)); +#endif mrb_gc_arena_restore(mrb, ai); _class_uv_process = mrb_define_class_under(mrb, UV, "Process", mrb->object_class); @@ -2107,6 +2231,20 @@ mrb_mruby_uv_gem_init_handle(mrb_state *mrb, struct RClass *UV) mrb_define_method(mrb, _class_uv_process, "stderr_pipe", mrb_uv_process_stderr_pipe_get, MRB_ARGS_NONE()); mrb_define_method(mrb, _class_uv_process, "kill", mrb_uv_process_kill, MRB_ARGS_NONE()); mrb_define_method(mrb, _class_uv_process, "pid", mrb_uv_process_pid, MRB_ARGS_NONE()); +#define MRB_UV_CHECK_VERSION(1, 23, 0) + mrb_define_method(mrb, _class_uv_process, "priority", mrb_uv_process_get_priority, MRB_ARGS_NONE()); + mrb_define_method(mrb, _class_uv_process, "priority=", mrb_uv_process_set_priority, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, _class_uv, "get_priority", mrb_uv_get_priority, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, _class_uv, "set_priority", mrb_uv_set_priority, MRB_ARGS_REQ(2)); +#define add_priority(name) mrb_define_const(mrb, _class_uv, "PRIORITY_" #name, mrb_fixnum_value(UV_PRIORITY_ ## name))) + add_priority(LOW); + add_priority(BELOW_NORMAL); + add_priority(NORMAL); + add_priority(ABOVE_NORMAL); + add_priority(HIGH); + add_priority(HIGHEST); +#undef add_priority +#endif mrb_gc_arena_restore(mrb, ai); _class_uv_signal = mrb_define_class_under(mrb, UV, "Signal", mrb->object_class); @@ -2207,6 +2345,9 @@ mrb_mruby_uv_gem_init_handle(mrb_state *mrb, struct RClass *UV) mrb_define_method(mrb, _class_uv_tcp, "getsockname", mrb_uv_tcp_getsockname, MRB_ARGS_NONE()); mrb_define_method(mrb, _class_uv_tcp, "peername", mrb_uv_tcp_getpeername, MRB_ARGS_NONE()); mrb_define_method(mrb, _class_uv_tcp, "sockname", mrb_uv_tcp_getsockname, MRB_ARGS_NONE()); +#if MRB_UV_CHECK_VERSION(1, 32, 0) + mrb_define_method(mrb, _class_uv_tcp, "close_reset", mrb_uv_tcp_close_reset, MRB_ARGS_BLOCK()); +#endif mrb_gc_arena_restore(mrb, ai); _class_uv_pipe = mrb_define_class_under(mrb, UV, "Pipe", mrb->object_class); @@ -2264,4 +2405,7 @@ mrb_mruby_uv_gem_init_handle(mrb_state *mrb, struct RClass *UV) mrb_define_const(mrb, UV, "READABLE", mrb_fixnum_value(UV_READABLE)); mrb_define_const(mrb, UV, "WRITABLE", mrb_fixnum_value(UV_WRITABLE)); +#if MRB_UV_CHECK_VERSION(1, 21, 0) + mrb_define_const(mrb, UV, "OVERLAPPED_PIPE", mrb_fixnum_value(UV_OVERLAPPED_PIPE)); +#endif } diff --git a/src/mrb_uv.c b/src/mrb_uv.c index ef140d2..05b41fb 100644 --- a/src/mrb_uv.c +++ b/src/mrb_uv.c @@ -835,6 +835,48 @@ mrb_uv_getnameinfo(mrb_state *mrb, mrb_value self) return ret; } +#if MRB_UV_CHECK_VERSION(1, 33, 0) + +static void +mrb_uv_random_cb(uv_random_t *uv_req, int status, void *buf, size_t len) +{ + mrb_uv_req_t *req = (mrb_uv_req_t*)uv_req->data; + mrb_state *mrb = req->mrb; + mrb_value str = mrb_str_new(mrb, buf, len); + mrb_free(mrb, buf); + mrb_uv_req_yield(req, 1, &str); +} + +static mrb_value +mrb_uv_random(mrb_state *mrb, mrb_value self) +{ + mrb_int len; + mrb_value b = mrb_nil_value(), l = mrb_nil_value(), opts = mrb_nil_value(), ret; + const unsigned flags = 0; + char *buf; + uv_random_cb cb = NULL; + mrb_uv_req_t *req = NULL; + + // TODO(take-cheeze): opts to flags conversion + mrb_get_args(mrb, "&i|H", &b, &len, &opts); + + buf = mrb_malloc(mrb, len); + if (mrb_nil_p(b)) { + cb = mrb_uv_random_cb; + } + req = mrb_uv_req_current(mrb, b, &ret); + mrb_uv_req_check_error(mrb, req, uv_random( + mrb_uv_current_loop(mrb), &req->req.random, buf, len, flags, cb)); + if (mrb_nil_p(b)) { + ret = mrb_str_new(mrb, buf, len); + mrb_free(mrb, buf); + mrb_uv_req_clear(req); + } + return ret; +} + +#endif + /********************************************************* * UV::Addrinfo *********************************************************/ @@ -1170,6 +1212,16 @@ mrb_uv_total_memory(mrb_state *mrb, mrb_value self) return mrb_uv_from_uint64(mrb, uv_get_total_memory()); } +#if MRB_UV_CHECK_VERSION(1, 29, 0) + +static mrb_value +mrb_uv_get_constrained_memory(mrb_state* mrb, mrb_value self) +{ + return mrb_uv_from_uint64(mrb, uv_get_constrained_memory()); +} + +#endif + static mrb_value mrb_uv_hrtime(mrb_state *mrb, mrb_value self) { @@ -1480,6 +1532,23 @@ mrb_uv_get_osfhandle(mrb_state *mrb, mrb_value self) #endif +#if MRB_UV_CHECK_VERSION(1, 23, 0) + +static mrb_value +mrb_uv_fs_open_osfandle(mrb_state *mrb, mrb_value self) +{ + mrb_value o; + mrb_get_args(mrb, "o", &o); + + if (!mrb_cptr_p(o)) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "Invalid object: %S", o); + } + + return mrb_fixnum_value(uv_open_osfhandle(mrb_cptr(o)); +} + +#endif + #if MRB_UV_CHECK_VERSION(1, 6, 0) static mrb_value @@ -1616,6 +1685,78 @@ mrb_uv_os_getppid(mrb_state *mrb, mrb_value self) #endif +#if MRB_UV_CHECK_VERSION(1, 25, 0) + +static mrb_value +mrb_uv_os_uname(mrb_state *mrb, mrb_value self) +{ + mrb_value ret = mrb_hash_new_capa(mrb, ); + uv_ustname_t uts; + mrb_uv_check_error(mrb, uv_is_uname(&uts)); + mrb_hash_set(ret, mrb_intern_lit(mrb, "sysname"), mrb_str_new_cstr(mrb, uts.sysname)); + mrb_hash_set(ret, mrb_intern_lit(mrb, "release"), mrb_str_new_cstr(mrb, uts.release)); + mrb_hash_set(ret, mrb_intern_lit(mrb, "version"), mrb_str_new_cstr(mrb, uts.version)); + mrb_hash_set(ret, mrb_intern_lit(mrb, "machine"), mrb_str_new_cstr(mrb, uts.machine)); + return ret; +} + +#endif + +#if MRB_UV_CHECK_VERSION(1, 31, 0) + +static mrb_value +mrb_uv_os_environ(mrb_state *mrb, mrb_value self) +{ + mrb_value ret = mrb_hash_new(mrb); + uv_env_item_t *items; + int i, count; + + mrb_uv_check_error(mrb, uv_os_environ(&items, &count)); + + for (i = 0; i < count; ++i) { + mrb_hash_set(mrb, mrb_str_new_cstr(mrb, items[i].name), mrb_str_new_cstr(mrb, items[i].value)); + } + uv_os_free_environ(items, count); + return ret; +} + +#endif + +#if MRB_UV_CHECK_VERSION(1, 28, 0) + +static mrb_value +mrb_uv_gettimeofday(mrb_state *mrb, mrb_value self) +{ + uv_timeval64_t tv; + mrb_uv_check_error(mrb, uv_gettimeofday(&tv)); + return mrb_funcall(mrb, mrb_obj_value(mrb_class_get(mrb, "Time")), "at", 2, \ + mrb_uv_from_uint64(mrb, tv.tv_sec), \ + mrb_uv_from_uint64(mrb, tv.tv_usec)); \ +} + +#endif + +#if MRB_UV_CHECK_VERSION(1, 33, 0) + +static mrb_value +mrb_uv_get_vterm_state(mrb_state *mrb, mrb_value self) +{ + uv_tty_vtermstate_t state; + mrb_uv_check_error(mrb, uv_tty_get_vterm_state(&state)); + return mrb_fixnum_value(state); +} + +static mrb_value +mrb_uv_set_vterm_state(mrb_state *mrb, mrb_value self) +{ + mrb_int state; + mrb_get_args(mrb, "i", &state); + uv_tty_set_vterm_state(&state); + return self; +} + +#endif + /********************************************************* * register *********************************************************/ @@ -1674,6 +1815,12 @@ mrb_mruby_uv_gem_init(mrb_state* mrb) { #if MRB_UV_CHECK_VERSION(1, 12, 0) mrb_define_module_function(mrb, _class_uv, "osfhandle", mrb_uv_get_osfhandle, MRB_ARGS_REQ(1)); #endif +#if MRB_UV_CHECK_VERSION(1, 23, 0) + mrb_define_class_method(mrb, _class_uv, "open_osfhandle", mrb_uv_fs_open_osfandle, MRB_ARGS_REQ(1)); +#endif +#if MRB_UV_CHECK_VERSION(1, 33, 0) + mrb_define_module_function(mrb, _class_uv, "random", mrb_uv_random, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1)); +#endif mrb_define_const(mrb, _class_uv, "UV_RUN_DEFAULT", mrb_fixnum_value(UV_RUN_DEFAULT)); mrb_define_const(mrb, _class_uv, "UV_RUN_ONCE", mrb_fixnum_value(UV_RUN_ONCE)); @@ -1817,6 +1964,12 @@ mrb_mruby_uv_gem_init(mrb_state* mrb) { #if MRB_UV_CHECK_VERSION(1, 18, 0) mrb_define_module_function(mrb, _class_uv_os, "getpid", mrb_uv_os_getpid, MRB_ARGS_NONE()); #endif +#if MRB_UV_CHECK_VERSION(1, 25, 0) + mrb_define_module_function(mrb, _class_uv_os, "uname", mrb_uv_os_uname, MRB_ARGS_NONE()); +#endif +#if MRB_UV_CHECK_VERSION(1, 31, 0) + mrb_define_module_function(mrb, _class_uv_os, "environ", mrb_uv_os_environ, MRB_ARGS_NONE()); +#endif #if MRB_UV_CHECK_VERSION(1, 9, 0) _class_uv_passwd = mrb_define_class_under(mrb, _class_uv_os, "Passwd", mrb->object_class); @@ -1829,6 +1982,21 @@ mrb_mruby_uv_gem_init(mrb_state* mrb) { mrb_define_method(mrb, _class_uv_passwd, "gid", mrb_uv_passwd_gid, MRB_ARGS_NONE()); #endif +#if MRB_UV_CHECK_VERSION(1, 28, 0) + mrb_define_module_function(mrb, _class_uv, "timeofday", mrb_uv_gettimeofday, MRB_ARGS_NONE()); +#endif + +#if MRB_UV_CHECK_VERSION(1, 29, 0) + mrb_define_module_function(mrb, _class_uv, "constrained_memory", mrb_uv_get_constrained_memory, MRB_ARGS_NONE()); +#endif + +#if MRB_UV_CHECK_VERSION(1, 33, 0) + mrb_define_module_function(mrb, _class_uv, "vterm_state", mrb_uv_get_vterm_state, MRB_ARGS_NONE()); + mrb_define_module_function(mrb, _class_uv, "vterm_state=", mrb_uv_set_vterm_state, MRB_ARGS_REQ(1)); + mrb_define_const(mrb, _class_uv, "TTY_SUPPORTED", mrb_fixnum_value(UV_TTY_SUPPORTED)); + mrb_define_const(mrb, _class_uv, "TTY_UNSUPPORTED", mrb_fixnum_value(UV_TTY_UNSUPPORTED)); +#endif + mrb_mruby_uv_gem_init_fs(mrb, _class_uv); mrb_mruby_uv_gem_init_handle(mrb, _class_uv); mrb_mruby_uv_gem_init_thread(mrb, _class_uv); diff --git a/src/mrb_uv.h b/src/mrb_uv.h index fe1025b..f0c3029 100644 --- a/src/mrb_uv.h +++ b/src/mrb_uv.h @@ -118,4 +118,6 @@ void mrb_uv_close_handle_belongs_to_vm(uv_handle_t * h, void *arg); mrb_value mrb_uv_create_error(mrb_state *mrb, int err); mrb_value mrb_uv_create_status(mrb_state *mrb, int status); +mrb_value mrb_uv_get_hash_opt(mrb_state *mrb, mrb_value h, const char *str); + #endif diff --git a/src/thread.c b/src/thread.c index 99441f0..2ffabe8 100644 --- a/src/thread.c +++ b/src/thread.c @@ -100,10 +100,10 @@ static mrb_value mrb_uv_thread_init(mrb_state *mrb, mrb_value self) { mrb_value thread_arg = mrb_nil_value(); - mrb_value b = mrb_nil_value(); + mrb_value b = mrb_nil_value(), opts; mrb_uv_thread* context = NULL; - mrb_get_args(mrb, "&|o", &b, &thread_arg); + mrb_get_args(mrb, "&|oH", &b, &thread_arg, opts); context = (mrb_uv_thread*)mrb_malloc(mrb, sizeof(mrb_uv_thread)); context->mrb = mrb; @@ -114,7 +114,21 @@ mrb_uv_thread_init(mrb_state *mrb, mrb_value self) DATA_PTR(self) = context; DATA_TYPE(self) = &mrb_uv_thread_type; - mrb_uv_check_error(mrb, uv_thread_create(&context->thread, _uv_thread_proc, context)); + if (mrb_nil_p(opts)) { + mrb_uv_check_error(mrb, uv_thread_create(&context->thread, _uv_thread_proc, context)); + } else { +#if MRB_UV_CHECK_VERSION(1, 26, 0) + uv_thread_options_t o = { UV_THREAD_NO_FLAGS }; + mrb_value stack_size = mrb_uv_get_hash_opt(mrb, opts, "stack_size"); + if (!mrb_nil_p(stack_size)) { + o.flags |= UV_THREAD_HAS_STACK_SIZE; + o.stack_size = mrb_int(mrb, stack_size); + } + mrb_uv_check_error(mrb, uv_thread_create_ex(&context->thread, &o, _uv_thread_proc, context)); +#else + mrb_raisef(mrb, E_ARGUMENT_ERROR, "Invalid option: %S", opts); +#endif + } return self; } @@ -596,7 +610,7 @@ void mrb_mruby_uv_gem_init_thread(mrb_state *mrb, struct RClass *UV) _class_uv_thread = mrb_define_class_under(mrb, UV, "Thread", mrb->object_class); MRB_SET_INSTANCE_TT(_class_uv_thread, MRB_TT_DATA); - mrb_define_method(mrb, _class_uv_thread, "initialize", mrb_uv_thread_init, MRB_ARGS_NONE()); + mrb_define_method(mrb, _class_uv_thread, "initialize", mrb_uv_thread_init, MRB_ARGS_OPT(1)); mrb_define_method(mrb, _class_uv_thread, "join", mrb_uv_thread_join, MRB_ARGS_NONE()); mrb_define_method(mrb, UV, "==", mrb_uv_thread_eq, MRB_ARGS_REQ(1)); mrb_gc_arena_restore(mrb, ai); From 62073f4506b47fb566be9a1907185691ab4a6d77 Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Fri, 13 Dec 2019 02:47:37 +0900 Subject: [PATCH 02/13] Update for 1.34 --- mrbgem.rake | 2 +- src/fs.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/mrb_uv.c | 15 +++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/mrbgem.rake b/mrbgem.rake index 761387c..24102f0 100644 --- a/mrbgem.rake +++ b/mrbgem.rake @@ -13,7 +13,7 @@ MRuby::Gem::Specification.new('mruby-uv') do |spec| def cross?; build.kind_of? MRuby::CrossBuild end - DEFAULT_UV_VERSION = '1.33.1' + DEFAULT_UV_VERSION = '1.34.0' def self.bundle_uv(version = DEFAULT_UV_VERSION) visualcpp = ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] diff --git a/src/fs.c b/src/fs.c index caef875..9f1c8b5 100644 --- a/src/fs.c +++ b/src/fs.c @@ -262,6 +262,12 @@ mrb_uv_fs_fd(mrb_state *mrb, mrb_value self) return mrb_fixnum_value(ctx->fd); } +static mrb_value +mrb_uv_fs_path(mrb_state *mrb, mrb_value self) +{ + return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "path")); +} + static void _uv_fs_open_cb(uv_fs_t* uv_req) { @@ -275,6 +281,7 @@ _uv_fs_open_cb(uv_fs_t* uv_req) mrb_iv_set(mrb, req->instance, mrb_intern_lit(mrb, "fs_open"), mrb_nil_value()); file = (mrb_uv_file*)DATA_PTR(args[0]); file->fd = uv_req->result; + mrb_iv_set(mrb, args[0], mrb_intern_lit(mrb, "path"), mrb_str_new_cstr(mrb, uv_req->path)); mrb_uv_req_yield(req, 2, args); } @@ -306,12 +313,52 @@ mrb_uv_fs_open(mrb_state *mrb, mrb_value self) mrb_uv_req_check_error(mrb, req, res); if (mrb_nil_p(req->block)) { context->fd = res; + mrb_iv_set(mrb, args[0], mrb_intern_lit(mrb, "path"), mrb_str_new_cstr(mrb, uv_req->path)); + return c; + } + mrb_iv_set(mrb, req->instance, mrb_intern_lit(mrb, "fs_open"), c); + return ret; +} + +#if MRB_UV_CHECK_VERSION(1, 34, 0) + +static mrb_value +mrb_uv_fs_mkstemp(mrb_state *mrb, mrb_value self) +{ + char const *arg_filename; + mrb_value c, b, ret; + mrb_int arg_flags, arg_mode; + struct RClass* _class_uv_fs; + mrb_uv_file* context; + mrb_uv_req_t* req; + int res; + + mrb_get_args(mrb, "&zii", &b, &arg_filename, &arg_flags, &arg_mode); + + _class_uv_fs = mrb_class_get_under(mrb, mrb_module_get(mrb, "UV"), "FS"); + c = mrb_obj_value(mrb_obj_alloc(mrb, MRB_TT_DATA, _class_uv_fs)); + context = (mrb_uv_file*)mrb_malloc(mrb, sizeof(mrb_uv_file)); + context->mrb = mrb; + context->instance = c; + context->fd = -1; + DATA_PTR(c) = context; + DATA_TYPE(c) = &mrb_uv_file_type; + + req = mrb_uv_req_current(mrb, b, &ret); + res = uv_fs_mkdtemp(mrb_uv_current_loop(mrb), &req->req.fs, + arg_filename, arg_flags, arg_mode, mrb_nil_p(req->block)? NULL : _uv_fs_open_cb); + mrb_uv_req_check_error(mrb, req, res); + if (mrb_nil_p(req->block)) { + context->fd = res; + mrb_iv_set(mrb, args[0], mrb_intern_lit(mrb, "path"), mrb_str_new_cstr(mrb, uv_req->path)); return c; } mrb_iv_set(mrb, req->instance, mrb_intern_lit(mrb, "fs_open"), c); return ret; } +#endif + static mrb_value mrb_uv_fs_close(mrb_state *mrb, mrb_value self) { @@ -1019,6 +1066,7 @@ void mrb_mruby_uv_gem_init_fs(mrb_state *mrb, struct RClass *UV) mrb_define_method(mrb, _class_uv_fs, "chown", mrb_uv_fs_fchown, MRB_ARGS_REQ(2)); mrb_define_method(mrb, _class_uv_fs, "close", mrb_uv_fs_close, MRB_ARGS_NONE()); mrb_define_method(mrb, _class_uv_fs, "fd", mrb_uv_fs_fd, MRB_ARGS_NONE()); + mrb_define_method(mrb, _class_uv_fs, "path", mrb_uv_fs_path, MRB_ARGS_NONE()); mrb_define_class_method(mrb, _class_uv_fs, "open", mrb_uv_fs_open, MRB_ARGS_REQ(2)); mrb_define_class_method(mrb, _class_uv_fs, "unlink", mrb_uv_fs_unlink, MRB_ARGS_REQ(1)); mrb_define_class_method(mrb, _class_uv_fs, "mkdir", mrb_uv_fs_mkdir, MRB_ARGS_REQ(1)); @@ -1055,6 +1103,9 @@ void mrb_mruby_uv_gem_init_fs(mrb_state *mrb, struct RClass *UV) #if MRB_UV_CHECK_VERSION(1, 31, 0) mrb_define_class_method(mrb, _class_uv_fs, "statfs", mrb_uv_fs_statfs, MRB_ARGS_REQ(1)); #endif +#if MRB_UV_CHECK_VERSION(1, 34, 0) + mrb_define_class_method(mrb, _class_uv_fs, "mkstemp", mrb_uv_fs_mkstemp, MRB_ARGS_REQ(1)); +#endif /* for compatibility */ mrb_define_class_method(mrb, _class_uv_fs, "readdir", mrb_uv_fs_scandir, MRB_ARGS_REQ(2)); diff --git a/src/mrb_uv.c b/src/mrb_uv.c index 05b41fb..7bcd421 100644 --- a/src/mrb_uv.c +++ b/src/mrb_uv.c @@ -1757,6 +1757,18 @@ mrb_uv_set_vterm_state(mrb_state *mrb, mrb_value self) #endif +#if MRB_UV_CHECK_VERSION(1, 34, 0) + +static mrb_value +mrb_uv_sleep(mrb_state *mrb, mrb_value self) { + mrb_int ms; + mrb_get_args(mrb, "i", &ms); + uv_sleep(ms); + return self; +} + +#endif + /********************************************************* * register *********************************************************/ @@ -1821,6 +1833,9 @@ mrb_mruby_uv_gem_init(mrb_state* mrb) { #if MRB_UV_CHECK_VERSION(1, 33, 0) mrb_define_module_function(mrb, _class_uv, "random", mrb_uv_random, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1)); #endif +#if MRB_UV_CHECK_VERSION(1, 34, 0) + mrb_define_module_function(mrb, _class_uv, "sleep", mrb_uv_sleep, MRB_ARGS_REQ(1)); +#endif mrb_define_const(mrb, _class_uv, "UV_RUN_DEFAULT", mrb_fixnum_value(UV_RUN_DEFAULT)); mrb_define_const(mrb, _class_uv, "UV_RUN_ONCE", mrb_fixnum_value(UV_RUN_ONCE)); From ee7c56a1b31240b5fc67ba4827da825b0b6c5571 Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Fri, 13 Dec 2019 03:03:08 +0900 Subject: [PATCH 03/13] Make things compile --- src/fs.c | 9 ++++---- src/handle.c | 62 ++++++++++++++-------------------------------------- src/mrb_uv.c | 60 ++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 68 insertions(+), 63 deletions(-) diff --git a/src/fs.c b/src/fs.c index 9f1c8b5..83e551d 100644 --- a/src/fs.c +++ b/src/fs.c @@ -313,7 +313,7 @@ mrb_uv_fs_open(mrb_state *mrb, mrb_value self) mrb_uv_req_check_error(mrb, req, res); if (mrb_nil_p(req->block)) { context->fd = res; - mrb_iv_set(mrb, args[0], mrb_intern_lit(mrb, "path"), mrb_str_new_cstr(mrb, uv_req->path)); + mrb_iv_set(mrb, c, mrb_intern_lit(mrb, "path"), mrb_str_new_cstr(mrb, req->req.fs.path)); return c; } mrb_iv_set(mrb, req->instance, mrb_intern_lit(mrb, "fs_open"), c); @@ -327,13 +327,12 @@ mrb_uv_fs_mkstemp(mrb_state *mrb, mrb_value self) { char const *arg_filename; mrb_value c, b, ret; - mrb_int arg_flags, arg_mode; struct RClass* _class_uv_fs; mrb_uv_file* context; mrb_uv_req_t* req; int res; - mrb_get_args(mrb, "&zii", &b, &arg_filename, &arg_flags, &arg_mode); + mrb_get_args(mrb, "&z", &b, &arg_filename); _class_uv_fs = mrb_class_get_under(mrb, mrb_module_get(mrb, "UV"), "FS"); c = mrb_obj_value(mrb_obj_alloc(mrb, MRB_TT_DATA, _class_uv_fs)); @@ -346,11 +345,11 @@ mrb_uv_fs_mkstemp(mrb_state *mrb, mrb_value self) req = mrb_uv_req_current(mrb, b, &ret); res = uv_fs_mkdtemp(mrb_uv_current_loop(mrb), &req->req.fs, - arg_filename, arg_flags, arg_mode, mrb_nil_p(req->block)? NULL : _uv_fs_open_cb); + arg_filename, mrb_nil_p(req->block)? NULL : _uv_fs_open_cb); mrb_uv_req_check_error(mrb, req, res); if (mrb_nil_p(req->block)) { context->fd = res; - mrb_iv_set(mrb, args[0], mrb_intern_lit(mrb, "path"), mrb_str_new_cstr(mrb, uv_req->path)); + mrb_iv_set(mrb, c, mrb_intern_lit(mrb, "path"), mrb_str_new_cstr(mrb, req->req.fs.path)); return c; } mrb_iv_set(mrb, req->instance, mrb_intern_lit(mrb, "fs_open"), c); diff --git a/src/handle.c b/src/handle.c index 7044b73..9092177 100644 --- a/src/handle.c +++ b/src/handle.c @@ -605,28 +605,29 @@ mrb_uv_tcp_nodelay_set(mrb_state *mrb, mrb_value self) } static mrb_value -sockaddtr_to_mrb(mrb_state *mrb, struct sockaddr *addr) +sockaddr_to_mrb(mrb_state *mrb, struct sockaddr *addr) { - struct RClass *class_uv, *_class_uv_ipaddr; + struct RClass *class_uv, *class_uv_ipaddr; struct RData *data; mrb_value value_data, value_result; - switch (addr.ss_family) { + switch (addr->sa_family) { case AF_INET: case AF_INET6: - _class_uv = mrb_module_get(mrb, "UV"); - if (addr.ss_family == AF_INET) { - _class_uv_ipaddr = mrb_class_get_under(mrb, _class_uv, "Ip4Addr"); - data = Data_Wrap_Struct(mrb, mrb->object_class, + class_uv = mrb_module_get(mrb, "UV"); + if (addr->sa_family == AF_INET) { + class_uv_ipaddr = mrb_class_get_under(mrb, class_uv, "Ip4Addr"); + data = Data_Wrap_Struct( + mrb, mrb->object_class, &mrb_uv_ip4addr_nofree_type, (void *) &addr); } else { - _class_uv_ipaddr = mrb_class_get_under(mrb, _class_uv, "Ip6Addr"); - data = Data_Wrap_Struct(mrb, mrb->object_class, + class_uv_ipaddr = mrb_class_get_under(mrb, class_uv, "Ip6Addr"); + data = Data_Wrap_Struct( + mrb, mrb->object_class, &mrb_uv_ip6addr_nofree_type, (void *) &addr); } value_data = mrb_obj_value((void *) data); - value_result = mrb_class_new_instance(mrb, 1, &value_data, - _class_uv_ipaddr); + value_result = mrb_class_new_instance(mrb, 1, &value_data, class_uv_ipaddr); break; } return value_result; @@ -641,7 +642,7 @@ mrb_uv_tcp_getpeername(mrb_state *mrb, mrb_value self) len = sizeof(addr); mrb_uv_check_error(mrb, uv_tcp_getpeername((uv_tcp_t*)&context->handle, (struct sockaddr *)&addr, &len)); - return sockaddtr_to_mrb(mrb, (struct sockaddr *)&addr); + return sockaddr_to_mrb(mrb, (struct sockaddr *)&addr); } static mrb_value @@ -679,7 +680,7 @@ mrb_uv_tcp_close_reset(mrb_state *mrb, mrb_value self) mrb_iv_set(mrb, context->instance, mrb_intern_lit(mrb, "close_cb"), b); mrb_uv_check_error(mrb, uv_tcp_close_reset( - (uv_tcp_t*)&context->handle, (uv_connect_cb)_uv_close_cb)); + (uv_tcp_t*)&context->handle, (uv_close_cb)_uv_close_cb)); return mrb_nil_value(); } @@ -1513,7 +1514,7 @@ mrb_uv_process_stderr_pipe_set(mrb_state *mrb, mrb_value self) return self; } -#define MRB_UV_CHECK_VERSION(1, 23, 0) +#if MRB_UV_CHECK_VERSION(1, 23, 0) static mrb_value mrb_uv_process_get_priority(mrb_state *mrb, mrb_value self) @@ -1538,27 +1539,6 @@ mrb_uv_process_set_priority(mrb_state *mrb, mrb_value self) return mrb_fixnum_value(priority); } -static mrb_value -mrb_uv_get_priority(mrb_state *mrb, mrb_value self) -{ - int priority; - mrb_int pid; - mrb_get_args(mrb, "i", &pid); - mrb_uv_check_error(mrb, uv_os_getpriority(pid, &priority)); - return mrb_fixnum_value(priority); -} - -static mrb_value -mrb_uv_set_priority(mrb_state *mrb, mrb_value self) -{ - mrb_int priority; - mrb_int pid; - mrb_get_args(mrb, "ii", &pid, priority); - - mrb_uv_check_error(mrb, uv_os_setpriority(pid, priority)); - return mrb_fixnum_value(priority); -} - #endif /********************************************************* @@ -2231,19 +2211,9 @@ mrb_mruby_uv_gem_init_handle(mrb_state *mrb, struct RClass *UV) mrb_define_method(mrb, _class_uv_process, "stderr_pipe", mrb_uv_process_stderr_pipe_get, MRB_ARGS_NONE()); mrb_define_method(mrb, _class_uv_process, "kill", mrb_uv_process_kill, MRB_ARGS_NONE()); mrb_define_method(mrb, _class_uv_process, "pid", mrb_uv_process_pid, MRB_ARGS_NONE()); -#define MRB_UV_CHECK_VERSION(1, 23, 0) +#if MRB_UV_CHECK_VERSION(1, 23, 0) mrb_define_method(mrb, _class_uv_process, "priority", mrb_uv_process_get_priority, MRB_ARGS_NONE()); mrb_define_method(mrb, _class_uv_process, "priority=", mrb_uv_process_set_priority, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, _class_uv, "get_priority", mrb_uv_get_priority, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, _class_uv, "set_priority", mrb_uv_set_priority, MRB_ARGS_REQ(2)); -#define add_priority(name) mrb_define_const(mrb, _class_uv, "PRIORITY_" #name, mrb_fixnum_value(UV_PRIORITY_ ## name))) - add_priority(LOW); - add_priority(BELOW_NORMAL); - add_priority(NORMAL); - add_priority(ABOVE_NORMAL); - add_priority(HIGH); - add_priority(HIGHEST); -#undef add_priority #endif mrb_gc_arena_restore(mrb, ai); diff --git a/src/mrb_uv.c b/src/mrb_uv.c index 7bcd421..41f4765 100644 --- a/src/mrb_uv.c +++ b/src/mrb_uv.c @@ -851,7 +851,7 @@ static mrb_value mrb_uv_random(mrb_state *mrb, mrb_value self) { mrb_int len; - mrb_value b = mrb_nil_value(), l = mrb_nil_value(), opts = mrb_nil_value(), ret; + mrb_value b = mrb_nil_value(), opts = mrb_nil_value(), ret; const unsigned flags = 0; char *buf; uv_random_cb cb = NULL; @@ -1544,7 +1544,7 @@ mrb_uv_fs_open_osfandle(mrb_state *mrb, mrb_value self) mrb_raisef(mrb, E_RUNTIME_ERROR, "Invalid object: %S", o); } - return mrb_fixnum_value(uv_open_osfhandle(mrb_cptr(o)); + return mrb_fixnum_value(uv_open_osfhandle((uintptr_t)mrb_cptr(o))); } #endif @@ -1685,18 +1685,43 @@ mrb_uv_os_getppid(mrb_state *mrb, mrb_value self) #endif +#if MRB_UV_CHECK_VERSION(1, 23, 0) + +static mrb_value +mrb_uv_get_priority(mrb_state *mrb, mrb_value self) +{ + int priority; + mrb_int pid; + mrb_get_args(mrb, "i", &pid); + mrb_uv_check_error(mrb, uv_os_getpriority(pid, &priority)); + return mrb_fixnum_value(priority); +} + +static mrb_value +mrb_uv_set_priority(mrb_state *mrb, mrb_value self) +{ + mrb_int priority; + mrb_int pid; + mrb_get_args(mrb, "ii", &pid, &priority); + + mrb_uv_check_error(mrb, uv_os_setpriority(pid, priority)); + return mrb_fixnum_value(priority); +} + +#endif + #if MRB_UV_CHECK_VERSION(1, 25, 0) static mrb_value mrb_uv_os_uname(mrb_state *mrb, mrb_value self) { - mrb_value ret = mrb_hash_new_capa(mrb, ); - uv_ustname_t uts; - mrb_uv_check_error(mrb, uv_is_uname(&uts)); - mrb_hash_set(ret, mrb_intern_lit(mrb, "sysname"), mrb_str_new_cstr(mrb, uts.sysname)); - mrb_hash_set(ret, mrb_intern_lit(mrb, "release"), mrb_str_new_cstr(mrb, uts.release)); - mrb_hash_set(ret, mrb_intern_lit(mrb, "version"), mrb_str_new_cstr(mrb, uts.version)); - mrb_hash_set(ret, mrb_intern_lit(mrb, "machine"), mrb_str_new_cstr(mrb, uts.machine)); + mrb_value ret = mrb_hash_new_capa(mrb, 4); + uv_utsname_t uts; + mrb_uv_check_error(mrb, uv_os_uname(&uts)); + mrb_hash_set(mrb, ret, mrb_symbol_value(mrb_intern_lit(mrb, "sysname")), mrb_str_new_cstr(mrb, uts.sysname)); + mrb_hash_set(mrb, ret, mrb_symbol_value(mrb_intern_lit(mrb, "release")), mrb_str_new_cstr(mrb, uts.release)); + mrb_hash_set(mrb, ret, mrb_symbol_value(mrb_intern_lit(mrb, "version")), mrb_str_new_cstr(mrb, uts.version)); + mrb_hash_set(mrb, ret, mrb_symbol_value(mrb_intern_lit(mrb, "machine")), mrb_str_new_cstr(mrb, uts.machine)); return ret; } @@ -1707,14 +1732,15 @@ mrb_uv_os_uname(mrb_state *mrb, mrb_value self) static mrb_value mrb_uv_os_environ(mrb_state *mrb, mrb_value self) { - mrb_value ret = mrb_hash_new(mrb); + mrb_value ret; uv_env_item_t *items; int i, count; mrb_uv_check_error(mrb, uv_os_environ(&items, &count)); + ret = mrb_hash_new_capa(mrb, count); for (i = 0; i < count; ++i) { - mrb_hash_set(mrb, mrb_str_new_cstr(mrb, items[i].name), mrb_str_new_cstr(mrb, items[i].value)); + mrb_hash_set(mrb, ret, mrb_str_new_cstr(mrb, items[i].name), mrb_str_new_cstr(mrb, items[i].value)); } uv_os_free_environ(items, count); return ret; @@ -1751,7 +1777,7 @@ mrb_uv_set_vterm_state(mrb_state *mrb, mrb_value self) { mrb_int state; mrb_get_args(mrb, "i", &state); - uv_tty_set_vterm_state(&state); + uv_tty_set_vterm_state((uv_tty_vtermstate_t)state); return self; } @@ -1829,6 +1855,16 @@ mrb_mruby_uv_gem_init(mrb_state* mrb) { #endif #if MRB_UV_CHECK_VERSION(1, 23, 0) mrb_define_class_method(mrb, _class_uv, "open_osfhandle", mrb_uv_fs_open_osfandle, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, _class_uv, "get_priority", mrb_uv_get_priority, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, _class_uv, "set_priority", mrb_uv_set_priority, MRB_ARGS_REQ(2)); +#define add_priority(name) mrb_define_const(mrb, _class_uv, "PRIORITY_" #name, mrb_fixnum_value(UV_PRIORITY_ ## name)) + add_priority(LOW); + add_priority(BELOW_NORMAL); + add_priority(NORMAL); + add_priority(ABOVE_NORMAL); + add_priority(HIGH); + add_priority(HIGHEST); +#undef add_priority #endif #if MRB_UV_CHECK_VERSION(1, 33, 0) mrb_define_module_function(mrb, _class_uv, "random", mrb_uv_random, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1)); From 4053e844c186e880253282d064a8acf795d77568 Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Fri, 13 Dec 2019 03:07:23 +0900 Subject: [PATCH 04/13] Fix CI --- .travis_config.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis_config.rb b/.travis_config.rb index 332170b..a1c0802 100644 --- a/.travis_config.rb +++ b/.travis_config.rb @@ -7,7 +7,7 @@ gem :core => 'mruby-sprintf' gem :core => 'mruby-time' gem "#{MRUBY_ROOT}/.." do |c| - c.bundle_onigmo + c.bundle_uv end end @@ -20,6 +20,6 @@ gem :core => 'mruby-sprintf' gem :core => 'mruby-time' gem "#{MRUBY_ROOT}/.." do |c| - c.bundle_onigmo '1.0.0' + c.bundle_uv '1.0.0' end end From f44ab963a57de2d4ee78778a527ccc91e1c0f91b Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Fri, 13 Dec 2019 03:07:29 +0900 Subject: [PATCH 05/13] Check unhandle enum --- src/handle.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/handle.c b/src/handle.c index 9092177..dd553d4 100644 --- a/src/handle.c +++ b/src/handle.c @@ -629,6 +629,8 @@ sockaddr_to_mrb(mrb_state *mrb, struct sockaddr *addr) value_data = mrb_obj_value((void *) data); value_result = mrb_class_new_instance(mrb, 1, &value_data, class_uv_ipaddr); break; + default: + mrb_assert(FALSE); } return value_result; } From 391141962885917d108638c9ccce07dc5d449a98 Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Fri, 13 Dec 2019 03:39:26 +0900 Subject: [PATCH 06/13] Workaround CI --- .travis_config.rb | 1 + mrbgem.rake | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis_config.rb b/.travis_config.rb index a1c0802..81f57e8 100644 --- a/.travis_config.rb +++ b/.travis_config.rb @@ -19,6 +19,7 @@ gem :core => 'mruby-print' gem :core => 'mruby-sprintf' gem :core => 'mruby-time' + ENV['SKIP_UV_BUNDLE'] = '1' gem "#{MRUBY_ROOT}/.." do |c| c.bundle_uv '1.0.0' end diff --git a/mrbgem.rake b/mrbgem.rake index 24102f0..c06873c 100644 --- a/mrbgem.rake +++ b/mrbgem.rake @@ -99,7 +99,7 @@ MRuby::Gem::Specification.new('mruby-uv') do |spec| if build.cc.respond_to? :search_header_path next if build.cc.search_header_path 'uv.h' end - if ENV['OS'] == 'Windows_NT' + if ENV['OS'] == 'Windows_NT' || ENV['SKIP_UV_BUNDLE'] next end From 3dccc51eab2fe7804d7477203ac2189347e105d5 Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Fri, 13 Dec 2019 03:39:35 +0900 Subject: [PATCH 07/13] Fix argumet handling --- src/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thread.c b/src/thread.c index 2ffabe8..8d1552f 100644 --- a/src/thread.c +++ b/src/thread.c @@ -103,7 +103,7 @@ mrb_uv_thread_init(mrb_state *mrb, mrb_value self) mrb_value b = mrb_nil_value(), opts; mrb_uv_thread* context = NULL; - mrb_get_args(mrb, "&|oH", &b, &thread_arg, opts); + mrb_get_args(mrb, "&|oH", &b, &thread_arg, &opts); context = (mrb_uv_thread*)mrb_malloc(mrb, sizeof(mrb_uv_thread)); context->mrb = mrb; From 3f026e0141d086e5981ce41a23567f04d5666698 Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Fri, 13 Dec 2019 03:46:14 +0900 Subject: [PATCH 08/13] Fix memory error --- src/handle.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/handle.c b/src/handle.c index dd553d4..28b7c9e 100644 --- a/src/handle.c +++ b/src/handle.c @@ -609,30 +609,29 @@ sockaddr_to_mrb(mrb_state *mrb, struct sockaddr *addr) { struct RClass *class_uv, *class_uv_ipaddr; struct RData *data; - mrb_value value_data, value_result; switch (addr->sa_family) { case AF_INET: case AF_INET6: class_uv = mrb_module_get(mrb, "UV"); if (addr->sa_family == AF_INET) { + struct sockaddr_in* ptr; class_uv_ipaddr = mrb_class_get_under(mrb, class_uv, "Ip4Addr"); - data = Data_Wrap_Struct( - mrb, mrb->object_class, - &mrb_uv_ip4addr_nofree_type, (void *) &addr); + ptr = mrb_malloc(mrb, sizeof(struct sockaddr_in)); + memcpy(ptr, addr, sizeof(struct sockaddr_in)); + data = Data_Wrap_Struct(mrb, class_uv_ipaddr, &mrb_uv_ip4addr_type, (void *)ptr); } else { + struct sockaddr_in6* ptr; class_uv_ipaddr = mrb_class_get_under(mrb, class_uv, "Ip6Addr"); - data = Data_Wrap_Struct( - mrb, mrb->object_class, - &mrb_uv_ip6addr_nofree_type, (void *) &addr); + ptr = mrb_malloc(mrb, sizeof(struct sockaddr_in6)); + memcpy(ptr, addr, sizeof(struct sockaddr_in6)); + data = Data_Wrap_Struct(mrb, class_uv_ipaddr, &mrb_uv_ip6addr_type, (void *)ptr); } - value_data = mrb_obj_value((void *) data); - value_result = mrb_class_new_instance(mrb, 1, &value_data, class_uv_ipaddr); break; default: mrb_assert(FALSE); } - return value_result; + return mrb_obj_value(data); } static mrb_value From 88c81cdcf6fba025b45bed07447ef82c4c3edf65 Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Fri, 13 Dec 2019 03:59:06 +0900 Subject: [PATCH 09/13] Add UV::FS#path test and fix callback error of UV::FS.open --- src/fs.c | 3 +-- test/callback.rb | 11 +++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/fs.c b/src/fs.c index 83e551d..9619548 100644 --- a/src/fs.c +++ b/src/fs.c @@ -277,7 +277,6 @@ _uv_fs_open_cb(uv_fs_t* uv_req) mrb_uv_file *file; args[0] = mrb_iv_get(mrb, req->instance, mrb_intern_lit(mrb, "fs_open")); - args[1] = mrb_uv_create_status(mrb, uv_req->result); mrb_iv_set(mrb, req->instance, mrb_intern_lit(mrb, "fs_open"), mrb_nil_value()); file = (mrb_uv_file*)DATA_PTR(args[0]); file->fd = uv_req->result; @@ -313,7 +312,7 @@ mrb_uv_fs_open(mrb_state *mrb, mrb_value self) mrb_uv_req_check_error(mrb, req, res); if (mrb_nil_p(req->block)) { context->fd = res; - mrb_iv_set(mrb, c, mrb_intern_lit(mrb, "path"), mrb_str_new_cstr(mrb, req->req.fs.path)); + mrb_iv_set(mrb, c, mrb_intern_lit(mrb, "path"), mrb_str_new_cstr(mrb, arg_filename)); return c; } mrb_iv_set(mrb, req->instance, mrb_intern_lit(mrb, "fs_open"), c); diff --git a/test/callback.rb b/test/callback.rb index e5d2612..4436666 100644 --- a/test/callback.rb +++ b/test/callback.rb @@ -45,13 +45,16 @@ def assert_uv(name, &block) test_str = 'helloworld' UV::FS.mkdir 'foo-bar' f = UV::FS.open 'foo-bar/foo.txt', UV::FS::O_CREAT|UV::FS::O_WRONLY, UV::FS::S_IWRITE | UV::FS::S_IREAD + assert_equal 'foo-bar/foo.txt', f.path f.write test_str f.close - f = UV::FS.open 'foo-bar/foo.txt', UV::FS::O_RDONLY, UV::FS::S_IREAD - assert_equal 'hello', f.read(5) - assert_equal test_str, f.read - f.close + UV::FS.open 'foo-bar/foo.txt', UV::FS::O_RDONLY, UV::FS::S_IREAD do |r| + assert_equal 'foo-bar/foo.txt', r.path + assert_equal 'hello', r.read(5) + assert_equal test_str, r.read + r.close + end remove_uv_test_tmpfile end From 93cf4a1e059b83bf7d0316008665b073e80b49a0 Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Fri, 13 Dec 2019 04:28:37 +0900 Subject: [PATCH 10/13] Fix FS.open handling --- src/fs.c | 1 + src/mrb_uv.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fs.c b/src/fs.c index 9619548..c4537d9 100644 --- a/src/fs.c +++ b/src/fs.c @@ -277,6 +277,7 @@ _uv_fs_open_cb(uv_fs_t* uv_req) mrb_uv_file *file; args[0] = mrb_iv_get(mrb, req->instance, mrb_intern_lit(mrb, "fs_open")); + args[1] = mrb_uv_create_status(mrb, uv_req->result); mrb_iv_set(mrb, req->instance, mrb_intern_lit(mrb, "fs_open"), mrb_nil_value()); file = (mrb_uv_file*)DATA_PTR(args[0]); file->fd = uv_req->result; diff --git a/src/mrb_uv.c b/src/mrb_uv.c index 41f4765..037595b 100644 --- a/src/mrb_uv.c +++ b/src/mrb_uv.c @@ -1159,7 +1159,6 @@ mrb_uv_create_status(mrb_state *mrb, int st) { if (st < 0) { return mrb_uv_create_error(mrb, st); } - mrb_assert(st == 0); return mrb_nil_value(); } From 6e06c74d876ac66bd56740602ace92bbbb8629ef Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Fri, 13 Dec 2019 04:56:28 +0900 Subject: [PATCH 11/13] Use 1.4.1 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 70df634..2b8848f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ env: - MRUBY_VERSION=1.2.0 - MRUBY_VERSION=1.3.0 - MRUBY_VERSION=1.4.0 - - MRUBY_VERSION=1.4.0 + - MRUBY_VERSION=1.4.1 - MRUBY_VERSION=2.0.0 - MRUBY_VERSION=2.1.0 before_script: From fd13561d14427164d94be9d69873e25215c0c60e Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Fri, 20 Dec 2019 11:00:55 +0900 Subject: [PATCH 12/13] Add some tests --- mrblib/yarn.rb | 6 +++++- src/mrb_uv.c | 2 +- test/uv.rb | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/mrblib/yarn.rb b/mrblib/yarn.rb index 729322c..419cd04 100644 --- a/mrblib/yarn.rb +++ b/mrblib/yarn.rb @@ -1,6 +1,10 @@ module UV def self.sleep sec - current_yarn.sleep sec + if UV.current_loop.current_yarn + current_yarn.sleep sec + else + UV.sleep_milli sec * 1000 + end end def self.quote cmd diff --git a/src/mrb_uv.c b/src/mrb_uv.c index 037595b..3c360d2 100644 --- a/src/mrb_uv.c +++ b/src/mrb_uv.c @@ -1869,7 +1869,7 @@ mrb_mruby_uv_gem_init(mrb_state* mrb) { mrb_define_module_function(mrb, _class_uv, "random", mrb_uv_random, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1)); #endif #if MRB_UV_CHECK_VERSION(1, 34, 0) - mrb_define_module_function(mrb, _class_uv, "sleep", mrb_uv_sleep, MRB_ARGS_REQ(1)); + mrb_define_module_function(mrb, _class_uv, "sleep_milli", mrb_uv_sleep, MRB_ARGS_REQ(1)); #endif mrb_define_const(mrb, _class_uv, "UV_RUN_DEFAULT", mrb_fixnum_value(UV_RUN_DEFAULT)); diff --git a/test/uv.rb b/test/uv.rb index 22e17b0..46f9d38 100644 --- a/test/uv.rb +++ b/test/uv.rb @@ -206,3 +206,36 @@ assert_kind_of Fixnum, p.uid assert_kind_of Fixnum, p.gid end + +assert 'UV.constrained_memory' do + skip unless UV.respond_to? :constrained_memory + assert_kind_of Fixnum, UV.constrained_memory +end + +assert 'UV.timeofday' do + skip unless UV.respond_to? :timeofday + assert_kind_of Time, UV.timeofday +end + +assert 'UV.sleep_milli' do + skip unless UV.respond_to? :sleep_milli + skip unless UV.respond_to? :timeofday + t = UV.timeofday + UV.sleep_milli 1 + assert_true (UV.timeofday - t) >= 0.001 +end + +assert 'UV::OS.environ' do + skip unless UV::OS.respond_to? :environ + assert_kind_of Hash, UV::OS.environ +end + +assert 'UV::OS.uname' do + skip unless UV::OS.respond_to? :uname + u = UV::OS.uname + assert_kind_of Hash, u + assert_kind_of String, u[:sysname] + assert_kind_of String, u[:release] + assert_kind_of String, u[:version] + assert_kind_of String, u[:machine] +end From 3248ca78348f97a59093cd2d7497c1ed368bc420 Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Mon, 20 Jan 2020 04:22:38 +0900 Subject: [PATCH 13/13] Fix condition of FS.open callback --- src/mrb_uv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mrb_uv.c b/src/mrb_uv.c index 3c360d2..3821ee4 100644 --- a/src/mrb_uv.c +++ b/src/mrb_uv.c @@ -861,7 +861,7 @@ mrb_uv_random(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "&i|H", &b, &len, &opts); buf = mrb_malloc(mrb, len); - if (mrb_nil_p(b)) { + if (!mrb_nil_p(b)) { cb = mrb_uv_random_cb; } req = mrb_uv_req_current(mrb, b, &ret);