static void signal_exec(VALUE cmd, int safe, int sig) { rb_thread_t *cur_th = GET_THREAD(); volatile unsigned long old_interrupt_mask = cur_th->interrupt_mask; int state; /* * workaround the following race: * 1. signal_enque queues signal for execution * 2. user calls trap(sig, "IGNORE"), setting SIG_IGN * 3. rb_signal_exec runs on queued signal */ if (IMMEDIATE_P(cmd)) return; cur_th->interrupt_mask |= TRAP_INTERRUPT_MASK; TH_PUSH_TAG(cur_th); if ((state = EXEC_TAG()) == 0) { VALUE signum = INT2NUM(sig); rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe); } TH_POP_TAG(); cur_th = GET_THREAD(); cur_th->interrupt_mask = old_interrupt_mask; if (state) { /* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */ JUMP_TAG(state); } }
static char* rb_type_to_s(VALUE obj) { VALUE type; if (IMMEDIATE_P(obj)) { if (FIXNUM_P(obj)) return "T_FIXNUM"; if (obj == Qtrue) return "T_TRUE"; if (SYMBOL_P(obj)) return "T_SYMBOL"; if (obj == Qundef) return "T_UNDEF"; } else if (!RTEST(obj)) { if (obj == Qnil) return "T_NIL"; if (obj == Qfalse) return "T_FALSE"; } type = BUILTIN_TYPE(obj); switch(type) { case T_NONE: return "RUBY_T_NONE"; case T_NIL: return "RUBY_T_NIL"; case T_OBJECT: return "RUBY_T_OBJECT"; case T_CLASS: return "RUBY_T_CLASS"; case T_ICLASS: return "RUBY_T_ICLASS"; case T_MODULE: return "RUBY_T_MODULE"; case T_FLOAT: return "RUBY_T_FLOAT"; case T_STRING: return "RUBY_T_STRING"; case T_REGEXP: return "RUBY_T_REGEXP"; case T_ARRAY: return "RUBY_T_ARRAY"; case T_HASH: return "RUBY_T_HASH"; case T_STRUCT: return "RUBY_T_STRUCT"; case T_BIGNUM: return "RUBY_T_BIGNUM"; case T_FILE: return "RUBY_T_FILE"; case T_FIXNUM: return "RUBY_T_FIXNUM"; case T_TRUE: return "RUBY_T_TRUE"; case T_FALSE: return "RUBY_T_FALSE"; case T_DATA: return "RUBY_T_DATA"; case T_MATCH: return "RUBY_T_MATCH"; case T_SYMBOL: return "RUBY_T_SYMBOL"; case T_RATIONAL: return "RUBY_T_RATIONAL"; case T_COMPLEX: return "RUBY_T_COMPLEX"; case T_UNDEF: return "RUBY_T_UNDEF"; case T_NODE: return "RUBY_T_NODE"; case T_ZOMBIE: return "RUBY_T_ZOMBIE"; default: return "Unknown"; } }
static VALUE rhe_accept(VALUE self, VALUE fileno, VALUE timeoutv, VALUE tcp, VALUE env) { struct sockaddr_in cliaddr; unsigned int len; char read_buf[MAX_HEADER_SIZE]; VALUE req; int flag = 1; ssize_t rv = 0; ssize_t buf_len; ssize_t reqlen; int fd; double timeout = NUM2DBL(timeoutv); len = sizeof(cliaddr); fd = _accept(NUM2INT(fileno), (struct sockaddr *)&cliaddr, len); /* endif */ if (fd < 0) { goto badexit; } rv = _read_timeout(fd, timeout, &read_buf[0], MAX_HEADER_SIZE); if ( rv <= 0 ) { close(fd); goto badexit; } if ( IMMEDIATE_P(tcp) ) { setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int)); rb_hash_aset(env, remote_addr_key, rb_str_new2(inet_ntoa(cliaddr.sin_addr))); rb_hash_aset(env, remote_port_key, rb_String(rb_int_new(ntohs(cliaddr.sin_port)))); } else { rb_hash_aset(env, remote_addr_key, rb_str_new("",0)); rb_hash_aset(env, remote_port_key, rb_String(rb_int_new(0))); } buf_len = rv; while (1) { reqlen = _parse_http_request(&read_buf[0],buf_len,env); if ( reqlen >= 0 ) { break; } else if ( reqlen == -1 ) { /* error */ close(fd); goto badexit; } if ( MAX_HEADER_SIZE - buf_len == 0 ) { /* too large header */ char* badreq; badreq = BAD_REQUEST; rv = _write_timeout(fd, timeout, badreq, sizeof(BAD_REQUEST) - 1); close(fd); goto badexit; } /* request is incomplete */ rv = _read_timeout(fd, timeout, &read_buf[buf_len], MAX_HEADER_SIZE - buf_len); if ( rv <= 0 ) { close(fd); goto badexit; } buf_len += rv; } req = rb_ary_new2(3); rb_ary_push(req, rb_int_new(fd)); rb_ary_push(req, rb_str_new(&read_buf[reqlen],buf_len - reqlen)); return req; badexit: return Qnil; }