aboutsummaryrefslogtreecommitdiff
path: root/lang/ruby18
diff options
context:
space:
mode:
authorStanislav Sedov <stas@FreeBSD.org>2007-07-10 15:04:49 +0000
committerStanislav Sedov <stas@FreeBSD.org>2007-07-10 15:04:49 +0000
commit889c289308d269f333481e061e95f791a4afb1b0 (patch)
treed5c648da54f8de327ac302f7cbf23fce759caf66 /lang/ruby18
parent6738a6da108a0cbe311a22296e69c4bc8e8bbc46 (diff)
downloadports-889c289308d269f333481e061e95f791a4afb1b0.tar.gz
ports-889c289308d269f333481e061e95f791a4afb1b0.zip
Notes
Diffstat (limited to 'lang/ruby18')
-rw-r--r--lang/ruby18/Makefile3
-rw-r--r--lang/ruby18/files/patch-bignum.c111
-rw-r--r--lang/ruby18/files/patch-dir.c41
-rw-r--r--lang/ruby18/files/patch-eval.c270
-rw-r--r--lang/ruby18/files/patch-ext_bigdecimal_bigdecimal.c11
-rw-r--r--lang/ruby18/files/patch-ext_dl_dl.c11
-rw-r--r--lang/ruby18/files/patch-ext_etc_etc.c11
-rw-r--r--lang/ruby18/files/patch-ext_thread_thread.c270
-rw-r--r--lang/ruby18/files/patch-ext_tk_lib_tkextlib_tcllib_tablelist.rb9
-rw-r--r--lang/ruby18/files/patch-ext_tk_lib_tkextlib_tile_dialog.rb11
-rw-r--r--lang/ruby18/files/patch-intern.h16
-rw-r--r--lang/ruby18/files/patch-lib_cgi.rb10
-rw-r--r--lang/ruby18/files/patch-lib_monitor.rb46
-rw-r--r--lang/ruby18/files/patch-lib_net_imap.rb15
-rw-r--r--lang/ruby18/files/patch-process.c10
-rw-r--r--lang/ruby18/files/patch-util.c13
16 files changed, 857 insertions, 1 deletions
diff --git a/lang/ruby18/Makefile b/lang/ruby18/Makefile
index ca53811b4cff..444c5b3da839 100644
--- a/lang/ruby18/Makefile
+++ b/lang/ruby18/Makefile
@@ -44,8 +44,9 @@ OPTIONS= PTHREADS "Enable pthreads support (may break some apps)" off \
.include <bsd.port.pre.mk>
-# PORTEPOCH hack
+# PORTEPOCH/PORTREVISION hack
_SUF2= ,${PORTEPOCH}
+_SUF1= _${PORTREVISION}
PKGNAMESUFFIX= #empty
CFLAGS+= ${PTHREAD_CFLAGS} # Keep this, else ruby will fail to load
diff --git a/lang/ruby18/files/patch-bignum.c b/lang/ruby18/files/patch-bignum.c
new file mode 100644
index 000000000000..570101c49640
--- /dev/null
+++ b/lang/ruby18/files/patch-bignum.c
@@ -0,0 +1,111 @@
+--- bignum.c.orig Tue Feb 13 02:01:19 2007
++++ bignum.c Wed May 23 00:37:49 2007
+@@ -96,35 +96,49 @@
+ }
+
+ static VALUE
+-bignorm(x)
++bigtrunc(x)
+ VALUE x;
+ {
+- if (FIXNUM_P(x)) {
+- return x;
+- }
+- else if (TYPE(x) == T_BIGNUM) {
+- long len = RBIGNUM(x)->len;
+- BDIGIT *ds = BDIGITS(x);
+-
+- while (len-- && !ds[len]) ;
+- RBIGNUM(x)->len = ++len;
+-
+- if (len*SIZEOF_BDIGITS <= sizeof(VALUE)) {
+- long num = 0;
+- while (len--) {
+- num = BIGUP(num) + ds[len];
++ long len = RBIGNUM(x)->len;
++ BDIGIT *ds = BDIGITS(x);
++
++ while (len-- && !ds[len]);
++ RBIGNUM(x)->len = ++len;
++ return x;
++}
++
++static VALUE
++bigfixize(VALUE x)
++{
++ long len = RBIGNUM(x)->len;
++ BDIGIT *ds = BDIGITS(x);
++
++ if (len*SIZEOF_BDIGITS <= sizeof(VALUE)) {
++ long num = 0;
++ while (len--) {
++ num = BIGUP(num) + ds[len];
++ }
++ if (num >= 0) {
++ if (RBIGNUM(x)->sign) {
++ if (POSFIXABLE(num)) return LONG2FIX(num);
+ }
+- if (num >= 0) {
+- if (RBIGNUM(x)->sign) {
+- if (POSFIXABLE(num)) return LONG2FIX(num);
+- }
+- else if (NEGFIXABLE(-(long)num)) return LONG2FIX(-(long)num);
++ else {
++ if (NEGFIXABLE(-(long)num)) return LONG2FIX(-(long)num);
+ }
+ }
+ }
+ return x;
+ }
+
++static VALUE
++bignorm(VALUE x)
++{
++ if (!FIXNUM_P(x) && TYPE(x) == T_BIGNUM) {
++ x = bigfixize(bigtrunc(x));
++ }
++ return x;
++}
++
+ VALUE
+ rb_big_norm(x)
+ VALUE x;
+@@ -642,10 +656,10 @@
+ j = j * 53L / 84 + 1;
+ break;
+ case 4: case 5: case 6: case 7:
+- j /= 2;
++ j = (j + 1) / 2;
+ break;
+ case 8: case 9:
+- j /= 3;
++ j = (j + 2) / 3;
+ break;
+ case 10: case 11: case 12: case 13: case 14: case 15:
+ j = j * 28L / 93 + 1;
+@@ -653,10 +667,10 @@
+ case 16: case 17: case 18: case 19: case 20: case 21:
+ case 22: case 23: case 24: case 25: case 26: case 27:
+ case 28: case 29: case 30: case 31:
+- j /= 4;
++ j = (j + 3) / 4;
+ break;
+ case 32: case 33: case 34: case 35: case 36:
+- j /= 5;
++ j = (j + 4) / 5;
+ break;
+ default:
+ rb_raise(rb_eArgError, "illegal radix %d", base);
+@@ -1641,10 +1655,10 @@
+ while (yy % 2 == 0) {
+ yy /= 2;
+ x = rb_big_mul0(x, x);
+- if (!BDIGITS(x)[RBIGNUM(x)->len-1]) RBIGNUM(x)->len--;
++ bigtrunc(x);
+ }
+ z = rb_big_mul0(z, x);
+- if (!BDIGITS(z)[RBIGNUM(z)->len-1]) RBIGNUM(z)->len--;
++ bigtrunc(z);
+ }
+ return bignorm(z);
+ }
diff --git a/lang/ruby18/files/patch-dir.c b/lang/ruby18/files/patch-dir.c
new file mode 100644
index 000000000000..f8c491e965e2
--- /dev/null
+++ b/lang/ruby18/files/patch-dir.c
@@ -0,0 +1,41 @@
+--- dir.c.orig Sat Feb 24 10:55:06 2007
++++ dir.c Tue May 22 23:22:14 2007
+@@ -958,13 +958,19 @@
+ #define GLOB_ALLOC_N(type, n) (type *)malloc(sizeof(type) * (n))
+ #define GLOB_JUMP_TAG(status) ((status == -1) ? rb_memerror() : rb_jump_tag(status))
+
++/*
++ * ENOTDIR can be returned by stat(2) if a non-leaf element of the path
++ * is not a directory.
++ */
++#define to_be_ignored(e) ((e) == ENOENT || (e) == ENOTDIR)
++
+ /* System call with warning */
+ static int
+ do_stat(const char *path, struct stat *pst, int flags)
+
+ {
+ int ret = stat(path, pst);
+- if (ret < 0 && errno != ENOENT)
++ if (ret < 0 && !to_be_ignored(errno))
+ sys_warning(path);
+
+ return ret;
+@@ -974,7 +980,7 @@
+ do_lstat(const char *path, struct stat *pst, int flags)
+ {
+ int ret = lstat(path, pst);
+- if (ret < 0 && errno != ENOENT)
++ if (ret < 0 && !to_be_ignored(errno))
+ sys_warning(path);
+
+ return ret;
+@@ -984,7 +990,7 @@
+ do_opendir(const char *path, int flags)
+ {
+ DIR *dirp = opendir(path);
+- if (dirp == NULL && errno != ENOENT && errno != ENOTDIR)
++ if (dirp == NULL && !to_be_ignored(errno))
+ sys_warning(path);
+
+ return dirp;
diff --git a/lang/ruby18/files/patch-eval.c b/lang/ruby18/files/patch-eval.c
new file mode 100644
index 000000000000..5f4cbc6d3008
--- /dev/null
+++ b/lang/ruby18/files/patch-eval.c
@@ -0,0 +1,270 @@
+--- eval.c.orig Sun Mar 11 11:31:53 2007
++++ eval.c Fri Jun 8 13:33:59 2007
+@@ -1562,11 +1565,15 @@
+ int ex;
+ {
+ int state;
+- volatile VALUE err = ruby_errinfo;
++ VALUE err;
++ volatile VALUE errs[2];
++ int nerr;
+
++ errs[0] = ruby_errinfo;
+ ruby_safe_level = 0;
+ Init_stack((void*)&state);
+ ruby_finalize_0();
++ errs[1] = ruby_errinfo;
+ PUSH_TAG(PROT_NONE);
+ PUSH_ITER(ITER_NOT);
+ if ((state = EXEC_TAG()) == 0) {
+@@ -1577,15 +1584,15 @@
+ ex = state;
+ }
+ POP_ITER();
+- ruby_errinfo = err;
++ ruby_errinfo = errs[0];
+ ex = error_handle(ex);
+ ruby_finalize_1();
+ POP_TAG();
+
+- if (err) {
++ for (nerr = sizeof(errs) / sizeof(errs[0]); nerr;) {
++ if (!(err = errs[--nerr])) continue;
+ if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
+- VALUE st = rb_iv_get(err, "status");
+- return NUM2INT(st);
++ return sysexit_status(err);
+ }
+ else if (rb_obj_is_kind_of(err, rb_eSignal)) {
+ VALUE sig = rb_iv_get(err, "signo");
+@@ -1855,7 +1862,7 @@
+ POP_TAG();
+ POP_FRAME();
+
+- jump_tag_but_local_jump(state, val);
++ if (state) jump_tag_but_local_jump(state, val);
+ return val;
+ }
+
+@@ -3494,6 +3501,10 @@
+ }
+ argv = RARRAY(RBASIC(ruby_scope)->klass)->ptr;
+ }
++ else if (!ruby_scope->local_vars) {
++ argc = 0;
++ argv = 0;
++ }
+ else {
+ argv = ruby_scope->local_vars + 2;
+ }
+@@ -4998,8 +5009,10 @@
+ CHECK_INTS;
+ goto redo;
+ case TAG_NEXT:
+- state = 0;
+- result = prot_tag->retval;
++ if (!lambda) {
++ state = 0;
++ result = prot_tag->retval;
++ }
+ break;
+ case TAG_BREAK:
+ if (TAG_DST()) {
+@@ -7017,7 +7030,8 @@
+ return Qfalse;
+ }
+ else if (IS_SOEXT(ext) || IS_DLEXT(ext)) {
+- return Qfalse; /* may be overriden by .rb file */
++ if (rb_feature_p(feature, ext, Qfalse)) return Qtrue;
++ return Qfalse;
+ }
+ }
+ if (rb_feature_p(feature, feature + strlen(feature), Qtrue))
+@@ -8597,6 +8611,7 @@
+ proc_jump_error(TAG_RETRY, Qnil); /* xxx */
+ JUMP_TAG(state);
+ break;
++ case TAG_NEXT:
+ case TAG_BREAK:
+ if (!pcall && result != Qundef) {
+ proc_jump_error(state, result);
+@@ -8966,7 +8981,6 @@
+ (FL_TEST(rklass, FL_SINGLETON) || TYPE(rklass) == T_ICLASS)) {
+ rklass = RCLASS(rklass)->super;
+ }
+- if (TYPE(klass) == T_ICLASS) klass = RBASIC(klass)->klass;
+ method = Data_Make_Struct(mklass, struct METHOD, bm_mark, free, data);
+ data->klass = klass;
+ data->recv = obj;
+@@ -9441,8 +9455,12 @@
+ else {
+ rb_str_buf_cat2(str, rb_class2name(data->rklass));
+ if (data->rklass != data->klass) {
++ VALUE klass = data -> klass;
++ if (TYPE(klass) == T_ICLASS) {
++ klass = RBASIC(klass)->klass;
++ }
+ rb_str_buf_cat2(str, "(");
+- rb_str_buf_cat2(str, rb_class2name(data->klass));
++ rb_str_buf_cat2(str, rb_class2name(klass));
+ rb_str_buf_cat2(str, ")");
+ }
+ }
+@@ -11201,10 +11217,19 @@
+ rb_thread_wakeup(thread)
+ VALUE thread;
+ {
++ if (!RTEST(rb_thread_wakeup_alive(thread)))
++ rb_raise(rb_eThreadError, "killed thread");
++ return thread;
++}
++
++VALUE
++rb_thread_wakeup_alive(thread)
++ VALUE thread;
++{
+ rb_thread_t th = rb_thread_check(thread);
+
+ if (th->status == THREAD_KILLED)
+- rb_raise(rb_eThreadError, "killed thread");
++ return Qnil;
+ rb_thread_ready(th);
+
+ return thread;
+@@ -11630,6 +11657,15 @@
+ }
+
+
++enum thread_status
++rb_thread_status(thread)
++ VALUE thread;
++{
++ rb_thread_t th = rb_thread_check(thread);
++ return th->status;
++}
++
++
+ /*
+ * call-seq:
+ * thr.group => thgrp or nil
+@@ -11736,21 +11772,36 @@
+ /* cause EINTR */
+ }
+
++static int time_thread_alive_p = 0;
+ static pthread_t time_thread;
+
+ static void*
+ thread_timer(dummy)
+ void *dummy;
+ {
++#ifdef _THREAD_SAFE
++#define test_cancel() pthread_testcancel()
++#else
++#define test_cancel() /* void */
++#endif
++
++ sigset_t all_signals;
++
++ sigfillset(&all_signals);
++ pthread_sigmask(SIG_BLOCK, &all_signals, 0);
++
+ for (;;) {
+ #ifdef HAVE_NANOSLEEP
+ struct timespec req, rem;
+
++ test_cancel();
+ req.tv_sec = 0;
+ req.tv_nsec = 10000000;
+ nanosleep(&req, &rem);
+ #else
+ struct timeval tv;
++
++ test_cancel();
+ tv.tv_sec = 0;
+ tv.tv_usec = 10000;
+ select(0, NULL, NULL, NULL, &tv);
+@@ -11762,6 +11813,7 @@
+ }
+ }
+ }
++#undef test_cancel
+ }
+
+ void
+@@ -11773,6 +11825,20 @@
+ rb_thread_stop_timer()
+ {
+ }
++
++void
++rb_thread_cancel_timer()
++{
++#ifdef _THREAD_SAFE
++ if( time_thread_alive_p )
++ {
++ pthread_cancel( time_thread );
++ pthread_join( time_thread, NULL );
++ time_thread_alive_p = 0;
++ }
++ thread_init = 0;
++#endif
++}
+ #elif defined(HAVE_SETITIMER)
+ static void
+ catch_timer(sig)
+@@ -11810,8 +11876,19 @@
+ tval.it_value = tval.it_interval;
+ setitimer(ITIMER_VIRTUAL, &tval, NULL);
+ }
++
++void
++rb_thread_cancel_timer()
++{
++}
++
+ #else /* !(_THREAD_SAFE || HAVE_SETITIMER) */
+ int rb_thread_tick = THREAD_TICK;
++
++void
++rb_thread_cancel_timer()
++{
++}
+ #endif
+
+ static VALUE
+@@ -11842,6 +11919,7 @@
+
+ #ifdef _THREAD_SAFE
+ pthread_create(&time_thread, 0, thread_timer, 0);
++ time_thread_alive_p = 1;
+ #else
+ rb_thread_start_timer();
+ #endif
+@@ -12106,7 +12184,7 @@
+ */
+
+ static VALUE
+-rb_thread_status(thread)
++rb_thread_status_name(thread)
+ VALUE thread;
+ {
+ rb_thread_t th = rb_thread_check(thread);
+@@ -12133,7 +12211,7 @@
+ * thr.alive? #=> false
+ */
+
+-static VALUE
++VALUE
+ rb_thread_alive_p(thread)
+ VALUE thread;
+ {
+@@ -12967,7 +13045,7 @@
+ rb_define_method(rb_cThread, "terminate!", rb_thread_kill_bang, 0);
+ rb_define_method(rb_cThread, "exit!", rb_thread_kill_bang, 0);
+ rb_define_method(rb_cThread, "value", rb_thread_value, 0);
+- rb_define_method(rb_cThread, "status", rb_thread_status, 0);
++ rb_define_method(rb_cThread, "status", rb_thread_status_name, 0);
+ rb_define_method(rb_cThread, "join", rb_thread_join_m, -1);
+ rb_define_method(rb_cThread, "alive?", rb_thread_alive_p, 0);
+ rb_define_method(rb_cThread, "stop?", rb_thread_stop_p, 0);
diff --git a/lang/ruby18/files/patch-ext_bigdecimal_bigdecimal.c b/lang/ruby18/files/patch-ext_bigdecimal_bigdecimal.c
new file mode 100644
index 000000000000..2aa3ef9a4473
--- /dev/null
+++ b/lang/ruby18/files/patch-ext_bigdecimal_bigdecimal.c
@@ -0,0 +1,11 @@
+--- ext/bigdecimal/bigdecimal.c.orig Tue Feb 27 14:51:55 2007
++++ ext/bigdecimal/bigdecimal.c Fri Mar 16 13:07:26 2007
+@@ -3921,7 +3921,7 @@
+ /* get integer part */
+ i = 0;
+ sign = 1;
+- if(ni > 0) {
++ if(ni >= 0) {
+ if(int_chr[0] == '-') {
+ sign = -1;
+ ++i;
diff --git a/lang/ruby18/files/patch-ext_dl_dl.c b/lang/ruby18/files/patch-ext_dl_dl.c
new file mode 100644
index 000000000000..1527786a7aca
--- /dev/null
+++ b/lang/ruby18/files/patch-ext_dl_dl.c
@@ -0,0 +1,11 @@
+--- ext/dl/dl.c.orig Tue Feb 13 02:01:19 2007
++++ ext/dl/dl.c Mon Mar 19 10:43:56 2007
+@@ -459,7 +459,7 @@
+ VALUE val0;
+
+ val0 = rb_check_array_type(v);
+- if(NIL_P(TYPE(val0))) {
++ if(NIL_P(val0)) {
+ rb_raise(rb_eDLTypeError, "an array is expected.");
+ }
+ v = val0;
diff --git a/lang/ruby18/files/patch-ext_etc_etc.c b/lang/ruby18/files/patch-ext_etc_etc.c
new file mode 100644
index 000000000000..b70983b64888
--- /dev/null
+++ b/lang/ruby18/files/patch-ext_etc_etc.c
@@ -0,0 +1,11 @@
+--- ext/etc/etc.c.orig Tue Feb 13 02:01:19 2007
++++ ext/etc/etc.c Fri Mar 16 14:53:15 2007
+@@ -337,7 +337,7 @@
+ struct group *grp;
+
+ rb_secure(4);
+- gid = getgid();
++ gid = PW_VAL2GID(id);
+ grp = getgrgid(gid);
+ if (grp == 0) rb_raise(rb_eArgError, "can't find group for %d", gid);
+ return setup_group(grp);
diff --git a/lang/ruby18/files/patch-ext_thread_thread.c b/lang/ruby18/files/patch-ext_thread_thread.c
new file mode 100644
index 000000000000..121dfa5380f6
--- /dev/null
+++ b/lang/ruby18/files/patch-ext_thread_thread.c
@@ -0,0 +1,270 @@
+--- ext/thread/thread.c.orig Sat Mar 3 13:08:06 2007
++++ ext/thread/thread.c Tue Jul 10 03:08:38 2007
+@@ -12,6 +12,7 @@
+ #include <ruby.h>
+ #include <intern.h>
+ #include <rubysig.h>
++#include <node.h>
+
+ static VALUE rb_cMutex;
+ static VALUE rb_cConditionVariable;
+@@ -163,13 +164,18 @@
+ remove_one(List *list, VALUE value)
+ {
+ Entry **ref;
++ Entry *prev;
+ Entry *entry;
+
+- for (ref = &list->entries, entry = list->entries;
++ for (ref = &list->entries, prev = NULL, entry = list->entries;
+ entry != NULL;
+- ref = &entry->next, entry = entry->next) {
++ ref = &entry->next, prev = entry, entry = entry->next) {
+ if (entry->value == value) {
+ *ref = entry->next;
++ list->size--;
++ if (!entry->next) {
++ list->last_entry = prev;
++ }
+ recycle_entries(list, entry, entry);
+ break;
+ }
+@@ -202,15 +208,16 @@
+ static VALUE
+ wake_thread(VALUE thread)
+ {
+- return rb_rescue2(rb_thread_wakeup, thread,
+- NULL, Qundef, rb_eThreadError, 0);
++ return rb_thread_wakeup_alive(thread);
+ }
+
+ static VALUE
+ run_thread(VALUE thread)
+ {
+- return rb_rescue2(rb_thread_run, thread,
+- NULL, Qundef, rb_eThreadError, 0);
++ thread = wake_thread(thread);
++ if (RTEST(thread) && !rb_thread_critical)
++ rb_thread_schedule();
++ return thread;
+ }
+
+ static VALUE
+@@ -220,7 +227,9 @@
+
+ waking = Qnil;
+ while (list->entries && !RTEST(waking)) {
+- waking = wake_thread(shift_list(list));
++ waking = shift_list(list);
++ if (waking == Qundef) break;
++ waking = wake_thread(waking);
+ }
+
+ return waking;
+@@ -251,7 +260,7 @@
+ return Qnil;
+ }
+
+-static void
++static VALUE
+ wait_list(List *list)
+ {
+ rb_ensure(wait_list_inner, (VALUE)list, wait_list_cleanup, (VALUE)list);
+@@ -261,10 +270,17 @@
+ assert_no_survivors(List *waiting, const char *label, void *addr)
+ {
+ Entry *entry;
++ VALUE ths = 0;
++
+ for (entry = waiting->entries; entry; entry = entry->next) {
+- if (RTEST(wake_thread(entry->value))) {
+- rb_bug("%s %p freed with live thread(s) waiting", label, addr);
+- }
++ if (RTEST(wake_thread(entry->value))) {
++ if (!ths) ths = rb_ary_new();
++ rb_ary_push(ths, entry->value);
++ }
++ }
++ if (ths) {
++ rb_bug("%s %p freed with live thread(s) %s waiting",
++ label, addr, RSTRING_PTR(rb_inspect(ths)));
+ }
+ }
+
+@@ -298,6 +314,8 @@
+ List waiting;
+ } Mutex;
+
++#define MUTEX_LOCKED_P(mutex) (RTEST((mutex)->owner) && rb_thread_alive_p((mutex)->owner))
++
+ static void
+ mark_mutex(Mutex *mutex)
+ {
+@@ -356,7 +374,7 @@
+ {
+ Mutex *mutex;
+ Data_Get_Struct(self, Mutex, mutex);
+- return RTEST(mutex->owner) ? Qtrue : Qfalse;
++ return MUTEX_LOCKED_P(mutex) ? Qtrue : Qfalse;
+ }
+
+ /*
+@@ -375,7 +393,7 @@
+
+ Data_Get_Struct(self, Mutex, mutex);
+
+- if (RTEST(mutex->owner))
++ if (MUTEX_LOCKED_P(mutex))
+ return Qfalse;
+
+ mutex->owner = rb_thread_current();
+@@ -390,7 +408,7 @@
+ *
+ */
+
+-static void
++static VALUE
+ lock_mutex(Mutex *mutex)
+ {
+ VALUE current;
+@@ -398,13 +416,23 @@
+
+ rb_thread_critical = 1;
+
+- while (RTEST(mutex->owner)) {
+- wait_list(&mutex->waiting);
+- rb_thread_critical = 1;
++ if (!MUTEX_LOCKED_P(mutex)) {
++ mutex->owner = current;
++ }
++ else {
++ push_list(&mutex->waiting, current);
++ do {
++ rb_thread_stop();
++ rb_thread_critical = 1;
++ if (!MUTEX_LOCKED_P(mutex)) {
++ mutex->owner = current;
++ break;
++ }
++ } while (mutex->owner != current);
+ }
+- mutex->owner = current;
+
+ rb_thread_critical = 0;
++ return Qnil;
+ }
+
+ static VALUE
+@@ -416,6 +444,22 @@
+ return self;
+ }
+
++static VALUE
++relock_mutex(Mutex *mutex)
++{
++ VALUE current = rb_thread_current();
++
++ switch (rb_thread_status(current)) {
++ case THREAD_RUNNABLE:
++ case THREAD_STOPPED:
++ lock_mutex(mutex);
++ break;
++ default:
++ break;
++ }
++ return Qundef;
++}
++
+ /*
+ * Document-method: unlock
+ *
+@@ -428,11 +472,12 @@
+ {
+ VALUE waking;
+
+- if (!RTEST(mutex->owner)) {
+- return Qundef;
++ if (mutex->owner != rb_thread_current()) {
++ rb_raise(rb_eThreadError, "not owner");
+ }
+- mutex->owner = Qnil;
++
+ waking = wake_one(&mutex->waiting);
++ mutex->owner = waking;
+
+ return waking;
+ }
+@@ -451,14 +496,11 @@
+
+ rb_thread_critical = 1;
+ waking = rb_ensure(unlock_mutex_inner, (VALUE)mutex, set_critical, 0);
+-
+- if (waking == Qundef) {
++ if (!RTEST(waking)) {
+ return Qfalse;
+ }
+
+- if (RTEST(waking)) {
+- run_thread(waking);
+- }
++ run_thread(waking);
+
+ return Qtrue;
+ }
+@@ -504,13 +546,11 @@
+ rb_thread_critical = 1;
+ waking = rb_ensure(rb_mutex_exclusive_unlock_inner, (VALUE)mutex, set_critical, 0);
+
+- if (waking == Qundef) {
++ if (waking == Qundef || !RTEST(waking)) {
+ return Qnil;
+ }
+
+- if (RTEST(waking)) {
+- run_thread(waking);
+- }
++ run_thread(waking);
+
+ return self;
+ }
+@@ -622,19 +662,18 @@
+ static void
+ wait_condvar(ConditionVariable *condvar, Mutex *mutex)
+ {
++ VALUE waking;
++
+ rb_thread_critical = 1;
+- if (!RTEST(mutex->owner)) {
++ if (rb_thread_current() != mutex->owner) {
+ rb_thread_critical = 0;
+- return;
++ rb_raise(rb_eThreadError, "not owner of the synchronization mutex");
+ }
+- if (mutex->owner != rb_thread_current()) {
+- rb_thread_critical = 0;
+- rb_raise(rb_eThreadError, "Not owner");
++ waking = unlock_mutex_inner(mutex);
++ if (RTEST(waking)) {
++ wake_thread(waking);
+ }
+- mutex->owner = Qnil;
+- wait_list(&condvar->waiting);
+-
+- lock_mutex(mutex);
++ rb_ensure(wait_list, (VALUE)&condvar->waiting, relock_mutex, (VALUE)mutex);
+ }
+
+ static VALUE
+@@ -830,10 +869,10 @@
+
+ array = rb_marshal_load(data);
+ if (TYPE(array) != T_ARRAY) {
+- rb_raise(rb_eRuntimeError, "expected Array of queue data");
++ rb_raise(rb_eTypeError, "expected Array of queue data");
+ }
+ if (RARRAY(array)->len < 1) {
+- rb_raise(rb_eRuntimeError, "missing capacity value");
++ rb_raise(rb_eArgError, "missing capacity value");
+ }
+ queue->capacity = NUM2ULONG(rb_ary_shift(array));
+ push_multiple_list(&queue->values, RARRAY(array)->ptr, (unsigned)RARRAY(array)->len);
diff --git a/lang/ruby18/files/patch-ext_tk_lib_tkextlib_tcllib_tablelist.rb b/lang/ruby18/files/patch-ext_tk_lib_tkextlib_tcllib_tablelist.rb
new file mode 100644
index 000000000000..3602f8ec347f
--- /dev/null
+++ b/lang/ruby18/files/patch-ext_tk_lib_tkextlib_tcllib_tablelist.rb
@@ -0,0 +1,9 @@
+--- ext/tk/lib/tkextlib/tcllib/tablelist.rb.orig Tue Feb 13 02:01:19 2007
++++ ext/tk/lib/tkextlib/tcllib/tablelist.rb Fri May 25 20:11:52 2007
+@@ -23,5 +23,5 @@
+ # TkPackage.require('Tablelist', '4.2')
+ TkPackage.require('Tablelist')
+
+- requrie 'tkextlib/tcllib/tablelist_core'
++ require 'tkextlib/tcllib/tablelist_core'
+ end
diff --git a/lang/ruby18/files/patch-ext_tk_lib_tkextlib_tile_dialog.rb b/lang/ruby18/files/patch-ext_tk_lib_tkextlib_tile_dialog.rb
new file mode 100644
index 000000000000..fd5e97c2db1d
--- /dev/null
+++ b/lang/ruby18/files/patch-ext_tk_lib_tkextlib_tile_dialog.rb
@@ -0,0 +1,11 @@
+--- ext/tk/lib/tkextlib/tile/dialog.rb.orig Tue Feb 13 02:01:19 2007
++++ ext/tk/lib/tkextlib/tile/dialog.rb Fri May 25 20:11:52 2007
+@@ -51,7 +51,7 @@
+ alias display show
+
+ def client_frame
+- window(tk_call_without_enc('::ttk::dialog::clientframe'))
++ window(tk_call_without_enc('::ttk::dialog::clientframe', @path))
+ end
+
+ def cget(slot)
diff --git a/lang/ruby18/files/patch-intern.h b/lang/ruby18/files/patch-intern.h
new file mode 100644
index 000000000000..97669273d111
--- /dev/null
+++ b/lang/ruby18/files/patch-intern.h
@@ -0,0 +1,16 @@
+--- intern.h.orig Sun Mar 11 11:31:53 2007
++++ intern.h Thu Jun 7 16:40:01 2007
+@@ -204,10 +204,13 @@
+ void rb_thread_polling _((void));
+ void rb_thread_sleep _((int));
+ void rb_thread_sleep_forever _((void));
++enum thread_status rb_thread_status _((VALUE));
+ VALUE rb_thread_stop _((void));
+ VALUE rb_thread_wakeup _((VALUE));
++VALUE rb_thread_wakeup_alive _((VALUE));
+ VALUE rb_thread_run _((VALUE));
+ VALUE rb_thread_kill _((VALUE));
++VALUE rb_thread_alive_p _((VALUE));
+ VALUE rb_thread_create _((VALUE (*)(ANYARGS), void*));
+ void rb_thread_interrupt _((void));
+ void rb_thread_trap_eval _((VALUE, int, int));
diff --git a/lang/ruby18/files/patch-lib_cgi.rb b/lang/ruby18/files/patch-lib_cgi.rb
new file mode 100644
index 000000000000..e3c7b0b412f8
--- /dev/null
+++ b/lang/ruby18/files/patch-lib_cgi.rb
@@ -0,0 +1,10 @@
+--- lib/cgi.rb.orig Mon Mar 12 20:55:03 2007
++++ lib/cgi.rb Wed May 23 01:58:09 2007
+@@ -1163,6 +1163,7 @@
+ # retrieved; use #params() to get the array of values.
+ def [](key)
+ params = @params[key]
++ return '' unless params
+ value = params[0]
+ if @multipart
+ if value
diff --git a/lang/ruby18/files/patch-lib_monitor.rb b/lang/ruby18/files/patch-lib_monitor.rb
new file mode 100644
index 000000000000..0c1d04371781
--- /dev/null
+++ b/lang/ruby18/files/patch-lib_monitor.rb
@@ -0,0 +1,46 @@
+--- lib/monitor.rb.orig Tue Feb 13 02:01:19 2007
++++ lib/monitor.rb Tue May 22 22:35:57 2007
+@@ -105,14 +105,17 @@
+ return false
+ ensure
+ Thread.critical = true
+- if timer && timer.alive?
+- Thread.kill(timer)
++ begin
++ if timer && timer.alive?
++ Thread.kill(timer)
++ end
++ if @waiters.include?(Thread.current) # interrupted?
++ @waiters.delete(Thread.current)
++ end
++ @monitor.instance_eval {mon_enter_for_cond(count)}
++ ensure
++ Thread.critical = false
+ end
+- if @waiters.include?(Thread.current) # interrupted?
+- @waiters.delete(Thread.current)
+- end
+- @monitor.instance_eval {mon_enter_for_cond(count)}
+- Thread.critical = false
+ end
+ end
+
+@@ -210,6 +213,7 @@
+ Thread.critical = true
+ mon_acquire(@mon_entering_queue)
+ @mon_count += 1
++ ensure
+ Thread.critical = false
+ end
+
+@@ -299,8 +303,9 @@
+ def mon_exit_for_cond
+ count = @mon_count
+ @mon_count = 0
+- mon_release
+ return count
++ ensure
++ mon_release
+ end
+ end
+
diff --git a/lang/ruby18/files/patch-lib_net_imap.rb b/lang/ruby18/files/patch-lib_net_imap.rb
new file mode 100644
index 000000000000..8ff68bb20ee2
--- /dev/null
+++ b/lang/ruby18/files/patch-lib_net_imap.rb
@@ -0,0 +1,15 @@
+--- lib/net/imap.rb.orig Tue Feb 13 02:01:19 2007
++++ lib/net/imap.rb Tue May 22 20:44:37 2007
+@@ -284,7 +284,11 @@
+
+ # Disconnects from the server.
+ def disconnect
+- @sock.shutdown unless @usessl
++ if SSL::SSLSocket === @sock
++ @sock.io.shutdown
++ else
++ @sock.shutdown
++ end
+ @receiver_thread.join
+ @sock.close
+ end
diff --git a/lang/ruby18/files/patch-process.c b/lang/ruby18/files/patch-process.c
new file mode 100644
index 000000000000..598cf5db50c8
--- /dev/null
+++ b/lang/ruby18/files/patch-process.c
@@ -0,0 +1,10 @@
+--- process.c.orig Tue Feb 13 02:01:19 2007
++++ process.c Wed May 23 02:32:16 2007
+@@ -981,6 +981,7 @@
+ }
+ #endif /* MSDOS or __human68k__ or __EMX__ */
+ before_exec();
++ rb_thread_cancel_timer();
+ execv(prog, argv);
+ after_exec();
+ return -1;
diff --git a/lang/ruby18/files/patch-util.c b/lang/ruby18/files/patch-util.c
new file mode 100644
index 000000000000..e236a9cd4154
--- /dev/null
+++ b/lang/ruby18/files/patch-util.c
@@ -0,0 +1,13 @@
+--- util.c.orig Sun Mar 4 17:20:24 2007
++++ util.c Tue May 22 22:25:13 2007
+@@ -683,8 +683,8 @@
+ *
+ */
+
+-#define MDMINEXPT DBL_MIN_EXP
+-#define MDMAXEXPT DBL_MAX_EXP
++#define MDMINEXPT DBL_MIN_10_EXP
++#define MDMAXEXPT DBL_MAX_10_EXP
+
+ static const
+ double powersOf10[] = { /* Table giving binary powers of 10. Entry */