static void check_dirname(volatile VALUE *dir) { char *path, *pend; rb_secure(2); FilePathValue(*dir); path = RSTRING_PTR(*dir); if (path && *(pend = rb_path_end(rb_path_skip_prefix(path)))) { *dir = rb_str_new(path, pend - path); } }
/* * Document-method: setsockopt * call-seq: * setsockopt(level, optname, optval) * setsockopt(socketoption) * * Sets a socket option. These are protocol and system specific, see your * local system documentation for details. * * === Parameters * * +level+ is an integer, usually one of the SOL_ constants such as * Socket::SOL_SOCKET, or a protocol level. * A string or symbol of the name, possibly without prefix, is also * accepted. * * +optname+ is an integer, usually one of the SO_ constants, such * as Socket::SO_REUSEADDR. * A string or symbol of the name, possibly without prefix, is also * accepted. * * +optval+ is the value of the option, it is passed to the underlying * setsockopt() as a pointer to a certain number of bytes. How this is * done depends on the type: * - Fixnum: value is assigned to an int, and a pointer to the int is * passed, with length of sizeof(int). * - true or false: 1 or 0 (respectively) is assigned to an int, and the * int is passed as for a Fixnum. Note that +false+ must be passed, * not +nil+. * - String: the string's data and length is passed to the socket. * * +socketoption+ is an instance of Socket::Option * * === Examples * * Some socket options are integers with boolean values, in this case * #setsockopt could be called like this: * sock.setsockopt(:SOCKET, :REUSEADDR, true) * sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true) * sock.setsockopt(Socket::Option.bool(:INET, :SOCKET, :REUSEADDR, true)) * * Some socket options are integers with numeric values, in this case * #setsockopt could be called like this: * sock.setsockopt(:IP, :TTL, 255) * sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, 255) * sock.setsockopt(Socket::Option.int(:INET, :IP, :TTL, 255)) * * Option values may be structs. Passing them can be complex as it involves * examining your system headers to determine the correct definition. An * example is an +ip_mreq+, which may be defined in your system headers as: * struct ip_mreq { * struct in_addr imr_multiaddr; * struct in_addr imr_interface; * }; * * In this case #setsockopt could be called like this: * optval = IPAddr.new("224.0.0.251").hton + * IPAddr.new(Socket::INADDR_ANY, Socket::AF_INET).hton * sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, optval) * */ static VALUE bsock_setsockopt(int argc, VALUE *argv, VALUE sock) { UNRUBBY_SOCKET_HACK; VALUE lev, optname, val; int family, level, option; rb_io_t *fptr; int i; char *v; int vlen; if (argc == 1) { lev = rb_funcall(argv[0], rb_intern("level"), 0); optname = rb_funcall(argv[0], rb_intern("optname"), 0); val = rb_funcall(argv[0], rb_intern("data"), 0); } else { rb_scan_args(argc, argv, "30", &lev, &optname, &val); } rb_secure(2); GetOpenFile(sock, fptr); family = rsock_getfamily(fptr->fd); level = rsock_level_arg(family, lev); option = rsock_optname_arg(family, level, optname); switch (TYPE(val)) { case T_FIXNUM: i = FIX2INT(val); goto numval; case T_FALSE: i = 0; goto numval; case T_TRUE: i = 1; numval: v = (char*)&i; vlen = (int)sizeof(i); break; default: StringValue(val); v = RSTRING_PTR(val); vlen = RSTRING_LENINT(val); break; } #define rb_sys_fail_path(path) rb_sys_fail(NIL_P(path) ? 0 : RSTRING_PTR(path)) rb_io_check_closed(fptr); if (setsockopt(fptr->fd, level, option, v, vlen) < 0) rb_sys_fail_path(fptr->pathv); return INT2FIX(0); }
static VALUE env_size(VALUE rcv, SEL sel) { rb_secure(4); char **env = GET_ENVIRON(); int i = 0; while (env[i] != NULL) { i++; } return INT2FIX(i); }
static VALUE fcgi_stream_write(VALUE self, VALUE str) { FCGX_Stream *stream; int len; rb_secure(4); Data_Get_Struct(self, FCGX_Stream, stream); str = rb_obj_as_string(str); len = FCGX_PutStr(RSTRING_PTR(str), RSTRING_LEN(str), stream); if (len == EOF) CHECK_STREAM_ERROR(stream); return INT2NUM(len); }
/* * call-seq: * Dir.getwd => string * Dir.pwd => string * * Returns the path to the current working directory of this process as * a string. * * Dir.chdir("/tmp") #=> 0 * Dir.getwd #=> "/tmp" */ static VALUE dir_s_getwd(VALUE dir) { char *path; VALUE cwd; rb_secure(4); path = my_getcwd(); cwd = rb_tainted_str_new2(path); xfree(path); return cwd; }
static VALUE Surface_s_load(VALUE klass, VALUE filename) { SDL_Surface *surface; rb_secure(4); ExportFilenameStringValue(filename); surface = IMG_Load(RSTRING_PTR(filename)); if(surface == NULL) rb_raise(eSDLError,"Couldn't load %s: %s", RSTRING_PTR(filename), SDL_GetError()); return Surface_create(surface); }
static VALUE env_has_key(VALUE env, SEL sel, VALUE key) { rb_secure(4); const char *s = StringValuePtr(key); if (strlen(s) != RSTRING_LEN(key)) { rb_raise(rb_eArgError, "bad environment variable name"); } if (getenv(s) != NULL) { return Qtrue; } return Qfalse; }
static VALUE __rho_compile( VALUE obj, VALUE src) { VALUE result; rb_thread_t *th = GET_THREAD(); rb_secure(1); th->parse_in_eval++; result = rb_iseq_compile(src, rb_str_new2("(eval)"), INT2FIX(1)); th->parse_in_eval--; return result; }
void rb_undef(VALUE klass, ID id) { VALUE origin; NODE *body; if (rb_vm_cbase() == rb_cObject && klass == rb_cObject) { rb_secure(4); } if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) { rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'", rb_id2name(id)); } rb_frozen_class_p(klass); if (id == object_id || id == __send__ || id == idInitialize) { rb_warn("undefining `%s' may cause serious problem", rb_id2name(id)); } body = search_method(klass, id, &origin); if (!body || !body->nd_body) { const char *s0 = " class"; VALUE c = klass; if (FL_TEST(c, FL_SINGLETON)) { VALUE obj = rb_iv_get(klass, "__attached__"); switch (TYPE(obj)) { case T_MODULE: case T_CLASS: c = obj; s0 = ""; } } else if (TYPE(c) == T_MODULE) { s0 = " module"; } rb_name_error(id, "undefined method `%s' for%s `%s'", rb_id2name(id), s0, rb_class2name(c)); } rb_add_method(klass, id, 0, NOEX_PUBLIC); if (FL_TEST(klass, FL_SINGLETON)) { rb_funcall(rb_iv_get(klass, "__attached__"), singleton_undefined, 1, ID2SYM(id)); } else { rb_funcall(klass, undefined, 1, ID2SYM(id)); } }
/* * call-seq: * basicsocket.do_not_reverse_lookup = bool * * Sets the do_not_reverse_lookup flag of _basicsocket_. * * BasicSocket.do_not_reverse_lookup = false * p TCPSocket.new("127.0.0.1", 80).do_not_reverse_lookup #=> false * BasicSocket.do_not_reverse_lookup = true * p TCPSocket.new("127.0.0.1", 80).do_not_reverse_lookup #=> true * */ static VALUE bsock_do_not_reverse_lookup_set(VALUE sock, VALUE state) { rb_io_t *fptr; rb_secure(4); GetOpenFile(sock, fptr); if (RTEST(state)) { fptr->mode |= FMODE_NOREVLOOKUP; } else { fptr->mode &= ~FMODE_NOREVLOOKUP; } return sock; }
/* Returns information about the group with specified String name, as found * in /etc/group. * * The information is returned as a Struct::Group; see getgrent above for * details. * * e.g. Etc.getgrnam('users') -> #<struct Struct::Group name="users", * passwd="x", gid=100, mem=["meta", "root"]> * */ static VALUE etc_getgrnam(VALUE obj, VALUE nam) { #ifdef HAVE_GETGRENT struct group *grp; rb_secure(4); SafeStringValue(nam); grp = getgrnam(RSTRING_PTR(nam)); if (grp == 0) rb_raise(rb_eArgError, "can't find group for %s", RSTRING_PTR(nam)); return setup_group(grp); #else return Qnil; #endif }
static VALUE top_include(VALUE self, SEL sel, int argc, VALUE *argv) { #if 0 rb_thread_t *th = GET_THREAD(); rb_secure(4); if (th->top_wrapper) { rb_warning ("main#include in the wrapped load is effective only in wrapper module"); return rb_mod_include(argc, argv, th->top_wrapper); } #endif return rb_mod_include(rb_cObject, 0, argc, argv); }
static VALUE env_assoc(VALUE env, SEL sel, VALUE key) { rb_secure(4); const char *s = StringValuePtr(key); if (strlen(s) != RSTRING_LEN(key)) { rb_raise(rb_eArgError, "bad environment variable name"); } const char *e = getenv(s); if (e != NULL) { return rb_assoc_new(key, rb_tainted_str_new2(e)); } return Qnil; }
VALUE rb_dlcfunc_new(void (*func)(), int type, const char *name, ID calltype) { VALUE val; struct cfunc_data *data; rb_secure(4); if( func ){ val = TypedData_Make_Struct(rb_cDLCFunc, struct cfunc_data, &dlcfunc_data_type, data); data->ptr = func; data->name = name ? strdup(name) : NULL; data->type = type; data->calltype = calltype; } else{
VALUE rb_dlptr_new2(VALUE klass, void *ptr, long size, freefunc_t func) { struct ptr_data *data; VALUE val; rb_secure(4); val = TypedData_Make_Struct(klass, struct ptr_data, &dlptr_data_type, data); data->ptr = ptr; data->free = func; data->size = size; OBJ_TAINT(val); return val; }
/* Provides a convenient Ruby iterator which executes a block for each entry * in the /etc/passwd file. * * The code block is passed an Struct::Passwd struct; see getpwent above for * details. * * Example: * * require 'etc' * * Etc.passwd {|u| * puts u.name + " = " + u.gecos * } * */ static VALUE etc_passwd(VALUE obj) { #ifdef HAVE_GETPWENT struct passwd *pw; rb_secure(4); if (rb_block_given_p()) { each_passwd(); } else if (pw = getpwent()) { return setup_passwd(pw); } #endif return Qnil; }
/* * call-seq: * udpsocket.connect(host, port) => 0 * * Connects _udpsocket_ to _host_:_port_. * * This makes possible to send without destination address. * * u1 = UDPSocket.new * u1.bind("127.0.0.1", 4913) * u2 = UDPSocket.new * u2.connect("127.0.0.1", 4913) * u2.send "uuuu", 0 * p u1.recvfrom(10) #=> ["uuuu", ["AF_INET", 33230, "localhost", "127.0.0.1"]] * */ static VALUE udp_connect(VALUE sock, VALUE host, VALUE port) { rb_io_t *fptr; struct udp_arg arg; VALUE ret; rb_secure(3); arg.res = rsock_addrinfo(host, port, SOCK_DGRAM, 0); GetOpenFile(sock, fptr); arg.fd = fptr->fd; ret = rb_ensure(udp_connect_internal, (VALUE)&arg, rsock_freeaddrinfo, (VALUE)arg.res); if (!ret) rsock_sys_fail_host_port("connect(2)", host, port); return INT2FIX(0); }
/* Closes the syslog facility. * Raises a runtime exception if it is not open. */ static VALUE mSyslog_close(VALUE self) { rb_secure(4); if (!syslog_opened) { rb_raise(rb_eRuntimeError, "syslog not opened"); } closelog(); free((void *)syslog_ident); syslog_ident = NULL; syslog_options = syslog_facility = syslog_mask = -1; syslog_opened = 0; return Qnil; }
/* Provides a convenient Ruby iterator which executes a block for each entry * in the /etc/group file. * * The code block is passed an Struct::Group struct; see getgrent above for * details. * * Example: * * require 'etc' * * Etc.group {|g| * puts g.name + ": " + g.mem.join(', ') * } * */ static VALUE etc_group(VALUE obj) { #ifdef HAVE_GETGRENT struct group *grp; rb_secure(4); if (rb_block_given_p()) { each_group(); } else if (grp = getgrent()) { return setup_group(grp); } #endif return Qnil; }
static VALUE env_values(VALUE rcv, SEL sel) { rb_secure(4); VALUE ary = rb_ary_new(); char **env = GET_ENVIRON(); while (*env != NULL) { const char *s = strchr(*env, '='); if (s != NULL) { rb_ary_push(ary, env_str_new2(s + 1)); } env++; } return ary; }
static VALUE thread_set_trace_func_m(VALUE obj, VALUE trace) { rb_thread_t *th; rb_secure(4); GetThreadPtr(obj, th); rb_threadptr_remove_event_hook(th, call_trace_func, Qundef); if (NIL_P(trace)) { return Qnil; } thread_add_trace_func(th, trace); return trace; }
static void rb_export_method(VALUE klass, ID name, ID noex) { rb_vm_method_node_t *node; SEL sel; if (klass == rb_cObject) { rb_secure(4); } if (!rb_vm_lookup_method2((Class)klass, name, &sel, NULL, &node)) { if (TYPE(klass) != T_MODULE || !rb_vm_lookup_method2((Class)rb_cObject, name, &sel, NULL, &node)) { rb_print_undef(klass, name, 0); } } if (node == NULL) { rb_raise(rb_eRuntimeError, "can't change visibility of non Ruby method `%s'", sel_getName(sel)); } long flags = (node->flags & ~VM_METHOD_PRIVATE) & ~VM_METHOD_PROTECTED; switch (noex) { case NOEX_PRIVATE: flags |= VM_METHOD_PRIVATE; break; case NOEX_PROTECTED: flags |= VM_METHOD_PROTECTED; break; default: break; } if (node->flags != flags) { if (node->klass == (Class)klass) { node->flags = flags; } else { rb_vm_define_method2((Class)klass, sel, node, flags, false); } } }
/* Package helper routines */ static void syslog_write(int pri, int argc, VALUE *argv) { VALUE str; rb_secure(4); if (argc < 1) { rb_raise(rb_eArgError, "no log message supplied"); } if (!syslog_opened) { rb_raise(rb_eRuntimeError, "must open syslog before write"); } str = rb_f_sprintf(argc, argv); syslog(pri, "%s", RSTRING_PTR(str)); }
void rb_undef(VALUE klass, ID id) { if (klass == rb_cObject) { rb_secure(4); } if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(klass)) { rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'", rb_id2name(id)); } rb_frozen_class_p(klass); if (id == object_id || id == __send__ || id == idInitialize) { rb_warn("undefining `%s' may cause serious problem", rb_id2name(id)); } rb_vm_undef_method((Class)klass, id, true); }
VALUE rb_tracepoint_disable(VALUE tpval) { rb_tp_t *tp; rb_secure(4); tp = tpptr(tpval); if (tp->target_th) { rb_thread_remove_event_hook_with_data(tp->target_th->self, (rb_event_hook_func_t)tp_call_trace, tpval); } else { rb_remove_event_hook_with_data((rb_event_hook_func_t)tp_call_trace, tpval); } tp->tracing = 0; return Qundef; }
/* * call-seq: * remove_features(mod) => mod * * When this module is unincluded from another, Ruby Internal calls * remove_features in this module. The default behavior is to remove * the constants, methods, and module variables of this module from * _mod_. If this module has not been included by _mod_, an exception * will be raised. */ static VALUE module_remove_features(VALUE module, VALUE uninclude) { VALUE prev, mod; if(TYPE(uninclude) != T_CLASS && TYPE(uninclude) != T_MODULE) { Check_Type(uninclude, T_CLASS); } rb_frozen_class_p(uninclude); if(!OBJ_TAINTED(uninclude)) { rb_secure(4); } OBJ_INFECT(uninclude, module); if(RCLASS(uninclude)->m_tbl == RCLASS(module)->m_tbl) { rb_raise(rb_eArgError, "Cannot remove module from itself"); } prev = uninclude; mod = RCLASS_SUPER(uninclude); while(mod) { if(RCLASS(module)->m_tbl == RCLASS(mod)->m_tbl) { RCLASS_SUPER(prev) = RCLASS_SUPER(mod); rb_clear_cache(); return module; } if(BUILTIN_TYPE(mod) == T_CLASS) { break; } prev = mod; mod = RCLASS_SUPER(mod); } rb_raise(rb_eArgError, "Could not find included module"); return module; }
/* Returns the short user name of the currently logged in user. * Unfortunately, it is often rather easy to fool getlogin(). * Avoid getlogin() for security-related purposes. * * e.g. * Etc.getlogin -> 'guest' */ static VALUE etc_getlogin(VALUE obj) { char *login; rb_secure(4); #ifdef HAVE_GETLOGIN login = getlogin(); if (!login) login = getenv("USER"); #else login = getenv("USER"); #endif if (login) return rb_tainted_str_new2(login); return Qnil; }
static VALUE readline_buffer_ext(VALUE self, VALUE str){ rb_secure(4); StringValue(str); if(rl_line_buffer == NULL) return Qnil; #ifdef HAVE_RL_DELETE_TEXT rl_delete_text(0, rl_end); #else rl_line_buffer[rl_end = 0] = '\0'; #endif rl_insert_text(RSTRING_PTR(str)); rl_redisplay(); return rb_str_new(rl_line_buffer, strlen(rl_line_buffer)); }
VALUE rb_dlhandle_sym(VALUE self, VALUE sym) { struct dl_handle *dlhandle; const char *name; rb_secure(2); name = StringValuePtr(sym); TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle); if( ! dlhandle->open ){ rb_raise(rb_eDLError, "closed handle"); } return dlhandle_sym(dlhandle->ptr, StringValueCStr(sym)); }
void rb_include_module(VALUE klass, VALUE module) { VALUE p, c; int changed = 0; rb_frozen_class_p(klass); if (!OBJ_UNTRUSTED(klass)) { rb_secure(4); } if (TYPE(module) != T_MODULE) { Check_Type(module, T_MODULE); } OBJ_INFECT(klass, module); c = klass; while (module) { int superclass_seen = FALSE; if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module)) rb_raise(rb_eArgError, "cyclic include detected"); /* ignore if the module included already in superclasses */ for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) { switch (BUILTIN_TYPE(p)) { case T_ICLASS: if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) { if (!superclass_seen) { c = p; /* move insertion point */ } goto skip; } break; case T_CLASS: superclass_seen = TRUE; break; } } c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c)); if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries) changed = 1; skip: module = RCLASS_SUPER(module); } if (changed) rb_clear_cache(); }