Feature #9502 ยป remove-deprecates.diff
| bignum.c (working copy) | ||
|---|---|---|
|     return bignorm(val); | ||
| } | ||
| #define QUAD_SIZE 8 | ||
| void | ||
| rb_quad_pack(char *buf, VALUE val) | ||
| { | ||
|     rb_integer_pack(val, buf, 1, QUAD_SIZE, 0, | ||
|             INTEGER_PACK_NATIVE_BYTE_ORDER| | ||
|             INTEGER_PACK_2COMP); | ||
| } | ||
| VALUE | ||
| rb_quad_unpack(const char *buf, int signed_p) | ||
| { | ||
|     return rb_integer_unpack(buf, 1, QUAD_SIZE, 0, | ||
|             INTEGER_PACK_NATIVE_BYTE_ORDER| | ||
|             (signed_p ? INTEGER_PACK_2COMP : 0)); | ||
| } | ||
| #define conv_digit(c) (ruby_digit36_to_number_table[(unsigned char)(c)]) | ||
| static void | ||
| ... | ... | |
|     return base36_power_cache[base - 2][power_level]; | ||
| } | ||
| /* | ||
|  * deprecated.  (used only from deprecated rb_big2str0) | ||
|  * | ||
|  * big2str_muraken_find_n1 | ||
|  * | ||
|  * Let a natural number x is given by: | ||
|  * x = 2^0 * x_0 + 2^1 * x_1 + ... + 2^(B*n_0 - 1) * x_{B*n_0 - 1}, | ||
|  * where B is BITSPERDIG (i.e. BDIGITS*CHAR_BIT) and n_0 is | ||
|  * RBIGNUM_LEN(x). | ||
|  * | ||
|  * Now, we assume n_1 = min_n \{ n | 2^(B*n_0/2) <= b_1^(n_1) \}, so | ||
|  * it is realized that 2^(B*n_0) <= {b_1}^{2*n_1}, where b_1 is a | ||
|  * given radix number. And then, we have n_1 <= (B*n_0) / | ||
|  * (2*log_2(b_1)), therefore n_1 is given by ceil((B*n_0) / | ||
|  * (2*log_2(b_1))). | ||
|  */ | ||
| static long | ||
| big2str_find_n1(VALUE x, int base) | ||
| { | ||
|     static const double log_2[] = { | ||
| 	1.0,              1.58496250072116, 2.0, | ||
| 	2.32192809488736, 2.58496250072116, 2.8073549220576, | ||
| 	3.0,              3.16992500144231, 3.32192809488736, | ||
| 	3.4594316186373,  3.58496250072116, 3.70043971814109, | ||
| 	3.8073549220576,  3.90689059560852, 4.0, | ||
| 	4.08746284125034, 4.16992500144231, 4.24792751344359, | ||
| 	4.32192809488736, 4.39231742277876, 4.4594316186373, | ||
| 	4.52356195605701, 4.58496250072116, 4.64385618977472, | ||
| 	4.70043971814109, 4.75488750216347, 4.8073549220576, | ||
| 	4.85798099512757, 4.90689059560852, 4.95419631038688, | ||
| 	5.0,              5.04439411935845, 5.08746284125034, | ||
| 	5.12928301694497, 5.16992500144231 | ||
|     }; | ||
|     long bits; | ||
|     if (base < 2 || 36 < base) | ||
| 	rb_bug("invalid radix %d", base); | ||
|     if (FIXNUM_P(x)) { | ||
| 	bits = (SIZEOF_LONG*CHAR_BIT - 1)/2 + 1; | ||
|     } | ||
|     else if (BIGZEROP(x)) { | ||
| 	return 0; | ||
|     } | ||
|     else if (RBIGNUM_LEN(x) >= LONG_MAX/BITSPERDIG) { | ||
| 	rb_raise(rb_eRangeError, "bignum too big to convert into `string'"); | ||
|     } | ||
|     else { | ||
| 	bits = BITSPERDIG*RBIGNUM_LEN(x); | ||
|     } | ||
|     /* @shyouhei note: vvvvvvvvvvvvv this cast is suspicious.  But I believe it is OK, because if that cast loses data, this x value is too big, and should have raised RangeError. */ | ||
|     return (long)ceil(((double)bits)/log_2[base - 2]); | ||
| } | ||
| struct big2str_struct { | ||
|     int negative; | ||
|     int base; | ||
| ... | ... | |
|     return big2str_generic(x, base); | ||
| } | ||
| /* deprecated */ | ||
| VALUE | ||
| rb_big2str0(VALUE x, int base, int trim) | ||
| { | ||
|     VALUE str; | ||
|     long oldlen; | ||
|     long n2; | ||
|     str = rb_big2str1(x, base); | ||
|     if (trim || FIXNUM_P(x) || BIGZEROP(x)) | ||
|         return str; | ||
|     oldlen = RSTRING_LEN(str); | ||
|     if (oldlen && RSTRING_PTR(str)[0] != '-') { | ||
|         rb_str_resize(str, oldlen+1); | ||
|         MEMMOVE(RSTRING_PTR(str)+1, RSTRING_PTR(str), char, oldlen); | ||
|         RSTRING_PTR(str)[0] = '+'; | ||
|     } | ||
|     n2 = big2str_find_n1(x, base); | ||
|     oldlen = RSTRING_LEN(str); | ||
|     if (oldlen-1 < n2) { | ||
|         long off = n2 - (oldlen-1); | ||
|         rb_str_resize(str, n2+1); | ||
|         MEMMOVE(RSTRING_PTR(str)+1+off, RSTRING_PTR(str)+1, char, oldlen-1); | ||
|         memset(RSTRING_PTR(str)+1, '0', off); | ||
|     } | ||
|     RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0'; | ||
|     return str; | ||
| } | ||
| VALUE | ||
| rb_big2str(VALUE x, int base) | ||
| { | ||
| ... | ... | |
|     return num; | ||
| } | ||
| /* deprecated */ | ||
| VALUE | ||
| rb_big2ulong_pack(VALUE x) | ||
| { | ||
|     unsigned long num; | ||
|     rb_integer_pack(x, &num, 1, sizeof(num), 0, | ||
|         INTEGER_PACK_NATIVE_BYTE_ORDER|INTEGER_PACK_2COMP); | ||
|     return num; | ||
| } | ||
| VALUE | ||
| rb_big2ulong(VALUE x) | ||
| { | ||
| ext/-test-/old_thread_select/depend (working copy) | ||
|---|---|---|
| $(OBJS): $(HDRS) $(ruby_headers) \ | ||
|   $(hdrdir)/ruby/io.h \ | ||
|   $(hdrdir)/ruby/encoding.h \ | ||
|   $(hdrdir)/ruby/oniguruma.h | ||
| ext/-test-/old_thread_select/extconf.rb (working copy) | ||
|---|---|---|
| $warnflags = "-Wno-deprecated-declarations" | ||
| $warnflags = "" unless try_compile("", $warnflags) | ||
| create_makefile("-test-/old_thread_select/old_thread_select") | ||
| ext/-test-/old_thread_select/old_thread_select.c (working copy) | ||
|---|---|---|
| /* test case for deprecated C API */ | ||
| #include "ruby/ruby.h" | ||
| #include "ruby/io.h" | ||
| static fd_set * array2fdset(fd_set *fds, VALUE ary, int *max) | ||
| { | ||
|     long i; | ||
|     if (NIL_P(ary)) | ||
| 	return NULL; | ||
|     FD_ZERO(fds); | ||
|     Check_Type(ary, T_ARRAY); | ||
|     for (i = 0; i < RARRAY_LEN(ary); i++) { | ||
| 	VALUE val = RARRAY_PTR(ary)[i]; | ||
| 	int fd; | ||
| 	Check_Type(val, T_FIXNUM); | ||
| 	fd = FIX2INT(val); | ||
| 	if (fd >= *max) | ||
| 	    *max = fd + 1; | ||
| 	FD_SET(fd, fds); | ||
|     } | ||
|     return fds; | ||
| } | ||
| static void fdset2array(VALUE dst, fd_set *fds, int max) | ||
| { | ||
|     int i; | ||
|     rb_ary_clear(dst); | ||
|     for (i = 0; i < max; i++) { | ||
| 	if (FD_ISSET(i, fds)) | ||
| 	    rb_ary_push(dst, INT2NUM(i)); | ||
|     } | ||
| } | ||
| static VALUE | ||
| old_thread_select(VALUE klass, VALUE r, VALUE w, VALUE e, VALUE timeout) | ||
| { | ||
|     struct timeval tv; | ||
|     struct timeval *tvp = NULL; | ||
|     fd_set rfds, wfds, efds; | ||
|     fd_set *rp, *wp, *ep; | ||
|     int rc; | ||
|     int max = 0; | ||
|     if (!NIL_P(timeout)) { | ||
| 	tv = rb_time_timeval(timeout); | ||
| 	tvp = &tv; | ||
|     } | ||
|     rp = array2fdset(&rfds, r, &max); | ||
|     wp = array2fdset(&wfds, w, &max); | ||
|     ep = array2fdset(&efds, e, &max); | ||
|     rc = rb_thread_select(max, rp, wp, ep, tvp); | ||
|     if (rc == -1) | ||
| 	rb_sys_fail("rb_wait_for_single_fd"); | ||
|     if (rp) | ||
| 	fdset2array(r, &rfds, max); | ||
|     if (wp) | ||
| 	fdset2array(w, &wfds, max); | ||
|     if (ep) | ||
| 	fdset2array(e, &efds, max); | ||
|     return INT2NUM(rc); | ||
| } | ||
| void | ||
| Init_old_thread_select(void) | ||
| { | ||
|     rb_define_singleton_method(rb_cIO, "old_thread_select", | ||
|                                old_thread_select, 4); | ||
| } | ||
| ext/socket/rubysocket.h (working copy) | ||
|---|---|---|
| #include "constdefs.h" | ||
| #define BLOCKING_REGION(func, arg) (long)rb_thread_blocking_region((func), (arg), RUBY_UBF_IO, 0) | ||
| #define BLOCKING_REGION_FD(func, arg) (long)rb_thread_io_blocking_region((func), (arg), (arg)->fd) | ||
| #define SockAddrStringValue(v) rsock_sockaddr_string_value(&(v)) | ||
| gc.c (working copy) | ||
|---|---|---|
| } | ||
| void | ||
| rb_gc_set_params(void) | ||
| { | ||
|     ruby_gc_set_params(rb_safe_level()); | ||
| } | ||
| void | ||
| rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *data) | ||
| { | ||
|     rb_objspace_t *objspace = &rb_objspace; | ||
| include/ruby/backward/rubysig.h (working copy) | ||
|---|---|---|
| RUBY_SYMBOL_EXPORT_BEGIN | ||
| struct rb_blocking_region_buffer; | ||
| DEPRECATED(RUBY_EXTERN struct rb_blocking_region_buffer *rb_thread_blocking_region_begin(void)); | ||
| DEPRECATED(RUBY_EXTERN void rb_thread_blocking_region_end(struct rb_blocking_region_buffer *)); | ||
| #define TRAP_BEG do {struct rb_blocking_region_buffer *__region = rb_thread_blocking_region_begin(); | ||
| #define TRAP_END rb_thread_blocking_region_end(__region);} while (0) | ||
| #define RUBY_CRITICAL(statements) do {statements;} while (0) | ||
| #define DEFER_INTS (0) | ||
| #define ENABLE_INTS (1) | ||
| include/ruby/intern.h (working copy) | ||
|---|---|---|
| VALUE rb_cstr2inum(const char*, int); | ||
| VALUE rb_str2inum(VALUE, int); | ||
| VALUE rb_big2str(VALUE, int); | ||
| DEPRECATED(VALUE rb_big2str0(VALUE, int, int)); | ||
| SIGNED_VALUE rb_big2long(VALUE); | ||
| #define rb_big2int(x) rb_big2long(x) | ||
| VALUE rb_big2ulong(VALUE); | ||
| #define rb_big2uint(x) rb_big2ulong(x) | ||
| DEPRECATED(VALUE rb_big2ulong_pack(VALUE x)); | ||
| #if HAVE_LONG_LONG | ||
| LONG_LONG rb_big2ll(VALUE); | ||
| unsigned LONG_LONG rb_big2ull(VALUE); | ||
| #endif  /* HAVE_LONG_LONG */ | ||
| DEPRECATED(void rb_quad_pack(char*,VALUE)); | ||
| DEPRECATED(VALUE rb_quad_unpack(const char*,int)); | ||
| void rb_big_pack(VALUE val, unsigned long *buf, long num_longs); | ||
| VALUE rb_big_unpack(unsigned long *buf, long num_longs); | ||
| int rb_uv_to_utf8(char[6],unsigned long); | ||
| ... | ... | |
| int rb_thread_fd_writable(int); | ||
| void rb_thread_fd_close(int); | ||
| int rb_thread_alone(void); | ||
| DEPRECATED(void rb_thread_polling(void)); | ||
| void rb_thread_sleep(int); | ||
| void rb_thread_sleep_forever(void); | ||
| void rb_thread_sleep_deadly(void); | ||
| ... | ... | |
| VALUE rb_thread_run(VALUE); | ||
| VALUE rb_thread_kill(VALUE); | ||
| VALUE rb_thread_create(VALUE (*)(ANYARGS), void*); | ||
| DEPRECATED(int rb_thread_select(int, fd_set *, fd_set *, fd_set *, struct timeval *)); | ||
| int rb_thread_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *); | ||
| void rb_thread_wait_for(struct timeval); | ||
| VALUE rb_thread_current(void); | ||
| ... | ... | |
| VALUE rb_gc_enable(void); | ||
| VALUE rb_gc_disable(void); | ||
| VALUE rb_gc_start(void); | ||
| DEPRECATED(void rb_gc_set_params(void)); | ||
| VALUE rb_define_finalizer(VALUE, VALUE); | ||
| VALUE rb_undefine_finalizer(VALUE); | ||
| size_t rb_gc_count(void); | ||
| ... | ... | |
| /* process.c */ | ||
| void rb_last_status_set(int status, rb_pid_t pid); | ||
| VALUE rb_last_status_get(void); | ||
| struct rb_exec_arg { | ||
|     VALUE execarg_obj; | ||
| }; | ||
| DEPRECATED(int rb_proc_exec_n(int, VALUE*, const char*)); | ||
| int rb_proc_exec(const char*); | ||
| DEPRECATED(VALUE rb_exec_arg_init(int argc, VALUE *argv, int accept_shell, struct rb_exec_arg *e)); | ||
| DEPRECATED(int rb_exec_arg_addopt(struct rb_exec_arg *e, VALUE key, VALUE val)); | ||
| DEPRECATED(void rb_exec_arg_fixup(struct rb_exec_arg *e)); | ||
| DEPRECATED(int rb_run_exec_options(const struct rb_exec_arg *e, struct rb_exec_arg *s)); | ||
| DEPRECATED(int rb_run_exec_options_err(const struct rb_exec_arg *e, struct rb_exec_arg *s, char*, size_t)); | ||
| DEPRECATED(int rb_exec(const struct rb_exec_arg*)); | ||
| DEPRECATED(int rb_exec_err(const struct rb_exec_arg*, char*, size_t)); | ||
| DEPRECATED(rb_pid_t rb_fork(int*, int (*)(void*), void*, VALUE)); | ||
| DEPRECATED(rb_pid_t rb_fork_err(int*, int (*)(void*, char*, size_t), void*, VALUE, char*, size_t)); | ||
| VALUE rb_f_exec(int,VALUE*); | ||
| rb_pid_t rb_waitpid(rb_pid_t pid, int *status, int flags); | ||
| void rb_syswait(rb_pid_t pid); | ||
| ... | ... | |
| VALUE rb_struct_aref(VALUE, VALUE); | ||
| VALUE rb_struct_aset(VALUE, VALUE, VALUE); | ||
| VALUE rb_struct_getmember(VALUE, ID); | ||
| DEPRECATED(VALUE rb_struct_iv_get(VALUE, const char*)); | ||
| VALUE rb_struct_s_members(VALUE); | ||
| VALUE rb_struct_members(VALUE); | ||
| VALUE rb_struct_alloc_noinit(VALUE); | ||
| ... | ... | |
| void rb_thread_check_ints(void); | ||
| int rb_thread_interrupted(VALUE thval); | ||
| /* Use rb_thread_call_without_gvl family instead. */ | ||
| DEPRECATED(VALUE rb_thread_blocking_region(rb_blocking_function_t *func, void *data1, | ||
| 					   rb_unblock_function_t *ubf, void *data2)); | ||
| #define RUBY_UBF_IO ((rb_unblock_function_t *)-1) | ||
| #define RUBY_UBF_PROCESS ((rb_unblock_function_t *)-1) | ||
| VALUE rb_mutex_new(void); | ||
| include/ruby/io.h (working copy) | ||
|---|---|---|
| void rb_io_read_check(rb_io_t*); | ||
| int rb_io_read_pending(rb_io_t*); | ||
| DEPRECATED(void rb_read_check(FILE*)); | ||
| struct stat; | ||
| VALUE rb_stat_new(const struct stat *); | ||
| include/ruby/ruby.h (working copy) | ||
|---|---|---|
| #define StringValueCStr(v) rb_string_value_cstr(&(v)) | ||
| void rb_check_safe_obj(VALUE); | ||
| DEPRECATED(void rb_check_safe_str(VALUE)); | ||
| #define SafeStringValue(v) do {\ | ||
|     StringValue(v);\ | ||
|     rb_check_safe_obj(v);\ | ||
| } while (0) | ||
| /* obsolete macro - use SafeStringValue(v) */ | ||
| #define Check_SafeStr(v) rb_check_safe_str((VALUE)(v)) | ||
| VALUE rb_str_export(VALUE); | ||
| #define ExportStringValue(v) do {\ | ||
| include/ruby/win32.h (working copy) | ||
|---|---|---|
| == ***CAUTION*** | ||
| Since this function is very dangerous, ((*NEVER*)) | ||
| * lock any HANDLEs(i.e. Mutex, Semaphore, CriticalSection and so on) or, | ||
| * use anything like TRAP_BEG...TRAP_END block structure, | ||
| * use anything like rb_thread_call_without_gvl, | ||
| in asynchronous_func_t. | ||
| */ | ||
| typedef uintptr_t (*asynchronous_func_t)(uintptr_t self, int argc, uintptr_t* argv); | ||
| io.c (working copy) | ||
|---|---|---|
| #define argf_of(obj) (*(struct argf *)DATA_PTR(obj)) | ||
| #define ARGF argf_of(argf) | ||
| #ifdef _STDIO_USES_IOSTREAM  /* GNU libc */ | ||
| #  ifdef _IO_fpos_t | ||
| #    define STDIO_READ_DATA_PENDING(fp) ((fp)->_IO_read_ptr != (fp)->_IO_read_end) | ||
| #  else | ||
| #    define STDIO_READ_DATA_PENDING(fp) ((fp)->_gptr < (fp)->_egptr) | ||
| #  endif | ||
| #elif defined(FILE_COUNT) | ||
| #  define STDIO_READ_DATA_PENDING(fp) ((fp)->FILE_COUNT > 0) | ||
| #elif defined(FILE_READEND) | ||
| #  define STDIO_READ_DATA_PENDING(fp) ((fp)->FILE_READPTR < (fp)->FILE_READEND) | ||
| #elif defined(__BEOS__) || defined(__HAIKU__) | ||
| #  define STDIO_READ_DATA_PENDING(fp) ((fp)->_state._eof == 0) | ||
| #else | ||
| #  define STDIO_READ_DATA_PENDING(fp) (!feof(fp)) | ||
| #endif | ||
| #define GetWriteIO(io) rb_io_get_write_io(io) | ||
| #define READ_DATA_PENDING(fptr) ((fptr)->rbuf.len) | ||
| ... | ... | |
| } | ||
| void | ||
| rb_read_check(FILE *fp) | ||
| { | ||
|     if (!STDIO_READ_DATA_PENDING(fp)) { | ||
| 	rb_thread_wait_fd(fileno(fp)); | ||
|     } | ||
| } | ||
| void | ||
| rb_io_read_check(rb_io_t *fptr) | ||
| { | ||
|     if (!READ_DATA_PENDING(fptr)) { | ||
| process.c (working copy) | ||
|---|---|---|
| #endif | ||
| } | ||
| /* deprecated */ | ||
| static int | ||
| proc_exec_v(char **argv, const char *prog) | ||
| { | ||
|     char fbuf[MAXPATHLEN]; | ||
|     if (!prog) | ||
|         prog = argv[0]; | ||
|     prog = dln_find_exe_r(prog, 0, fbuf, sizeof(fbuf)); | ||
|     if (!prog) { | ||
|         errno = ENOENT; | ||
|         return -1; | ||
|     } | ||
|     before_exec(); | ||
|     execv(prog, argv); | ||
|     preserving_errno(try_with_sh(prog, argv, 0); after_exec()); | ||
|     return -1; | ||
| } | ||
| /* deprecated */ | ||
| int | ||
| rb_proc_exec_n(int argc, VALUE *argv, const char *prog) | ||
| { | ||
| #define ARGV_COUNT(n) ((n)+1) | ||
| #define ARGV_SIZE(n) (sizeof(char*) * ARGV_COUNT(n)) | ||
| #define ALLOC_ARGV(n, v) ALLOCV_N(char*, (v), ARGV_COUNT(n)) | ||
|     char **args; | ||
|     int i; | ||
|     int ret = -1; | ||
|     VALUE v; | ||
|     args = ALLOC_ARGV(argc+1, v); | ||
|     for (i=0; i<argc; i++) { | ||
| 	args[i] = RSTRING_PTR(argv[i]); | ||
|     } | ||
|     args[i] = 0; | ||
|     if (args[0]) { | ||
| 	ret = proc_exec_v(args, prog); | ||
|     } | ||
|     ALLOCV_END(v); | ||
|     return ret; | ||
| #undef ARGV_COUNT | ||
| #undef ARGV_SIZE | ||
| #undef ALLOC_ARGV | ||
| } | ||
| /* This function should be async-signal-safe.  Actually it is. */ | ||
| static int | ||
| proc_exec_sh(const char *str, VALUE envp_str) | ||
| ... | ... | |
|     return ST_CONTINUE; | ||
| } | ||
| int | ||
| rb_exec_arg_addopt(struct rb_exec_arg *e, VALUE key, VALUE val) | ||
| { | ||
|     return rb_execarg_addopt(e->execarg_obj, key, val); | ||
| } | ||
| static int | ||
| check_exec_options_i(st_data_t st_key, st_data_t st_val, st_data_t arg) | ||
| { | ||
| ... | ... | |
|     return ret; | ||
| } | ||
| VALUE | ||
| rb_exec_arg_init(int argc, VALUE *argv, int accept_shell, struct rb_exec_arg *e) | ||
| { | ||
|     return rb_execarg_init(argc, argv, accept_shell, e->execarg_obj); | ||
| } | ||
| void | ||
| rb_execarg_setenv(VALUE execarg_obj, VALUE env) | ||
| { | ||
| ... | ... | |
|     RB_GC_GUARD(execarg_obj); | ||
| } | ||
| void | ||
| rb_exec_arg_fixup(struct rb_exec_arg *e) | ||
| { | ||
|     rb_execarg_fixup(e->execarg_obj); | ||
| } | ||
| #if defined(__APPLE__) || defined(__HAIKU__) | ||
| static int rb_exec_without_timer_thread(const struct rb_execarg *eargp, char *errmsg, size_t errmsg_buflen); | ||
| #endif | ||
| /* | ||
|  *  call-seq: | ||
| ... | ... | |
| run_exec_pgroup(const struct rb_execarg *eargp, struct rb_execarg *sargp, char *errmsg, size_t errmsg_buflen) | ||
| { | ||
|     /* | ||
|      * If FD_CLOEXEC is available, rb_fork waits the child's execve. | ||
|      * So setpgid is done in the child when rb_fork is returned in the parent. | ||
|      * If FD_CLOEXEC is available, rb_fork_internal waits the child's execve. | ||
|      * So setpgid is done in the child when rb_fork_internal is returned in | ||
|      * the parent. | ||
|      * No race condition, even without setpgid from the parent. | ||
|      * (Is there an environment which has setpgid but no FD_CLOEXEC?) | ||
|      */ | ||
| ... | ... | |
|     return 0; | ||
| } | ||
| int | ||
| rb_run_exec_options_err(const struct rb_exec_arg *e, struct rb_exec_arg *s, char *errmsg, size_t errmsg_buflen) | ||
| { | ||
|     return rb_execarg_run_options(rb_execarg_get(e->execarg_obj), rb_execarg_get(s->execarg_obj), errmsg, errmsg_buflen); | ||
| } | ||
| int | ||
| rb_run_exec_options(const struct rb_exec_arg *e, struct rb_exec_arg *s) | ||
| { | ||
|     return rb_execarg_run_options(rb_execarg_get(e->execarg_obj), rb_execarg_get(s->execarg_obj), NULL, 0); | ||
| } | ||
| /* This function should be async-signal-safe.  Hopefully it is. */ | ||
| int | ||
| rb_exec_async_signal_safe(const struct rb_execarg *eargp, char *errmsg, size_t errmsg_buflen) | ||
| ... | ... | |
|     return -1; | ||
| } | ||
| #if defined(__APPLE__) || defined(__HAIKU__) | ||
| static int | ||
| rb_exec_without_timer_thread(const struct rb_execarg *eargp, char *errmsg, size_t errmsg_buflen) | ||
| { | ||
| ... | ... | |
|     preserving_errno(after_exec_non_async_signal_safe()); /* not async-signal-safe because it calls rb_thread_start_timer_thread.  */ | ||
|     return ret; | ||
| } | ||
| int | ||
| rb_exec_err(const struct rb_exec_arg *e, char *errmsg, size_t errmsg_buflen) | ||
| { | ||
|     return rb_exec_without_timer_thread(rb_execarg_get(e->execarg_obj), errmsg, errmsg_buflen); | ||
| } | ||
| int | ||
| rb_exec(const struct rb_exec_arg *e) | ||
| { | ||
| #if !defined FD_CLOEXEC && !defined HAVE_SPAWNV | ||
|     char errmsg[80] = { '\0' }; | ||
|     int ret = rb_exec_without_timer_thread(rb_execarg_get(e->execarg_obj), errmsg, sizeof(errmsg)); | ||
|     preserving_errno( | ||
| 	if (errmsg[0]) { | ||
| 	    fprintf(stderr, "%s\n", errmsg); | ||
| 	} | ||
| 	else { | ||
| 	    fprintf(stderr, "%s:%d: command not found: %s\n", | ||
| 		    rb_sourcefile(), rb_sourceline(), | ||
|                     RSTRING_PTR(e->use_shell ? e->invoke.sh.shell_script : e->invoke.cmd.command_name)); | ||
| 	} | ||
|     ); | ||
|     return ret; | ||
| #else | ||
|     return rb_exec_without_timer_thread(rb_execarg_get(e->execarg_obj), NULL, 0); | ||
| #endif | ||
| } | ||
| #ifdef HAVE_FORK | ||
| /* This function should be async-signal-safe.  Hopefully it is. */ | ||
| ... | ... | |
| } | ||
| rb_pid_t | ||
| rb_fork_err(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds, | ||
|         char *errmsg, size_t errmsg_buflen) | ||
| { | ||
|     return rb_fork_internal(status, chfunc, charg, FALSE, fds, errmsg, errmsg_buflen); | ||
| } | ||
| rb_pid_t | ||
| rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds, | ||
|         char *errmsg, size_t errmsg_buflen) | ||
| { | ||
|     return rb_fork_internal(status, chfunc, charg, TRUE, fds, errmsg, errmsg_buflen); | ||
| } | ||
| struct chfunc_wrapper_t { | ||
|     int (*chfunc)(void*); | ||
|     void *arg; | ||
| }; | ||
| static int | ||
| chfunc_wrapper(void *arg_, char *errmsg, size_t errmsg_buflen) | ||
| { | ||
|     struct chfunc_wrapper_t *arg = arg_; | ||
|     return arg->chfunc(arg->arg); | ||
| } | ||
| rb_pid_t | ||
| rb_fork(int *status, int (*chfunc)(void*), void *charg, VALUE fds) | ||
| { | ||
|     if (chfunc) { | ||
|         struct chfunc_wrapper_t warg; | ||
|         warg.chfunc = chfunc; | ||
|         warg.arg = charg; | ||
|         return rb_fork_internal(status, chfunc_wrapper, &warg, FALSE, fds, NULL, 0); | ||
|     } | ||
|     else { | ||
|         return rb_fork_internal(status, NULL, NULL, FALSE, fds, NULL, 0); | ||
|     } | ||
| } | ||
| rb_pid_t | ||
| rb_fork_ruby(int *status) | ||
| { | ||
| safe.c (working copy) | ||
|---|---|---|
| } | ||
| void | ||
| rb_check_safe_str(VALUE x) | ||
| { | ||
|     rb_check_safe_obj(x); | ||
|     if (!RB_TYPE_P(x, T_STRING)) { | ||
| 	rb_raise(rb_eTypeError, "wrong argument type %s (expected String)", | ||
| 		 rb_obj_classname(x)); | ||
|     } | ||
| } | ||
| void | ||
| Init_safe(void) | ||
| { | ||
|     rb_define_virtual_variable("$SAFE", safe_getter, safe_setter); | ||
| struct.c (working copy) | ||
|---|---|---|
| } | ||
| VALUE | ||
| rb_struct_iv_get(VALUE c, const char *name) | ||
| { | ||
|     return struct_ivar_get(c, rb_intern(name)); | ||
| } | ||
| VALUE | ||
| rb_struct_s_members(VALUE klass) | ||
| { | ||
|     VALUE members = struct_ivar_get(klass, id_members); | ||
| test/-ext-/old_thread_select/test_old_thread_select.rb (working copy) | ||
|---|---|---|
| require 'test/unit' | ||
| class TestOldThreadSelect < Test::Unit::TestCase | ||
|   require '-test-/old_thread_select/old_thread_select' | ||
|   ANCIENT_LINUX = RUBY_PLATFORM =~ /linux/ && `uname -r`.chomp < '2.6.32' | ||
|   DARWIN_10     = RUBY_PLATFORM =~ /darwin10/ | ||
|   WINDOWS       = RUBY_PLATFORM =~ /mswin|mingw/ | ||
|   def with_pipe | ||
|     r, w = IO.pipe | ||
|     begin | ||
|       yield r, w | ||
|     ensure | ||
|       r.close unless r.closed? | ||
|       w.close unless w.closed? | ||
|     end | ||
|   end | ||
|   def test_old_select_read_timeout | ||
|     with_pipe do |r, w| | ||
|       t0 = Time.now | ||
|       rc = IO.old_thread_select([r.fileno], nil, nil, 0.001) | ||
|       diff = Time.now - t0 | ||
|       assert_equal 0, rc | ||
|       assert_operator diff, :>=, 0.001, "returned too early: diff=#{diff}" | ||
|     end | ||
|   end unless ANCIENT_LINUX | ||
|   def test_old_select_error_timeout | ||
|     bug5299 = '[ruby-core:39380]' | ||
|     with_pipe do |r, w| | ||
|       t0 = Time.now | ||
|       rc = IO.old_thread_select(nil, nil, [r.fileno], 0.001) | ||
|       diff = Time.now - t0 | ||
|       assert_equal 0, rc, bug5299 | ||
|       assert_operator diff, :>=, 0.001, "returned too early: diff=#{diff}" | ||
|     end | ||
|   end unless ANCIENT_LINUX | ||
|   def test_old_select_false_positive | ||
|     bug5306 = '[ruby-core:39435]' | ||
|     with_pipe do |r2, w2| | ||
|       with_pipe do |r, w| | ||
|         t0 = Time.now | ||
|         w.syswrite '.' | ||
|         rfds = [ r.fileno, r2.fileno ] | ||
|         rc = IO.old_thread_select(rfds, nil, nil, nil) | ||
|         diff = Time.now - t0 | ||
|         assert_equal [ r.fileno ], rfds, bug5306 | ||
|         assert_equal 1, rc, bug5306 | ||
|         assert_operator diff, :>=, 0, "returned too early: diff=#{diff}" | ||
|       end | ||
|     end | ||
|   end | ||
|   def test_old_select_read_write_check | ||
|     with_pipe do |r, w| | ||
|       w.syswrite('.') | ||
|       rc = IO.old_thread_select([r.fileno], nil, nil, nil) | ||
|       assert_equal 1, rc | ||
|       rc = IO.old_thread_select([r.fileno], [w.fileno], nil, nil) | ||
|       assert_equal 2, rc | ||
|       assert_equal '.', r.read(1) | ||
|       rc = IO.old_thread_select([r.fileno], [w.fileno], nil, nil) | ||
|       assert_equal 1, rc | ||
|     end | ||
|   end | ||
|   def test_old_select_signal_safe | ||
|     return unless Process.respond_to?(:kill) | ||
|     received = false | ||
|     trap(:INT) { received = true } | ||
|     main = Thread.current | ||
|     thr = Thread.new do | ||
|       Thread.pass until main.stop? | ||
|       Process.kill(:INT, $$) | ||
|       true | ||
|     end | ||
|     rc = nil | ||
|     diff = nil | ||
|     with_pipe do |r,w| | ||
|       assert_nothing_raised do | ||
|         t0 = Time.now | ||
|         rc = IO.old_thread_select([r.fileno], nil, nil, 1) | ||
|         diff = Time.now - t0 | ||
|       end | ||
|     end | ||
|     unless ANCIENT_LINUX || DARWIN_10 || WINDOWS | ||
|       assert_operator diff, :>=, 1, "interrupted or short wait: diff=#{diff}" | ||
|     end | ||
|     assert_equal 0, rc | ||
|     assert_equal true, thr.value | ||
|     assert_not_equal false, received, "SIGINT not received" | ||
|   ensure | ||
|     trap(:INT, "DEFAULT") | ||
|   end | ||
| end | ||
| thread.c (working copy) | ||
|---|---|---|
|     sleep_timeval(th, double2timeval(sleepsec), spurious_check); | ||
| } | ||
| static void | ||
| sleep_for_polling(rb_thread_t *th) | ||
| { | ||
|     struct timeval time; | ||
|     time.tv_sec = 0; | ||
|     time.tv_usec = 100 * 1000;	/* 0.1 sec */ | ||
|     sleep_timeval(th, time, 1); | ||
| } | ||
| void | ||
| rb_thread_wait_for(struct timeval time) | ||
| { | ||
| ... | ... | |
|     sleep_timeval(th, time, 1); | ||
| } | ||
| void | ||
| rb_thread_polling(void) | ||
| { | ||
|     if (!rb_thread_alone()) { | ||
| 	rb_thread_t *th = GET_THREAD(); | ||
| 	RUBY_VM_CHECK_INTS_BLOCKING(th); | ||
| 	sleep_for_polling(th); | ||
|     } | ||
| } | ||
| /* | ||
|  * CAUTION: This function causes thread switching. | ||
|  *          rb_thread_check_ints() check ruby's interrupts. | ||
| ... | ... | |
|     } | ||
| } | ||
| struct rb_blocking_region_buffer * | ||
| rb_thread_blocking_region_begin(void) | ||
| { | ||
|     rb_thread_t *th = GET_THREAD(); | ||
|     struct rb_blocking_region_buffer *region = ALLOC(struct rb_blocking_region_buffer); | ||
|     blocking_region_begin(th, region, ubf_select, th, FALSE); | ||
|     return region; | ||
| } | ||
| void | ||
| rb_thread_blocking_region_end(struct rb_blocking_region_buffer *region) | ||
| { | ||
|     int saved_errno = errno; | ||
|     rb_thread_t *th = ruby_thread_from_native(); | ||
|     blocking_region_end(th, region); | ||
|     xfree(region); | ||
|     RUBY_VM_CHECK_INTS_BLOCKING(th); | ||
|     errno = saved_errno; | ||
| } | ||
| static void * | ||
| call_without_gvl(void *(*func)(void *), void *data1, | ||
| 		 rb_unblock_function_t *ubf, void *data2, int fail_if_interrupted) | ||
| ... | ... | |
|     return val; | ||
| } | ||
| VALUE | ||
| rb_thread_blocking_region( | ||
|     rb_blocking_function_t *func, void *data1, | ||
|     rb_unblock_function_t *ubf, void *data2) | ||
| { | ||
|     void *(*f)(void*) = (void *(*)(void*))func; | ||
|     return (VALUE)rb_thread_call_without_gvl(f, data1, ubf, data2); | ||
| } | ||
| /* | ||
|  * rb_thread_call_with_gvl - re-enter the Ruby world after GVL release. | ||
|  * | ||
|  * After releasing GVL using rb_thread_blocking_region() or | ||
|  * After releasing GVL using | ||
|  * rb_thread_call_without_gvl() you can not access Ruby values or invoke | ||
|  * methods. If you need to access Ruby you must use this function | ||
|  * rb_thread_call_with_gvl(). | ||
| ... | ... | |
|     memcpy(dst->fdset, src, size); | ||
| } | ||
| static void | ||
| rb_fd_rcopy(fd_set *dst, rb_fdset_t *src) | ||
| { | ||
|     size_t size = howmany(rb_fd_max(src), NFDBITS) * sizeof(fd_mask); | ||
|     if (size > sizeof(fd_set)) { | ||
| 	rb_raise(rb_eArgError, "too large fdsets"); | ||
|     } | ||
|     memcpy(dst, rb_fd_ptr(src), sizeof(fd_set)); | ||
| } | ||
| void | ||
| rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src) | ||
| { | ||
| ... | ... | |
|     rb_fd_dup(dst, src); | ||
| } | ||
| static void | ||
| rb_fd_rcopy(fd_set *dst, rb_fdset_t *src) | ||
| { | ||
|     int max = rb_fd_max(src); | ||
|     /* we assume src is the result of select() with dst, so dst should be | ||
|      * larger or equal than src. */ | ||
|     if (max > FD_SETSIZE || (UINT)max > dst->fd_count) { | ||
| 	rb_raise(rb_eArgError, "too large fdsets"); | ||
|     } | ||
|     memcpy(dst->fd_array, src->fdset->fd_array, max); | ||
|     dst->fd_count = max; | ||
| } | ||
| void | ||
| rb_fd_term(rb_fdset_t *set) | ||
| { | ||
| ... | ... | |
| #define FD_CLR(i, f)	rb_fd_clr((i), (f)) | ||
| #define FD_ISSET(i, f)	rb_fd_isset((i), (f)) | ||
| #else | ||
| #define rb_fd_rcopy(d, s) (*(d) = *(s)) | ||
| #endif | ||
| static int | ||
| ... | ... | |
| } | ||
| int | ||
| rb_thread_select(int max, fd_set * read, fd_set * write, fd_set * except, | ||
| 		 struct timeval *timeout) | ||
| { | ||
|     rb_fdset_t fdsets[3]; | ||
|     rb_fdset_t *rfds = NULL; | ||
|     rb_fdset_t *wfds = NULL; | ||
|     rb_fdset_t *efds = NULL; | ||
|     int retval; | ||
|     if (read) { | ||
| 	rfds = &fdsets[0]; | ||
| 	rb_fd_init(rfds); | ||
| 	rb_fd_copy(rfds, read, max); | ||
|     } | ||
|     if (write) { | ||
| 	wfds = &fdsets[1]; | ||
| 	rb_fd_init(wfds); | ||
| 	rb_fd_copy(wfds, write, max); | ||
|     } | ||
|     if (except) { | ||
| 	efds = &fdsets[2]; | ||
| 	rb_fd_init(efds); | ||
| 	rb_fd_copy(efds, except, max); | ||
|     } | ||
|     retval = rb_thread_fd_select(max, rfds, wfds, efds, timeout); | ||
|     if (rfds) { | ||
| 	rb_fd_rcopy(read, rfds); | ||
| 	rb_fd_term(rfds); | ||
|     } | ||
|     if (wfds) { | ||
| 	rb_fd_rcopy(write, wfds); | ||
| 	rb_fd_term(wfds); | ||
|     } | ||
|     if (efds) { | ||
| 	rb_fd_rcopy(except, efds); | ||
| 	rb_fd_term(efds); | ||
|     } | ||
|     return retval; | ||
| } | ||
| int | ||
| rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t * except, | ||
| 		    struct timeval *timeout) | ||
| { | ||