[#4076] Re: call/cc — shugo@... (Shugo Maeda)

51 messages 1999/01/08
[#4077] Re: [ruby-list:11512] Re: call/cc — maeda@... 1999/01/08

前田@リコーです。

[#4078] Re: call/cc — shugo@... (Shugo Maeda) 1999/01/08

[#4079] Re: call/cc — kjana@... (YANAGAWA Kazuhisa) 1999/01/08

In message <m0zyZO8-0003EbC@crunkey.chocolate.or.jp>

[#4098] Re: call/cc — shugo@... (Shugo Maeda) 1999/01/11

[#4105] Re: call/cc — EGUCHI Osamu <eguchi@...> 1999/01/12

えぐち@エスアンドイー です。

[#4144] Re: call/cc — shugo@... (Shugo Maeda) 1999/01/13

[#4090] finalizers — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

19 messages 1999/01/11

[#4095] Ruby on CYGWIN — TAKAHASHI Masayoshi <maki@...>

高橋です。久しぶりに書きます。

26 messages 1999/01/11
[#4111] Re: Ruby on CYGWIN — WATANABE Hirofumi <watanabe@...> 1999/01/12

わたなべです.

[#4115] Re: Ruby on CYGWIN — TAKAHASHI Masayoshi <maki@...> 1999/01/12

高橋です。Rubyのリンク集から見つけたのですが、sgmailって

[#4118] sgmail (Re: Ruby on CYGWIN) — Takahiro Maebashi <maebashi@...> 1999/01/12

前橋です。

[#4123] Tk? Gtk? (Re: sgmail) — TAKAHASHI Masayoshi <maki@...> 1999/01/13

高橋です。

[#4203] Compile via WATCOM C — ARIMA Yasuhiro <fit0298@...>

有馬です。

20 messages 1999/01/18
[#4204] Re: Compile via WATCOM C — KIMURA Koichi <kimura@...> 1999/01/18

[#4248] patch for ruby-mswin32 — Koji Oda <oda@...1.qnes.nec.co.jp>

小田@QNES です。

27 messages 1999/01/19
[#4254] Re: patch for ruby-mswin32 — matz@... (Yukihiro Matsumoto) 1999/01/19

まつもと ゆきひろです

[#4256] Re: patch for ruby-mswin32 — WATANABE Hirofumi <watanabe@...> 1999/01/19

わたなべです.

[#4258] Re: patch for ruby-mswin32 — matz@... (Yukihiro Matsumoto) 1999/01/19

まつもと ゆきひろです

[#4290] signed/unsigned char — ARIMA Yasuhiro <fit0298@...>

有馬です。

17 messages 1999/01/20
[#4292] Re: signed/unsigned char — EGUCHI Osamu <eguchi@...> 1999/01/20

えぐち@エスアンドイー です。

[#4293] Re: signed/unsigned char — ARIMA Yasuhiro <fit0298@...> 1999/01/20

Regard to "[ruby-dev:4292] Re: signed/unsigned char"

[#4295] Re: signed/unsigned char — EGUCHI Osamu <eguchi@...> 1999/01/20

えぐち@エスアンドイー です。

[#4327] pack("F") for bigendian float — gotoken@... (GOTO Kentaro)

ごとけんです。

25 messages 1999/01/22
[#4330] Re: pack("F") for bigendian float — gotoken@... (GOTO Kentaro) 1999/01/23

ごとけんです

[#4331] Re: pack("F") for bigendian float — gotoken@... (GOTO Kentaro) 1999/01/23

ごとけんです

[#4336] Re: pack("F") for bigendian float — matz@... (Yukihiro Matsumoto) 1999/01/24

まつもと ゆきひろです

[#4337] Re: pack("F") for bigendian float — gotoken@... (GOTO Kentaro) 1999/01/24

ごとけんです

[#4338] Re: pack("F") for bigendian float — Yamashita Junji (山下 純司) <ys_jyunji@...> 1999/01/24

山下 純司です。

[#4341] cascades on ruby — Kazunori NISHI <kazunori@...>

西@九大です。

51 messages 1999/01/25
[#4342] Re: cascades on ruby — Kazuhiro HIWADA <hiwada@...> 1999/01/25

ひわだです。

[#4343] Re: cascades on ruby — Kazunori NISHI <kazunori@...> 1999/01/25

西@九大です。

[#4344] Re: cascades on ruby — matz@... (Yukihiro Matsumoto) 1999/01/25

まつもと ゆきひろです

[#4386] Re: cascades on ruby — keiju@... (石塚圭樹 ) 1999/01/26

けいじゅ@日本ラショナルソフトウェアです.

[#4389] Re: cascades on ruby — matz@... (Yukihiro Matsumoto) 1999/01/26

まつもと ゆきひろです

[#4394] Re: cascades on ruby — keiju@... (石塚圭樹 ) 1999/01/26

けいじゅ@日本ラショナルソフトウェアです.

[#4396] keyword argument (Re: Re: cascades on ruby) — matz@... (Yukihiro Matsumoto) 1999/01/26

[#4399] Re: keyword argument (Re: Re: cascades on ruby) — keiju@... (石塚圭樹 ) 1999/01/26

けいじゅ@日本ラショナルソフトウェアです.

[#4400] Re: keyword argument (Re: Re: cascades on ruby) — matz@... (Yukihiro Matsumoto) 1999/01/26

まつもと ゆきひろです

[#4401] Re: keyword argument (Re: Re: cascades on ruby) — keiju@... (石塚圭樹 ) 1999/01/26

けいじゅ@日本ラショナルソフトウェアです.

[#4404] Re: keyword argument (Re: Re: cascades on ruby) — matz@... (Yukihiro Matsumoto) 1999/01/26

まつもと ゆきひろです

[#4410] Re: keyword argument (Re: Re: cascades on ruby) — keiju@... (石塚圭樹 ) 1999/01/26

けいじゅ@日本ラショナルソフトウェアです.

[#4412] Re: keyword argument (Re: Re: cascades on ruby) — matz@... (Yukihiro Matsumoto) 1999/01/26

まつもと ゆきひろです

[#4473] Re: keyword argument (Re: Re: cascades on ruby) — matz@... (Yukihiro Matsumoto) 1999/01/28

まつもと ゆきひろです

[#4495] Re: keyword argument (Re: Re: cascades on ruby) — shugo@... (Shugo Maeda) 1999/01/29

前田です。

[#4349] Re: [ruby-list:11707] Re: ruby 1.2.2 released — EGUCHI Osamu <eguchi@...>

えぐち@エスアンドイー です。

35 messages 1999/01/25
[#4353] Re: [ruby-list:11707] Re: ruby 1.2.2 released — EGUCHI Osamu <eguchi@...> 1999/01/25

えぐち@エスアンドイー です。

[#4357] --enable-shared/BSD (Re: ) — EGUCHI Osamu <eguchi@...> 1999/01/25

えぐち@エスアンドイー です。

[#4375] Re: --enable-shared/BSD (Re: ) — matz@... (Yukihiro Matsumoto) 1999/01/26

まつもと ゆきひろです

[#4387] Re: --enable-shared/BSD (Re: ) — EGUCHI Osamu <eguchi@...> 1999/01/26

えぐち@エスアンドイー です。

[#4391] Re: --enable-shared/BSD (Re: ) — matz@... (Yukihiro Matsumoto) 1999/01/26

まつもと ゆきひろです

[#4406] Re: --enable-shared/BSD (Re: ) — EGUCHI Osamu <eguchi@...> 1999/01/26

えぐち@エスアンドイー です。

[#4419] Re: module Precision — Inaba Hiroto <inaba@...>

21 messages 1999/01/26
[#4438] Re: module Precision — gotoken@... (GOTO Kentaro) 1999/01/27

ごとけんです

[#4451] Re: module Precision — Inaba Hiroto <inaba@...> 1999/01/27

From: gotoken@math.sci.hokudai.ac.jp (GOTO Kentaro)

[#4453] new class for float of C (Re: module Precision) — gotoken@... (GOTO Kentaro) 1999/01/27

ごとけんです

[#4457] Re: new class for float of C (Re: module Precision) — matz@... (Yukihiro Matsumoto) 1999/01/28

まつもと ゆきひろです

[#4460] Re: new class for float of C (Re: module Precision) — gotoken@... (GOTO Kentaro) 1999/01/28

ごとけんです

[#4461] Re: new class for float of C (Re: module Precision) — matz@... (Yukihiro Matsumoto) 1999/01/28

まつもと ゆきひろです

[#4462] Re: new class for float of C (Re: module Precision) — gotoken@... (GOTO Kentaro) 1999/01/28

ごとけんです

[#4420] ruby 1.3.1-990126 — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

17 messages 1999/01/26

[#4452] permit to put a comma — Koji Arai <JCA02266@...>

新井です。

18 messages 1999/01/27
[#4484] Re: permit to put a comma — matz@... (Yukihiro Matsumoto) 1999/01/29

まつもと ゆきひろです

[#4518] Inf.0 — gotoken@... (GOTO Kentaro)

ごとけんです

17 messages 1999/01/30

[ruby-dev:4248] patch for ruby-mswin32

From: Koji Oda <oda@...1.qnes.nec.co.jp>
Date: 1999-01-19 00:13:50 UTC
List: ruby-dev #4248
小田@QNES です。

だいぶ過ぎてしまいましたが、明けましておめでとうございます。
今年もよろしくお願いします。

年末年始が忙しくってなかなか時間がとれませんでしたが、やっと
できました。

ところで、GNU diff の使い方がよくわかって無くって、かなりの
量になってしまいましたが、diff のオプションは、どう指定した方が
よかったんでしょうか?

---
修正としては、not reached の部分もreturn を入れています。
return が無い場合はreturn Qnilとしていますが、正しいかどうかは
分かりません(^^;;

gc.c 396行で
	return rb_mark_generic_ivar((VALUE)obj);
となっていたところは、
関数の戻りがvoidだったので、2つに分けてみました。

---------8<-----ここから---------8<-----
diff -iNu ruby-1.3_org/bignum.c ruby-1.3/bignum.c
--- ruby-1.3_org/bignum.c	Wed Nov 25 12:31:09 1998
+++ ruby-1.3/bignum.c	Tue Jan 12 22:10:30 1999
@@ -64,9 +64,9 @@
 	num += ds[i];
 	ds[i++] = BIGLO(num);
 	num = BIGDN(num);
-    } while (i < RBIGNUM(x)->len);
+    } while (i < (UINT)RBIGNUM(x)->len);
     if (ds[0] == 1 || ds[0] == 0) {
-	for (i=1;i<RBIGNUM(x)->len;i++) {
+	for (i=1;i<(UINT)RBIGNUM(x)->len;i++) {
 	    if (ds[i] != 0) return;
 	}
 	REALLOC_N(BDIGITS(x), USHORT, RBIGNUM(x)->len++);
@@ -119,7 +119,7 @@
     big = bignew(DIGSPERINT, 1);
     digits = BDIGITS(big);
     while (i < DIGSPERINT) {
-	digits[i++] = BIGLO(n);
+	digits[i++] = (USHORT)BIGLO(n);
 	n = BIGDN(n);
     }
 
@@ -256,7 +256,7 @@
 	for (;;) {
 	    while (i<blen) {
 		num += zds[i]*base;
-		zds[i++] = BIGLO(num);
+		zds[i++] = (USHORT)BIGLO(num);
 		num = BIGDN(num);
 	    }
 	    if (num) {
@@ -319,13 +319,13 @@
 	unsigned long num = 0;
 	while (k--) {
 	    num = BIGUP(num) + ds[k];
-	    ds[k] = num / hbase;
+	    ds[k] = (USHORT)(num / hbase);
 	    num %= hbase;
 	}
 	if (ds[i-1] == 0) i--;
 	k = 4;
 	while (k--) {
-	    c = num % base;
+	    c = (char)(num % base);
 	    s[--j] = hexmap[(int)c];
 	    num /= base;
 	    if (i == 0 && num == 0) break;
@@ -374,7 +374,7 @@
     if ((long)num < 0) {
 	rb_raise(rb_eArgError, "bignum too big to convert into `int'");
     }
-    if (!RBIGNUM(x)->sign) return -num;
+    if (!RBIGNUM(x)->sign) return -1*abs(num);
     return num;
 }
 
@@ -405,7 +405,7 @@
 	u *= BIGRAD;
 	c = (long)u;
 	u -= c;
-	digits[i] = c;
+	digits[i] = (USHORT)c;
     }
 
     return bignorm(z);
@@ -530,17 +530,17 @@
     z = bignew(RBIGNUM(x)->len, (z == 0)?1:0);
     zds = BDIGITS(z);
 
-    for (i = 0, num = 0; i < RBIGNUM(y)->len; i++) { 
+    for (i = 0, num = 0; i < (UINT)(RBIGNUM(y)->len); i++) { 
 	num += (long)BDIGITS(x)[i] - BDIGITS(y)[i];
 	zds[i] = BIGLO(num);
 	num = BIGDN(num);
     } 
-    while (num && i < RBIGNUM(x)->len) {
+    while (num && i < (UINT)(RBIGNUM(x)->len)) {
 	num += BDIGITS(x)[i];
 	zds[i++] = BIGLO(num);
 	num = BIGDN(num);
     }
-    while (i < RBIGNUM(x)->len) {
+    while (i < (UINT)(RBIGNUM(x)->len)) {
 	zds[i] = BDIGITS(x)[i];
 	i++;
     }
@@ -588,7 +588,7 @@
 	BDIGITS(z)[i] = BDIGITS(y)[i];
 	i++;
     }
-    BDIGITS(z)[i] = num;
+    BDIGITS(z)[i] = (USHORT)num;
 
     return bignorm(z);
 }
@@ -660,18 +660,18 @@
     z = bignew(j, RBIGNUM(x)->sign==RBIGNUM(y)->sign);
     zds = BDIGITS(z);
     while (j--) zds[j] = 0;
-    for (i = 0; i < RBIGNUM(x)->len; i++) {
+    for (i = 0; i < (UINT)(RBIGNUM(x)->len); i++) {
 	unsigned long dd = BDIGITS(x)[i]; 
 	if (dd == 0) continue;
 	n = 0;
-	for (j = 0; j < RBIGNUM(y)->len; j++) {
+	for (j = 0; j < (UINT)(RBIGNUM(y)->len); j++) {
 	    int ee = n + dd * BDIGITS(y)[j];
 	    n = zds[i + j] + ee;
-	    if (ee) zds[i + j] = BIGLO(n);
+	    if (ee) zds[i + j] = (USHORT)BIGLO(n);
 	    n = BIGDN(n);
 	}
 	if (n) {
-	    zds[i + j] = n;
+	    zds[i + j] = (USHORT)n;
 	}
     }
 
@@ -706,12 +706,12 @@
 	t2 = 0; i = nx;
 	while (i--) {
 	    t2 = BIGUP(t2) + zds[i];
-	    zds[i] = t2 / dd;
+	    zds[i] = (USHORT)(t2 / dd);
 	    t2 %= dd;
 	}
 	if (div) *div = bignorm(z);
 	if (mod) {
-	    if (!RBIGNUM(y)->sign) t2 = -t2;
+	    if (!RBIGNUM(y)->sign) t2 = -1*abs(t2);
 	    *mod = INT2FIX(t2);
 	}
 	return;
@@ -738,7 +738,7 @@
 	    zds[j++] = BIGLO(num);
 	    num = BIGDN(num);
 	}
-	zds[j] = num;
+	zds[j] = (USHORT)num;
     }
     else {
 	zds[nx] = 0;
@@ -748,7 +748,7 @@
     j = nx==ny?nx+1:nx;
     do {
 	if (zds[j] ==  yds[ny-1]) q = BIGRAD-1;
-	else q = (BIGUP(zds[j]) + zds[j-1])/yds[ny-1];
+	else q = (USHORT)((BIGUP(zds[j]) + zds[j-1])/yds[ny-1]);
 	if (q) {
 	    i = 0; num = 0; t2 = 0;
 	    do {			/* multiply and subtract */
@@ -789,7 +789,7 @@
 	    t2 = 0; i = ny;
 	    while(i--) {
 		t2 = BIGUP(t2) + zds[i];
-		zds[i] = t2 / dd;
+		zds[i] = (USHORT)(t2 / dd);
 		t2 %= dd;
 	    }
 	}
@@ -1126,10 +1126,10 @@
     }
     for (i=0; i<len; i++) {
 	num = num | *xds++<<s2;
-	*zds++ = BIGLO(num);
+	*zds++ = (USHORT)BIGLO(num);
 	num = BIGDN(num);
     }
-    *zds = BIGLO(num);
+    *zds = (USHORT)BIGLO(num);
     return bignorm(z);
 }
 
@@ -1147,7 +1147,7 @@
     unsigned int j;
 
     if (shift < 0) return rb_big_lshift(x, INT2FIX(-shift));
-    if (s1 > RBIGNUM(x)->len) {
+    if (s1 > (UINT)(RBIGNUM(x)->len)) {
 	if (RBIGNUM(x)->sign)
 	    return INT2FIX(0);
 	else
@@ -1159,7 +1159,7 @@
     zds = BDIGITS(z);
     while (i--, j--) {
 	num = (num | xds[i]) >> s2;
-	zds[j] = BIGLO(num);
+	zds[j] = (USHORT)BIGLO(num);
 	num = BIGUP(xds[i]);
     }
     return bignorm(z);
@@ -1178,12 +1178,12 @@
     s2 = shift%BITSPERDIG;
 
     if (!RBIGNUM(x)->sign) {
-	if (s1 >= RBIGNUM(x)->len) return INT2FIX(1);
+	if (s1 >= (UINT)(RBIGNUM(x)->len)) return INT2FIX(1);
 	x = rb_big_clone(x);
 	rb_big_2comp(x);
     }
     else {
-	if (s1 >= RBIGNUM(x)->len) return INT2FIX(0);
+	if (s1 >= (UINT)(RBIGNUM(x)->len)) return INT2FIX(0);
     }
     xds = BDIGITS(x);
     if (xds[s1] & (1<<s2))
@@ -1216,7 +1216,8 @@
 	rb_raise(rb_eTypeError, "can't coerce %s to Bignum",
 		 rb_class2name(CLASS_OF(y)));
     }
-    /* not reached */
+    /* not reached */
+	return Qnil;
 }
 
 static VALUE
diff -iNu ruby-1.3_org/dir.c ruby-1.3/dir.c
--- ruby-1.3_org/dir.c	Wed Nov 25 12:31:10 1998
+++ ruby-1.3/dir.c	Mon Jan 11 15:15:16 1999
@@ -126,6 +126,7 @@
     else {
 	rb_sys_fail(0);
     }
+	return Qnil;
 }
 
 static VALUE
@@ -258,6 +259,7 @@
 #else
     rb_notimplement();
 #endif
+	return Qnil;
 }
 
 static VALUE
diff -iNu ruby-1.3_org/dln.c ruby-1.3/dln.c
--- ruby-1.3_org/dln.c	Tue Dec 22 18:01:48 1998
+++ ruby-1.3/dln.c	Mon Jan 11 22:14:34 1999
@@ -1,1692 +1,1691 @@
-/************************************************
-
-  dln.c -
-
-  $Author: matz $
-  $Date: 1998/12/22 09:01:48 $
-  created at: Tue Jan 18 17:05:06 JST 1994
-
-  Copyright (C) 1993-1998 Yukihiro Matsumoto
-
-************************************************/
-
-#include "config.h"
-#include "defines.h"
-#include "dln.h"
-
-char *dln_argv0;
-
-#ifdef _AIX
-#pragma alloca
-#endif
-
-#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
-#include <alloca.h>
-#endif
-
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
-
-void *xmalloc();
-void *xcalloc();
-void *xrealloc();
-
-#include <stdio.h>
-#ifndef NT
-# ifndef USE_CWGUSI
-#  include <sys/file.h>
-# endif
-#else
-#include "missing/file.h"
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#else
-# define MAXPATHLEN 1024
-#endif
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifndef NT
-char *strdup();
-char *getenv();
-#endif
-
-#ifdef __MACOS__
-# include <TextUtils.h>
-# include <CodeFragments.h>
-# include <Aliases.h>
-#endif
-
-#ifdef __BEOS__
-# include <image.h>
-#endif
-
-int eaccess();
-
-#if defined(HAVE_DLOPEN) && !defined(USE_DLN_A_OUT) && !defined(__CYGWIN32__) && !defined(_AIX)
-/* dynamic load with dlopen() */
-# define USE_DLN_DLOPEN
-#endif
-
-#ifndef FUNCNAME_PATTERN
-# if defined(__hp9000s300) || defined(__NetBSD__) || defined(__BORLANDC__) || (defined(__FreeBSD__) && __FreeBSD__ < 3) || defined(NeXT) || defined(__WATCOMC__)
-#  define FUNCNAME_PATTERN "_Init_%.200s"
-# else
-#  define FUNCNAME_PATTERN "Init_%.200s"
-# endif
-#endif
-
-static void
-init_funcname(buf, file)
-    char *buf, *file;
-{
-    char *p, *slash;
-
-    /* Load the file as an object one */
-    for (p = file, slash = p-1; *p; p++) /* Find position of last '/' */
-#ifdef __MACOS__
-	if (*p == ':') slash = p;
-#else
-	if (*p == '/') slash = p;
-#endif
-
-    sprintf(buf, FUNCNAME_PATTERN, slash + 1);
-    for (p = buf; *p; p++) {         /* Delete suffix it it exists */
-	if (*p == '.') {
-	    *p = '\0'; break;
-	}
-    }
-}
-
-#ifdef USE_DLN_A_OUT
-
-#ifndef LIBC_NAME
-# define LIBC_NAME "libc.a"
-#endif
-
-#ifndef DLN_DEFAULT_LIB_PATH
-#  define DLN_DEFAULT_LIB_PATH "/lib:/usr/lib:/usr/local/lib:."
-#endif
-
-#include <errno.h>
-
-static int dln_errno;
-
-#define DLN_ENOEXEC	ENOEXEC	/* Exec format error */
-#define DLN_ECONFL	201	/* Symbol name conflict */
-#define DLN_ENOINIT	202	/* No inititalizer given */
-#define DLN_EUNDEF	203	/* Undefine symbol remains */
-#define DLN_ENOTLIB	204	/* Not a library file */
-#define DLN_EBADLIB	205	/* Malformed library file */
-#define DLN_EINIT	206	/* Not initialized */
-
-static int dln_init_p = 0;
-
-#include "st.h"
-#include <ar.h>
-#include <a.out.h>
-#ifndef N_COMM
-# define N_COMM 0x12
-#endif
-#ifndef N_MAGIC
-# define N_MAGIC(x) (x).a_magic
-#endif
-
-#define INVALID_OBJECT(h) (N_MAGIC(h) != OMAGIC)
-
-static st_table *sym_tbl;
-static st_table *undef_tbl;
-
-static int load_lib();
-
-static int
-load_header(fd, hdrp, disp)
-    int fd;
-    struct exec *hdrp;
-    long disp;
-{
-    int size;
-
-    lseek(fd, disp, 0);
-    size = read(fd, hdrp, sizeof(struct exec));
-    if (size == -1) {
-	dln_errno = errno;
-	return -1;
-    }
-    if (size != sizeof(struct exec) || N_BADMAG(*hdrp)) {
-	dln_errno = DLN_ENOEXEC;
-	return -1;
-    }
-    return 0;
-}
-
-#if defined(sequent)
-#define RELOC_SYMBOL(r)			((r)->r_symbolnum)
-#define RELOC_MEMORY_SUB_P(r)		((r)->r_bsr)
-#define RELOC_PCREL_P(r)		((r)->r_pcrel || (r)->r_bsr)
-#define RELOC_TARGET_SIZE(r)		((r)->r_length)
-#endif
-
-/* Default macros */
-#ifndef RELOC_ADDRESS
-#define RELOC_ADDRESS(r)		((r)->r_address)
-#define RELOC_EXTERN_P(r)		((r)->r_extern)
-#define RELOC_SYMBOL(r)			((r)->r_symbolnum)
-#define RELOC_MEMORY_SUB_P(r)		0
-#define RELOC_PCREL_P(r)		((r)->r_pcrel)
-#define RELOC_TARGET_SIZE(r)		((r)->r_length)
-#endif
-
-#if defined(sun) && defined(sparc)
-/* Sparc (Sun 4) macros */
-#  undef relocation_info
-#  define relocation_info reloc_info_sparc
-#  define R_RIGHTSHIFT(r)	(reloc_r_rightshift[(r)->r_type])
-#  define R_BITSIZE(r) 		(reloc_r_bitsize[(r)->r_type])
-#  define R_LENGTH(r)		(reloc_r_length[(r)->r_type])
-static int reloc_r_rightshift[] = {
-  0, 0, 0, 0, 0, 0, 2, 2, 10, 0, 0, 0, 0, 0, 0,
-};
-static int reloc_r_bitsize[] = {
-  8, 16, 32, 8, 16, 32, 30, 22, 22, 22, 13, 10, 32, 32, 16,
-};
-static int reloc_r_length[] = {
-  0, 1, 2, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-};
-#  define R_PCREL(r) \
-    ((r)->r_type >= RELOC_DISP8 && (r)->r_type <= RELOC_WDISP22)
-#  define R_SYMBOL(r) ((r)->r_index)
-#endif
-
-#if defined(sequent)
-#define R_SYMBOL(r)		((r)->r_symbolnum)
-#define R_MEMORY_SUB(r)		((r)->r_bsr)
-#define R_PCREL(r)		((r)->r_pcrel || (r)->r_bsr)
-#define R_LENGTH(r)		((r)->r_length)
-#endif
-
-#ifndef R_SYMBOL
-#  define R_SYMBOL(r) 		((r)->r_symbolnum)
-#  define R_MEMORY_SUB(r)	0
-#  define R_PCREL(r)  		((r)->r_pcrel)
-#  define R_LENGTH(r) 		((r)->r_length)
-#endif
-
-static struct relocation_info *
-load_reloc(fd, hdrp, disp)
-     int fd;
-     struct exec *hdrp;
-     long disp;
-{
-    struct relocation_info *reloc;
-    int size;
-
-    lseek(fd, disp + N_TXTOFF(*hdrp) + hdrp->a_text + hdrp->a_data, 0);
-    size = hdrp->a_trsize + hdrp->a_drsize;
-    reloc = (struct relocation_info*)xmalloc(size);
-    if (reloc == NULL) {
-	dln_errno = errno;
-	return NULL;
-    }
-
-    if (read(fd, reloc, size) !=  size) {
-	dln_errno = errno;
-	free(reloc);
-	return NULL;
-    }
-
-    return reloc;
-}
-
-static struct nlist *
-load_sym(fd, hdrp, disp)
-    int fd;
-    struct exec *hdrp;
-    long disp;
-{
-    struct nlist * buffer;
-    struct nlist * sym;
-    struct nlist * end;
-    long displ;
-    int size;
-
-    lseek(fd, N_SYMOFF(*hdrp) + hdrp->a_syms + disp, 0);
-    if (read(fd, &size, sizeof(int)) != sizeof(int)) {
-	goto err_noexec;
-    }
-
-    buffer = (struct nlist*)xmalloc(hdrp->a_syms + size);
-    if (buffer == NULL) {
-	dln_errno = errno;
-	return NULL;
-    }
-
-    lseek(fd, disp + N_SYMOFF(*hdrp), 0);
-    if (read(fd, buffer, hdrp->a_syms + size) != hdrp->a_syms + size) {
-	free(buffer);
-	goto err_noexec;
-    }
-
-    sym = buffer;
-    end = sym + hdrp->a_syms / sizeof(struct nlist);
-    displ = (long)buffer + (long)(hdrp->a_syms);
-
-    while (sym < end) {
-	sym->n_un.n_name = (char*)sym->n_un.n_strx + displ;
-	sym++;
-    }
-    return buffer;
-
-  err_noexec:
-    dln_errno = DLN_ENOEXEC;
-    return NULL;
-}
-
-static st_table *
-sym_hash(hdrp, syms)
-    struct exec *hdrp;
-    struct nlist *syms;
-{
-    st_table *tbl;
-    struct nlist *sym = syms;
-    struct nlist *end = syms + (hdrp->a_syms / sizeof(struct nlist));
-
-    tbl = st_init_strtable();
-    if (tbl == NULL) {
-	dln_errno = errno;
-	return NULL;
-    }
-
-    while (sym < end) {
-	st_insert(tbl, sym->n_un.n_name, sym);
-	sym++;
-    }
-    return tbl;
-}
-
-static int
-dln_init(prog)
-    char *prog;
-{
-    char *file;
-    int fd;
-    struct exec hdr;
-    struct nlist *syms;
-
-    if (dln_init_p == 1) return 0;
-
-    file = dln_find_exe(prog, NULL);
-    if (file == NULL || (fd = open(file, O_RDONLY)) < 0) {
-	dln_errno = errno;
-	return -1;
-    }
-
-    if (load_header(fd, &hdr, 0) == -1) return -1;
-    syms = load_sym(fd, &hdr, 0);
-    if (syms == NULL) {
-	close(fd);
-	return -1;
-    }
-    sym_tbl = sym_hash(&hdr, syms);
-    if (sym_tbl == NULL) {	/* file may be start with #! */
-	char c = '\0';
-	char buf[MAXPATHLEN];
-	char *p;
-
-	free(syms);
-	lseek(fd, 0L, 0);
-	if (read(fd, &c, 1) == -1) {
-	    dln_errno = errno;
-	    return -1;
-	}
-	if (c != '#') goto err_noexec;
-	if (read(fd, &c, 1) == -1) {
-	    dln_errno = errno;
-	    return -1;
-	}
-	if (c != '!') goto err_noexec;
-
-	p = buf;
-	/* skip forwading spaces */
-	while (read(fd, &c, 1) == 1) {
-	    if (c == '\n') goto err_noexec;
-	    if (c != '\t' && c != ' ') {
-		*p++ = c;
-		break;
-	    }
-	}
-	/* read in command name */
-	while (read(fd, p, 1) == 1) {
-	    if (*p == '\n' || *p == '\t' || *p == ' ') break;
-	    p++;
-	}
-	*p = '\0';
-
-	return dln_init(buf);
-    }
-    dln_init_p = 1;
-    undef_tbl = st_init_strtable();
-    close(fd);
-    return 0;
-
-  err_noexec:
-    close(fd);
-    dln_errno = DLN_ENOEXEC;
-    return -1;
-}
-
-static long
-load_text_data(fd, hdrp, bss, disp)
-    int fd;
-    struct exec *hdrp;
-    int bss;
-    long disp;
-{
-    int size;
-    unsigned char* addr;
-
-    lseek(fd, disp + N_TXTOFF(*hdrp), 0);
-    size = hdrp->a_text + hdrp->a_data;
-
-    if (bss == -1) size += hdrp->a_bss;
-    else if (bss > 1) size += bss;
-
-    addr = (unsigned char*)xmalloc(size);
-    if (addr == NULL) {
-	dln_errno = errno;
-	return 0;
-    }
-
-    if (read(fd, addr, size) !=  size) {
-	dln_errno = errno;
-	free(addr);
-	return 0;
-    }
-
-    if (bss == -1) {
-	memset(addr +  hdrp->a_text + hdrp->a_data, 0, hdrp->a_bss);
-    }
-    else if (bss > 0) {
-	memset(addr +  hdrp->a_text + hdrp->a_data, 0, bss);
-    }
-
-    return (long)addr;
-}
-
-static int
-underb_f_print(key, value)
-    char *key, *value;
-{
-    fprintf(stderr, "  %s\n", key);
-    return ST_CONTINUE;
-}
-
-static void
-dln_print_undef()
-{
-    fprintf(stderr, " Undefined symbols:\n");
-    st_foreach(undef_tbl, underb_f_print, NULL);
-}
-
-static void
-dln_undefined()
-{
-    if (undef_tbl->num_entries > 0) {
-	fprintf(stderr, "dln: Calling undefined function\n");
-	dln_print_undef();
-	rb_exit(1);
-    }
-}
-
-struct undef {
-    char *name;
-    struct relocation_info reloc;
-    long base;
-    char *addr;
-    union {
-	char c;
-	short s;
-	long l;
-    } u;
-};
-
-static st_table *reloc_tbl = NULL;
-static void
-link_undef(name, base, reloc)
-    char *name;
-    long base;
-    struct relocation_info *reloc;
-{
-    static int u_no = 0;
-    struct undef *obj;
-    char *addr = (char*)(reloc->r_address + base);
-
-    obj = (struct undef*)xmalloc(sizeof(struct undef));
-    obj->name = strdup(name);
-    obj->reloc = *reloc;
-    obj->base = base;
-    switch (R_LENGTH(reloc)) {
-      case 0:		/* byte */
-	obj->u.c = *addr;
-	break;
-      case 1:		/* word */
-	obj->u.s = *(short*)addr;
-	break;
-      case 2:		/* long */
-	obj->u.l = *(long*)addr;
-	break;
-    }
-    if (reloc_tbl == NULL) {
-	reloc_tbl = st_init_numtable();
-    }
-    st_insert(reloc_tbl, u_no++, obj);
-}
-
-struct reloc_arg {
-    char *name;
-    long value;
-};
-
-static int
-reloc_undef(no, undef, arg)
-    int no;
-    struct undef *undef;
-    struct reloc_arg *arg;
-{
-    int datum;
-    char *address;
-#if defined(sun) && defined(sparc)
-    unsigned int mask = 0;
-#endif
-
-    if (strcmp(arg->name, undef->name) != 0) return ST_CONTINUE;
-    address = (char*)(undef->base + undef->reloc.r_address);
-    datum = arg->value;
-
-    if (R_PCREL(&(undef->reloc))) datum -= undef->base;
-#if defined(sun) && defined(sparc)
-    datum += undef->reloc.r_addend;
-    datum >>= R_RIGHTSHIFT(&(undef->reloc));
-    mask = (1 << R_BITSIZE(&(undef->reloc))) - 1;
-    mask |= mask -1;
-    datum &= mask;
-    switch (R_LENGTH(&(undef->reloc))) {
-      case 0:
-	*address = undef->u.c;
-	*address &= ~mask;
-	*address |= datum;
-	break;
-      case 1:
-	*(short *)address = undef->u.s;
-	*(short *)address &= ~mask;
-	*(short *)address |= datum;
-	break;
-      case 2:
-	*(long *)address = undef->u.l;
-	*(long *)address &= ~mask;
-	*(long *)address |= datum;
-	break;
-    }
-#else
-    switch (R_LENGTH(&(undef->reloc))) {
-      case 0:		/* byte */
-	if (R_MEMORY_SUB(&(undef->reloc)))
-	    *address = datum - *address;
-	else *address = undef->u.c + datum;
-	break;
-      case 1:		/* word */
-	if (R_MEMORY_SUB(&(undef->reloc)))
-	    *(short*)address = datum - *(short*)address;
-	else *(short*)address = undef->u.s + datum;
-	break;
-      case 2:		/* long */
-	if (R_MEMORY_SUB(&(undef->reloc)))
-	    *(long*)address = datum - *(long*)address;
-	else *(long*)address = undef->u.l + datum;
-	break;
-    }
-#endif
-    free(undef->name);
-    free(undef);
-    return ST_DELETE;
-}
-
-static void
-unlink_undef(name, value)
-    char *name;
-    long value;
-{
-    struct reloc_arg arg;
-
-    arg.name = name;
-    arg.value = value;
-    st_foreach(reloc_tbl, reloc_undef, &arg);
-}
-
-#ifdef N_INDR
-struct indr_data {
-    char *name0, *name1;
-};
-
-static int
-reloc_repl(no, undef, data)
-    int no;
-    struct undef *undef;
-    struct indr_data *data;
-{
-    if (strcmp(data->name0, undef->name) == 0) {
-	free(undef->name);
-	undef->name = strdup(data->name1);
-    }
-    return ST_CONTINUE;
-}
-#endif
-
-static int
-load_1(fd, disp, need_init)
-    int fd;
-    long disp;
-    char *need_init;
-{
-    static char *libc = LIBC_NAME;
-    struct exec hdr;
-    struct relocation_info *reloc = NULL;
-    long block = 0;
-    long new_common = 0; /* Length of new common */
-    struct nlist *syms = NULL;
-    struct nlist *sym;
-    struct nlist *end;
-    int init_p = 0;
-    char buf[256];
-
-    if (load_header(fd, &hdr, disp) == -1) return -1;
-    if (INVALID_OBJECT(hdr)) {
-	dln_errno = DLN_ENOEXEC;
-	return -1;
-    }
-    reloc = load_reloc(fd, &hdr, disp);
-    if (reloc == NULL) return -1;
-    syms = load_sym(fd, &hdr, disp);
-    if (syms == NULL) return -1;
-
-    sym = syms;
-    end = syms + (hdr.a_syms / sizeof(struct nlist));
-    while (sym < end) {
-	struct nlist *old_sym;
-	int value = sym->n_value;
-
-#ifdef N_INDR
-	if (sym->n_type == (N_INDR | N_EXT)) {
-	    char *key = sym->n_un.n_name;
-
-	    if (st_lookup(sym_tbl, sym[1].n_un.n_name, &old_sym)) {
-		if (st_delete(undef_tbl, &key, NULL)) {
-		    unlink_undef(key, old_sym->n_value);
-		    free(key);
-		}
-	    }
-	    else {
-		struct indr_data data;
-
-		data.name0 = sym->n_un.n_name;
-		data.name1 = sym[1].n_un.n_name;
-		st_foreach(reloc_tbl, reloc_repl, &data);
-
-		st_insert(undef_tbl, strdup(sym[1].n_un.n_name), NULL);
-		if (st_delete(undef_tbl, &key, NULL)) {
-		    free(key);
-		}
-	    }
-	    sym += 2;
-	    continue;
-	}
-#endif
-	if (sym->n_type == (N_UNDF | N_EXT)) {
-	    if (st_lookup(sym_tbl, sym->n_un.n_name, &old_sym) == 0) {
-		old_sym = NULL;
-	    }
-
-	    if (value) {
-		if (old_sym) {
-		    sym->n_type = N_EXT | N_COMM;
-		    sym->n_value = old_sym->n_value;
-		}
-		else {
-		    int rnd =
-			value >= sizeof(double) ? sizeof(double) - 1
-			    : value >= sizeof(long) ? sizeof(long) - 1
-				: sizeof(short) - 1;
-
-		    sym->n_type = N_COMM;
-		    new_common += rnd;
-		    new_common &= ~(long)rnd;
-		    sym->n_value = new_common;
-		    new_common += value;
-		}
-	    }
-	    else {
-		if (old_sym) {
-		    sym->n_type = N_EXT | N_COMM;
-		    sym->n_value = old_sym->n_value;
-		}
-		else {
-		    sym->n_value = (long)dln_undefined;
-		    st_insert(undef_tbl, strdup(sym->n_un.n_name), NULL);
-		}
-	    }
-	}
-	sym++;
-    }
-
-    block = load_text_data(fd, &hdr, hdr.a_bss + new_common, disp);
-    if (block == 0) goto err_exit;
-
-    sym = syms;
-    while (sym < end) {
-	struct nlist *new_sym;
-	char *key;
-
-	switch (sym->n_type) {
-	  case N_COMM:
-	    sym->n_value += hdr.a_text + hdr.a_data;
-	  case N_TEXT|N_EXT:
-	  case N_DATA|N_EXT:
-
-	    sym->n_value += block;
-
-	    if (st_lookup(sym_tbl, sym->n_un.n_name, &new_sym) != 0
-		&& new_sym->n_value != (long)dln_undefined) {
-		dln_errno = DLN_ECONFL;
-		goto err_exit;
-	    }
-
-	    key = sym->n_un.n_name;
-	    if (st_delete(undef_tbl, &key, NULL) != 0) {
-		unlink_undef(key, sym->n_value);
-		free(key);
-	    }
-
-	    new_sym = (struct nlist*)xmalloc(sizeof(struct nlist));
-	    *new_sym = *sym;
-	    new_sym->n_un.n_name = strdup(sym->n_un.n_name);
-	    st_insert(sym_tbl, new_sym->n_un.n_name, new_sym);
-	    break;
-
-	  case N_TEXT:
-	  case N_DATA:
-	    sym->n_value += block;
-	    break;
-	}
-	sym++;
-    }
-
-    /*
-     * First comes the text-relocation
-     */
-    {
-	struct relocation_info * rel = reloc;
-	struct relocation_info * rel_beg = reloc +
-	    (hdr.a_trsize/sizeof(struct relocation_info));
-	struct relocation_info * rel_end = reloc +
-	    (hdr.a_trsize+hdr.a_drsize)/sizeof(struct relocation_info);
-
-	while (rel < rel_end) {
-	    char *address = (char*)(rel->r_address + block);
-	    long datum = 0;
-#if defined(sun) && defined(sparc)
-	    unsigned int mask = 0;
-#endif
-
-	    if(rel >= rel_beg)
-		address += hdr.a_text;
-
-	    if (rel->r_extern) { /* Look it up in symbol-table */
-		sym = &(syms[R_SYMBOL(rel)]);
-		switch (sym->n_type) {
-		  case N_EXT|N_UNDF:
-		    link_undef(sym->n_un.n_name, block, rel);
-		  case N_EXT|N_COMM:
-		  case N_COMM:
-		    datum = sym->n_value;
-		    break;
-		  default:
-		    goto err_exit;
-		}
-	    } /* end.. look it up */
-	    else { /* is static */
-		switch (R_SYMBOL(rel)) { 
-		  case N_TEXT:
-		  case N_DATA:
-		    datum = block;
-		    break;
-		  case N_BSS:
-		    datum = block +  new_common;
-		    break;
-		  case N_ABS:
-		    break;
-		}
-	    } /* end .. is static */
-	    if (R_PCREL(rel)) datum -= block;
-
-#if defined(sun) && defined(sparc)
-	    datum += rel->r_addend;
-	    datum >>= R_RIGHTSHIFT(rel);
-	    mask = (1 << R_BITSIZE(rel)) - 1;
-	    mask |= mask -1;
-	    datum &= mask;
-
-	    switch (R_LENGTH(rel)) {
-	      case 0:
-		*address &= ~mask;
-		*address |= datum;
-		break;
-	      case 1:
-		*(short *)address &= ~mask;
-		*(short *)address |= datum;
-		break;
-	      case 2:
-		*(long *)address &= ~mask;
-		*(long *)address |= datum;
-		break;
-	    }
-#else
-	    switch (R_LENGTH(rel)) {
-	      case 0:		/* byte */
-		if (datum < -128 || datum > 127) goto err_exit;
-		*address += datum;
-		break;
-	      case 1:		/* word */
-		*(short *)address += datum;
-		break;
-	      case 2:		/* long */
-		*(long *)address += datum;
-		break;
-	    }
-#endif
-	    rel++;
-	}
-    }
-
-    if (need_init) {
-	int len;
-	char **libs_to_be_linked = 0;
-
-	if (undef_tbl->num_entries > 0) {
-	    if (load_lib(libc) == -1) goto err_exit;
-	}
-
-	init_funcname(buf, need_init);
-	len = strlen(buf);
-
-	for (sym = syms; sym<end; sym++) {
-	    char *name = sym->n_un.n_name;
-	    if (name[0] == '_' && sym->n_value >= block) {
-		if (strcmp(name+1, "dln_libs_to_be_linked") == 0) {
-		    libs_to_be_linked = (char**)sym->n_value;
-		}
-		else if (strcmp(name+1, buf) == 0) {
-		    init_p = 1;
-		    ((int (*)())sym->n_value)();
-		}
-	    }
-	}
-	if (libs_to_be_linked && undef_tbl->num_entries > 0) {
-	    while (*libs_to_be_linked) {
-		load_lib(*libs_to_be_linked);
-		libs_to_be_linked++;
-	    }
-	}
-    }
-    free(reloc);
-    free(syms);
-    if (need_init) {
-	if (init_p == 0) {
-	    dln_errno = DLN_ENOINIT;
-	    return -1;
-	}
-	if (undef_tbl->num_entries > 0) {
-	    if (load_lib(libc) == -1) goto err_exit;
-	    if (undef_tbl->num_entries > 0) {
-		dln_errno = DLN_EUNDEF;
-		return -1;
-	    }
-	}
-    }
-    return 0;
-
-  err_exit:
-    if (syms) free(syms);
-    if (reloc) free(reloc);
-    if (block) free((char*)block);
-    return -1;
-}
-
-static int target_offset;
-static int
-search_undef(key, value, lib_tbl)
-    char *key;
-    int value;
-    st_table *lib_tbl;
-{
-    int offset;
-
-    if (st_lookup(lib_tbl, key, &offset) == 0) return ST_CONTINUE;
-    target_offset = offset;
-    return ST_STOP;
-}
-
-struct symdef {
-    int rb_str_index;
-    int lib_offset;
-};
-
-char *dln_librrb_ary_path = DLN_DEFAULT_LIB_PATH;
-
-static int
-load_lib(lib)
-    char *lib;
-{
-    char *path, *file;
-    char armagic[SARMAG];
-    int fd, size;
-    struct ar_hdr ahdr;
-    st_table *lib_tbl = NULL;
-    int *data, nsym;
-    struct symdef *base;
-    char *name_base;
-
-    if (dln_init_p == 0) {
-	dln_errno = DLN_ENOINIT;
-	return -1;
-    }
-
-    if (undef_tbl->num_entries == 0) return 0;
-    dln_errno = DLN_EBADLIB;
-
-    if (lib[0] == '-' && lib[1] == 'l') {
-	char *p = alloca(strlen(lib) + 4);
-	sprintf(p, "lib%s.a", lib+2);
-	lib = p;
-    }
-
-    /* library search path: */
-    /* look for environment variable DLN_LIBRARY_PATH first. */
-    /* then variable dln_librrb_ary_path. */
-    /* if path is still NULL, use "." for path. */
-    path = getenv("DLN_LIBRARY_PATH");
-    if (path == NULL) path = dln_librrb_ary_path;
-
-    file = dln_find_file(lib, path);
-    fd = open(file, O_RDONLY);
-    if (fd == -1) goto syserr;
-    size = read(fd, armagic, SARMAG);
-    if (size == -1) goto syserr;
-
-    if (size != SARMAG) {
-	dln_errno = DLN_ENOTLIB;
-	goto badlib;
-    }
-    size = read(fd, &ahdr, sizeof(ahdr));
-    if (size == -1) goto syserr;
-    if (size != sizeof(ahdr) || sscanf(ahdr.ar_size, "%d", &size) != 1) {
-	goto badlib;
-    }
-
-    if (strncmp(ahdr.ar_name, "__.SYMDEF", 9) == 0) {
-	/* make hash table from __.SYMDEF */
-
-	lib_tbl = st_init_strtable();
-	data = (int*)xmalloc(size);
-	if (data == NULL) goto syserr;
-	size = read(fd, data, size);
-	nsym = *data / sizeof(struct symdef);
-	base = (struct symdef*)(data + 1);
-	name_base = (char*)(base + nsym) + sizeof(int);
-	while (nsym > 0) {
-	    char *name = name_base + base->rb_str_index;
-
-	    st_insert(lib_tbl, name, base->lib_offset + sizeof(ahdr));
-	    nsym--;
-	    base++;
-	}
-	for (;;) {
-	    target_offset = -1;
-	    st_foreach(undef_tbl, search_undef, lib_tbl);
-	    if (target_offset == -1) break;
-	    if (load_1(fd, target_offset, 0) == -1) {
-		st_free_table(lib_tbl);
-		free(data);
-		goto badlib;
-	    }
-	    if (undef_tbl->num_entries == 0) break;
-	}
-	free(data);
-	st_free_table(lib_tbl);
-    }
-    else {
-	/* linear library, need to scan (FUTURE) */
-
-	for (;;) {
-	    int offset = SARMAG;
-	    int found = 0;
-	    struct exec hdr;
-	    struct nlist *syms, *sym, *end;
-
-	    while (undef_tbl->num_entries > 0) {
-		found = 0;
-		lseek(fd, offset, 0);
-		size = read(fd, &ahdr, sizeof(ahdr));
-		if (size == -1) goto syserr;
-		if (size == 0) break;
-		if (size != sizeof(ahdr)
-		    || sscanf(ahdr.ar_size, "%d", &size) != 1) {
-		    goto badlib;
-		}
-		offset += sizeof(ahdr);
-		if (load_header(fd, &hdr, offset) == -1)
-		    goto badlib;
-		syms = load_sym(fd, &hdr, offset);
-		if (syms == NULL) goto badlib;
-		sym = syms;
-		end = syms + (hdr.a_syms / sizeof(struct nlist));
-		while (sym < end) {
-		    if (sym->n_type == N_EXT|N_TEXT
-			&& st_lookup(undef_tbl, sym->n_un.n_name, NULL)) {
-			break;
-		    }
-		    sym++;
-		}
-		if (sym < end) {
-		    found++;
-		    free(syms);
-		    if (load_1(fd, offset, 0) == -1) {
-			goto badlib;
-		    }
-		}
-		offset += size;
-		if (offset & 1) offset++;
-	    }
-	    if (found) break;
-	}
-    }
-    close(fd);
-    return 0;
-
-  syserr:
-    dln_errno = errno;
-  badlib:
-    if (fd >= 0) close(fd);
-    return -1;
-}
-
-static int
-load(file)
-    char *file;
-{
-    int fd;
-    int result;
-
-    if (dln_init_p == 0) {
-	if (dln_init(dln_argv0) == -1) return -1;
-    }
-    result = strlen(file);
-    if (file[result-1] == 'a') {
-	return load_lib(file);
-    }
-
-    fd = open(file, O_RDONLY);
-    if (fd == -1) {
-	dln_errno = errno;
-	return -1;
-    }
-    result = load_1(fd, 0, file);
-    close(fd);
-
-    return result;
-}
-
-void*
-dln_sym(name)
-    char *name;
-{
-    struct nlist *sym;
-
-    if (st_lookup(sym_tbl, name, &sym))
-	return (void*)sym->n_value;
-    return NULL;
-}
-
-#endif /* USE_DLN_A_OUT */
-
-#ifdef USE_DLN_DLOPEN
-# ifdef __NetBSD__
-#  include <nlist.h>
-#  include <link.h>
-# else
-#  include <dlfcn.h>
-# endif
-#endif
-
-#ifdef hpux
-#include <errno.h>
-#include "dl.h"
-#endif
-
-#if defined(_AIX)
-#include <ctype.h>	/* for isdigit()	*/
-#include <errno.h>	/* for global errno	*/
-#include <sys/ldr.h>
-#endif
-
-#ifdef NeXT
-#if NS_TARGET_MAJOR < 4
-#include <mach-o/rld.h>
-#else
-#include <mach-o/dyld.h>
-#endif
-#endif
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-static char *
-dln_strerror()
-{
-#ifdef USE_DLN_A_OUT
-    char *strerror();
-
-    switch (dln_errno) {
-      case DLN_ECONFL:
-	return "Symbol name conflict";
-      case DLN_ENOINIT:
-	return "No inititalizer given";
-      case DLN_EUNDEF:
-	return "Unresolved symbols";
-      case DLN_ENOTLIB:
-	return "Not a library file";
-      case DLN_EBADLIB:
-	return "Malformed library file";
-      case DLN_EINIT:
-	return "Not initialized";
-      default:
-	return strerror(dln_errno);
-    }
-#endif
-
-#ifdef USE_DLN_DLOPEN
-    return (char*)dlerror();
-#endif
-
-#ifdef _WIN32
-    static char message[1024];
-    int error = GetLastError();
-    char *p = message;
-    p += sprintf(message, "%d: ", error);
-    FormatMessage(
-	FORMAT_MESSAGE_FROM_SYSTEM,
-	NULL,
-	error,
-	MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-	p,
-	sizeof message - strlen(message),
-	NULL);
-
-    for (p = message; *p; p++) {
-	if (*p == '\n' || *p == '\r')
-	    *p = ' ';
-    }
-    return message;
-#endif
-}
-
-
-#if defined(_AIX)
-static void
-aix_loaderror(char *pathname)
-{
-    char *message[8], errbuf[1024];
-    int i,j;
-
-    struct errtab { 
-	int errno;
-	char *errstr;
-    } load_errtab[] = {
-	{L_ERROR_TOOMANY,	"too many errors, rest skipped."},
-	{L_ERROR_NOLIB,		"can't load library:"},
-	{L_ERROR_UNDEF,		"can't find symbol in library:"},
-	{L_ERROR_RLDBAD,
-	     "RLD index out of range or bad relocation type:"},
-	{L_ERROR_FORMAT,	"not a valid, executable xcoff file:"},
-	{L_ERROR_MEMBER,
-	     "file not an archive or does not contain requested member:"},
-	{L_ERROR_TYPE,		"symbol table mismatch:"},
-	{L_ERROR_ALIGN,		"text allignment in file is wrong."},
-	{L_ERROR_SYSTEM,	"System error:"},
-	{L_ERROR_ERRNO,		NULL}
-    };
-
-#define LOAD_ERRTAB_LEN	(sizeof(load_errtab)/sizeof(load_errtab[0]))
-#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
-
-    sprintf(errbuf, "load failed - %.200s ", pathname);
-
-    if (!loadquery(1, &message[0], sizeof(message))) 
-	ERRBUF_APPEND(strerror(errno));
-    for(i = 0; message[i] && *message[i]; i++) {
-	int nerr = atoi(message[i]);
-	for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
-	    if (nerr == load_errtab[i].errno && load_errtab[i].errstr)
-		ERRBUF_APPEND(load_errtab[i].errstr);
-	}
-	while (isdigit(*message[i])) message[i]++ ; 
-	ERRBUF_APPEND(message[i]);
-	ERRBUF_APPEND("\n");
-    }
-    errbuf[strlen(errbuf)-1] = '\0';	/* trim off last newline */
-    rb_loaderror(errbuf);
-    return;
-}
-#endif
-
-void
-dln_load(file)
-    char *file;
-{
-#ifdef _WIN32
-    HINSTANCE handle;
-    char winfile[255];
-    void (*init_fct)();
-    char buf[MAXPATHLEN];
-
-    /* Load the file as an object one */
-    init_funcname(buf, file);
-
-#ifdef __CYGWIN32__
-    cygwin32_conv_to_win32_path(file, winfile);
-#else
-    strcpy(winfile, file);
-#endif
-
-    /* Load file */
-    if ((handle =
-	LoadLibraryExA(winfile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) == NULL) {
-        printf("LoadLibraryExA: %s\n", winfile);
-	goto failed;
-    }
-
-#ifdef __CYGWIN32__
-    init_fct = (void(*)())GetProcAddress(handle, "impure_setup");
-
-    if (init_fct)
-	init_fct(_impure_ptr);
-#endif
-
-    if ((init_fct = (void(*)())GetProcAddress(handle, buf)) == NULL) {
-        printf("GetProcAddress %s\n", buf);
-	goto failed;
-    }
-    /* Call the init code */
-    (*init_fct)();
-    return;
-#else
-#ifdef USE_DLN_A_OUT
-    if (load(file) == -1) {
-	goto failed;
-    }
-    return;
-#else
-
-    char buf[MAXPATHLEN];
-    /* Load the file as an object one */
-    init_funcname(buf, file);
-
-#ifdef USE_DLN_DLOPEN
-#define DLN_DEFINED
-    {
-	void *handle;
-	void (*init_fct)();
-
-# ifndef RTLD_LAZY
-#  define RTLD_LAZY 1
-# endif
-# ifndef RTLD_GLOBAL
-#  define RTLD_GLOBAL 0
-# endif
-
-	/* Load file */
-	if ((handle = (void*)dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == NULL) {
-	    goto failed;
-	}
-
-	if ((init_fct = (void(*)())dlsym(handle, buf)) == NULL) {
-	    goto failed;
-	}
-	/* Call the init code */
-	(*init_fct)();
-	return;
-    }
-#endif /* USE_DLN_DLOPEN */
-
-#ifdef hpux
-#define DLN_DEFINED
-    {
-	shl_t lib = NULL;
-	int flags;
-	void (*init_fct)();
-
-	flags = BIND_DEFERRED;
-	lib = shl_load(file, flags, 0);
-	if (lib == NULL) {
-	    extern int errno;
-	    rb_loaderror("%s - %s", strerror(errno), file);
-	}
-	shl_findsym(&lib, buf, TYPE_PROCEDURE, (void*)&init_fct);
-	if (init_fct == NULL) {
-	    shl_findsym(&lib, buf, TYPE_UNDEFINED, (void*)&init_fct);
-	    if (init_fct == NULL) {
-		errno = ENOSYM;
-		rb_loaderror("%s - %s", strerror(ENOSYM), file);
-	    }
-	}
-	(*init_fct)();
-	return;
-    }
-#endif /* hpux */
-
-#if defined(_AIX)
-#define DLN_DEFINED
-    {
-	void (*init_fct)();
-
-	init_fct = (void(*)())load(file, 1, 0);
-	if (init_fct == NULL) {
-	    aix_loaderror(file);
-	}
-	(*init_fct)();
-	return;
-    }
-#endif /* _AIX */
-
-#ifdef NeXT
-#define DLN_DEFINED
-/*----------------------------------------------------
-   By SHIROYAMA Takayuki Psi@fortune.nest.or.jp
- 
-   Special Thanks...
-    Yu tomoak-i@is.aist-nara.ac.jp,
-    Mi hisho@tasihara.nest.or.jp,
-    and... Miss ARAI Akino(^^;)
- ----------------------------------------------------*/
-#if NS_TARGET_MAJOR < 4 /* NeXTSTEP rld functions */
-    {
-	unsigned long init_address;
-	char *object_files[2] = {NULL, NULL};
-
-	void (*init_fct)();
-	
-	object_files[0] = file;
-	
-	/* Load object file, if return value ==0 ,  load failed*/
-	if(rld_load(NULL, NULL, object_files, NULL) == 0) {
-	    rb_loaderror("Failed to load %.200s", file);
-	}
-
-	/* lookup the initial function */
-	if(rld_lookup(NULL, buf, &init_address) == 0) {
-	    rb_loaderror("Failed to lookup Init function %.200s", file);
-	}
-
-	 /* Cannot call *init_address directory, so copy this value to
-	    funtion pointer */
-
-	init_fct = (void(*)())init_address;
-	(*init_fct)();
-	return ;
-    }
-#else/* OPENSTEP dyld functions */
-    {
-	int dyld_result ;
-	NSObjectFileImage obj_file ; /* handle, but not use it */
-	/* "file" is module file name .
-	   "buf" is initial function name with "_" . */
-
-	void (*init_fct)();
-
-
-	dyld_result = NSCreateObjectFileImageFromFile( file, &obj_file );
-
-	if (dyld_result != NSObjectFileImageSuccess) {
-	    rb_loaderror("Failed to load %.200s", file);
-	}
-
-	NSLinkModule(obj_file, file, TRUE);
-
-	/* lookup the initial function */
-	/*NSIsSymbolNameDefined require function name without "_" */
-	if( NSIsSymbolNameDefined( buf + 1 ) ) {
-	    rb_loaderror("Failed to lookup Init function %.200s",file);
-	}
-
-	/* NSLookupAndBindSymbol require function name with "_" !! */
-	init_fct = NSAddressOfSymbol( NSLookupAndBindSymbol( buf ) );
-	(*init_fct)();
-
-	return ;
-    }
-#endif /* rld or dyld */
-#endif
-
-#ifdef __BEOS__
-# define DLN_DEFINED
-    {
-      status_t err_stat;  /* BeOS error status code */
-      image_id img_id;    /* extention module unique id */
-      void (*init_fct)(); /* initialize function for extention module */
-
-      /* load extention module */
-      img_id = load_add_on(file);
-      if (img_id <= 0) {
-	rb_loaderror("Failed to load %.200s", file);
-      }
-      
-      /* find symbol for module initialize function. */
-	  /* The Be Book KernelKit Images section described to use
-		 B_SYMBOL_TYPE_TEXT for symbol of function, not
-		 B_SYMBOL_TYPE_CODE. Why ? */
-	  /* strcat(init_fct_symname, "__Fv"); */  /* parameter nothing. */
-	  /* "__Fv" dont need! The Be Book Bug ? */
-      err_stat = get_image_symbol(img_id, buf,
-				  B_SYMBOL_TYPE_TEXT, &init_fct);
-
-      if (err_stat != B_NO_ERROR) {
-	    char real_name[1024];
-	    strcpy(real_name, buf);
-	    strcat(real_name, "__Fv");
-        err_stat = get_image_symbol(img_id, real_name,
-				  B_SYMBOL_TYPE_TEXT, &init_fct);
-      }
-
-      if ((B_BAD_IMAGE_ID == err_stat) || (B_BAD_INDEX == err_stat)) {
-	unload_add_on(img_id);
-	rb_loaderror("Failed to lookup Init function %.200s", file);
-      }
-      else if (B_NO_ERROR != err_stat) {
-	char errmsg[] = "Internal of BeOS version. %.200s (symbol_name = %s)";
-	unload_add_on(img_id);
-	rb_loaderror(errmsg, strerror(err_stat), buf);
-      }
-
-      /* call module initialize function. */
-      (*init_fct)();
-      return;
-    }
-#endif /* __BEOS__*/
-
-#ifdef __MACOS__
-# define DLN_DEFINED
-    {
-      OSErr err;
-      FSSpec libspec;
-      CFragConnectionID connID;
-      Ptr mainAddr;
-      char errMessage[1024];
-      Boolean isfolder, didsomething;
-      Str63 fragname;
-      Ptr symAddr;
-      CFragSymbolClass class;
-      void (*init_fct)();
-      char fullpath[MAXPATHLEN];
-
-      strcpy(fullpath, file);
-
-      /* resolve any aliases to find the real file */
-      c2pstr(fullpath);
-      (void)FSMakeFSSpec(0, 0, fullpath, &libspec);
-      err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
-      if ( err ) {
-	rb_loaderror("Unresolved Alias - %s", file);
-      }
-
-      /* Load the fragment (or return the connID if it is already loaded */
-      fragname[0] = 0;
-      err = GetDiskFragment(&libspec, 0, 0, fragname, 
-			    kLoadCFrag, &connID, &mainAddr,
-			    errMessage);
-      if ( err ) {
-	p2cstr(errMessage);
-	rb_loaderror("%s - %s",errMessage , file);
-      }
-
-      /* Locate the address of the correct init function */
-      c2pstr(buf);
-      err = FindSymbol(connID, buf, &symAddr, &class);
-      if ( err ) {
-	rb_loaderror("Unresolved symbols - %s" , file);
-      }
-	
-      init_fct = (void (*)())symAddr;
-      (*init_fct)();
-      return;
-    }
-#endif /* __MACOS__ */
-
-#ifndef DLN_DEFINED
-    rb_notimplement("dynamic link not supported");
-#endif
-
-#endif /* USE_DLN_A_OUT */
-#endif
-#if !defined(_AIX) && !defined(NeXT)
-  failed:
-    rb_loaderror("%s - %s", dln_strerror(), file);
-#endif
-}
-
-static char *dln_find_1();
-
-char *
-dln_find_exe(fname, path)
-    char *fname;
-    char *path;
-{
-#if defined(__human68k__)
-    if (!path)
-	path = getenv("path");
-    if (!path)
-	path = "/usr/local/bin;/usr/ucb;/usr/bin;/bin;.";
-#else
-    if (!path) path = getenv("PATH");
-    if (!path) path = "/usr/local/bin:/usr/ucb:/usr/bin:/bin:.";
-#endif
-    return dln_find_1(fname, path, 1);
-}
-
-char *
-dln_find_file(fname, path)
-    char *fname;
-    char *path;
-{
-    if (!path) path = ".";
-    return dln_find_1(fname, path, 0);
-}
-
-#if defined(__CYGWIN32__)
-char *
-conv_to_posix_path(win32, posix)
-    char *win32;
-    char *posix;
-{
-    char *first = win32;
-    char *p = win32;
-    char *dst = posix;
-
-    for (p = win32; *p; p++)
-	if (*p == ';') {
-	    *p = 0;
-	    cygwin32_conv_to_posix_path(first, posix);
-	    posix += strlen(posix);
-	    *posix++ = ':';
-	    first = p + 1;
-	    *p = ';';
-	}
-    cygwin32_conv_to_posix_path(first, posix);
-    return dst;
-}
-#endif
-
-static char fbuf[MAXPATHLEN];
-
-static char *
-dln_find_1(fname, path, exe_flag)
-    char *fname;
-    char *path;
-    int exe_flag;		/* non 0 if looking for executable. */
-{
-    register char *dp;
-    register char *ep;
-    register char *bp;
-    struct stat st;
-
-#if defined(__CYGWIN32__)
-    char rubypath[MAXPATHLEN];
-    conv_to_posix_path(path, rubypath);
-    path = rubypath;
-#endif
-#ifndef __MACOS__
-    if (fname[0] == '/') return fname;
-    if (strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0)
-      return fname;
-    if (exe_flag && strchr(fname, '/')) return fname;
-#if defined(MSDOS) || defined(NT) || defined(__human68k__)
-    if (fname[0] == '\\') return fname;
-    if (strlen(fname) > 2 && fname[1] == ':') return fname;
-    if (strncmp(".\\", fname, 2) == 0 || strncmp("..\\", fname, 3) == 0)
-      return fname;
-    if (exe_flag && strchr(fname, '\\')) return fname;
-#endif
-#endif /* __MACOS__ */
-
-    for (dp = path;; dp = ++ep) {
-	register int l;
-	int i;
-	int fspace;
-
-	/* extract a component */
-#if !defined(MSDOS)  && !defined(NT) && !defined(__human68k__) && !defined(__MACOS__)
-	ep = strchr(dp, ':');
-#else
-	ep = strchr(dp, ';');
-#endif
-	if (ep == NULL)
-	    ep = dp+strlen(dp);
-
-	/* find the length of that component */
-	l = ep - dp;
-	bp = fbuf;
-	fspace = sizeof fbuf - 2;
-	if (l > 0) {
-	    /*
-	    **	If the length of the component is zero length,
-	    **	start from the current directory.  If the
-	    **	component begins with "~", start from the
-	    **	user's $HOME environment variable.  Otherwise
-	    **	take the path literally.
-	    */
-
-	    if (*dp == '~' && (l == 1 ||
-#if defined(MSDOS) || defined(NT) || defined(__human68k__)
-			       dp[1] == '\\' || 
-#endif
-			       dp[1] == '/')) {
-		char *home;
-
-		home = getenv("HOME");
-		if (home != NULL) {
-		    i = strlen(home);
-		    if ((fspace -= i) < 0)
-			goto toolong;
-		    memcpy(bp, home, i);
-		    bp += i;
-		}
-		dp++;
-		l--;
-	    }
-	    if (l > 0) {
-		if ((fspace -= l) < 0)
-		    goto toolong;
-		memcpy(bp, dp, l);
-		bp += l;
-	    }
-
-	    /* add a "/" between directory and filename */
-	    if (ep[-1] != '/')
-#ifdef __MACOS__
-		*bp++ = ':';
-#else
-		*bp++ = '/';
-#endif
-	}
-
-	/* now append the file name */
-	i = strlen(fname);
-	if ((fspace -= i) < 0) {
-	  toolong:
-	    fprintf(stderr, "openpath: pathname too long (ignored)\n");
-	    *bp = '\0';
-	    fprintf(stderr, "\tDirectory \"%s\"\n", fbuf);
-	    fprintf(stderr, "\tFile \"%s\"\n", fname);
-	    continue;
-	}
-	memcpy(bp, fname, i + 1);
-
-	if (stat(fbuf, &st) == 0) {
-	    if (exe_flag == 0) return fbuf;
-	    /* looking for executable */
-	    if (eaccess(fbuf, X_OK) == 0) return fbuf;
-	}
-#if defined(MSDOS) || defined(NT) || defined(__human68k__)
-	if (exe_flag) {
-	    static const char *extension[] = {
-#if defined(MSDOS)
-		".com", ".exe", ".bat",
-#if defined(DJGPP)
-		".btm", ".sh", ".ksh", ".pl", ".sed",
-#endif
-#else
-		".r", ".R", ".x", ".X", ".bat", ".BAT",
-#endif
-		(char *) NULL
-	    };
-	    int j;
-
-	    for (j = 0; extension[j]; j++) {
-		if (fspace < strlen(extension[j])) {
-		    fprintf(stderr, "openpath: pathname too long (ignored)\n");
-		    fprintf(stderr, "\tDirectory \"%.*s\"\n", (int) (bp - fbuf), fbuf);
-		    fprintf(stderr, "\tFile \"%s%s\"\n", fname, extension[j]);
-		    continue;
-		}
-		strcpy(bp + i, extension[j]);
-		if (stat(fbuf, &st) == 0)
-		    return fbuf;
-	    }
-	}
-#endif /* MSDOS or NT or __human68k__ */
-	/* if not, and no other alternatives, life is bleak */
-	if (*ep == '\0') {
-	    return NULL;
-	}
-
-	/* otherwise try the next component in the search path */
-    }
-}
+/************************************************
+
+  dln.c -
+
+  $Author: matz $
+  $Date: 1998/12/22 09:01:48 $
+  created at: Tue Jan 18 17:05:06 JST 1994
+
+  Copyright (C) 1993-1998 Yukihiro Matsumoto
+
+************************************************/
+
+#ifdef NT
+#include "missing/file.h"
+#endif
+#include "ruby.h"
+
+char *dln_argv0;
+
+#ifdef _AIX
+#pragma alloca
+#endif
+
+#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
+#include <alloca.h>
+#endif
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# include <strings.h>
+#endif
+
+void *xmalloc();
+void *xcalloc();
+void *xrealloc();
+
+#include <stdio.h>
+#ifndef NT
+# ifndef USE_CWGUSI
+#  include <sys/file.h>
+# endif
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#else
+# define MAXPATHLEN 1024
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifndef NT
+char *strdup();
+char *getenv();
+#endif
+
+#ifdef __MACOS__
+# include <TextUtils.h>
+# include <CodeFragments.h>
+# include <Aliases.h>
+#endif
+
+#ifdef __BEOS__
+# include <image.h>
+#endif
+
+int eaccess();
+
+#if defined(HAVE_DLOPEN) && !defined(USE_DLN_A_OUT) && !defined(__CYGWIN32__) && !defined(_AIX)
+/* dynamic load with dlopen() */
+# define USE_DLN_DLOPEN
+#endif
+
+#ifndef FUNCNAME_PATTERN
+# if defined(__hp9000s300) || defined(__NetBSD__) || defined(__BORLANDC__) || (defined(__FreeBSD__) && __FreeBSD__ < 3) || defined(NeXT) || defined(__WATCOMC__)
+#  define FUNCNAME_PATTERN "_Init_%.200s"
+# else
+#  define FUNCNAME_PATTERN "Init_%.200s"
+# endif
+#endif
+
+static void
+init_funcname(buf, file)
+    char *buf, *file;
+{
+    char *p, *slash;
+
+    /* Load the file as an object one */
+    for (p = file, slash = p-1; *p; p++) /* Find position of last '/' */
+#ifdef __MACOS__
+	if (*p == ':') slash = p;
+#else
+	if (*p == '/') slash = p;
+#endif
+
+    sprintf(buf, FUNCNAME_PATTERN, slash + 1);
+    for (p = buf; *p; p++) {         /* Delete suffix it it exists */
+	if (*p == '.') {
+	    *p = '\0'; break;
+	}
+    }
+}
+
+#ifdef USE_DLN_A_OUT
+
+#ifndef LIBC_NAME
+# define LIBC_NAME "libc.a"
+#endif
+
+#ifndef DLN_DEFAULT_LIB_PATH
+#  define DLN_DEFAULT_LIB_PATH "/lib:/usr/lib:/usr/local/lib:."
+#endif
+
+#include <errno.h>
+
+static int dln_errno;
+
+#define DLN_ENOEXEC	ENOEXEC	/* Exec format error */
+#define DLN_ECONFL	201	/* Symbol name conflict */
+#define DLN_ENOINIT	202	/* No inititalizer given */
+#define DLN_EUNDEF	203	/* Undefine symbol remains */
+#define DLN_ENOTLIB	204	/* Not a library file */
+#define DLN_EBADLIB	205	/* Malformed library file */
+#define DLN_EINIT	206	/* Not initialized */
+
+static int dln_init_p = 0;
+
+#include "st.h"
+#include <ar.h>
+#include <a.out.h>
+#ifndef N_COMM
+# define N_COMM 0x12
+#endif
+#ifndef N_MAGIC
+# define N_MAGIC(x) (x).a_magic
+#endif
+
+#define INVALID_OBJECT(h) (N_MAGIC(h) != OMAGIC)
+
+static st_table *sym_tbl;
+static st_table *undef_tbl;
+
+static int load_lib();
+
+static int
+load_header(fd, hdrp, disp)
+    int fd;
+    struct exec *hdrp;
+    long disp;
+{
+    int size;
+
+    lseek(fd, disp, 0);
+    size = read(fd, hdrp, sizeof(struct exec));
+    if (size == -1) {
+	dln_errno = errno;
+	return -1;
+    }
+    if (size != sizeof(struct exec) || N_BADMAG(*hdrp)) {
+	dln_errno = DLN_ENOEXEC;
+	return -1;
+    }
+    return 0;
+}
+
+#if defined(sequent)
+#define RELOC_SYMBOL(r)			((r)->r_symbolnum)
+#define RELOC_MEMORY_SUB_P(r)		((r)->r_bsr)
+#define RELOC_PCREL_P(r)		((r)->r_pcrel || (r)->r_bsr)
+#define RELOC_TARGET_SIZE(r)		((r)->r_length)
+#endif
+
+/* Default macros */
+#ifndef RELOC_ADDRESS
+#define RELOC_ADDRESS(r)		((r)->r_address)
+#define RELOC_EXTERN_P(r)		((r)->r_extern)
+#define RELOC_SYMBOL(r)			((r)->r_symbolnum)
+#define RELOC_MEMORY_SUB_P(r)		0
+#define RELOC_PCREL_P(r)		((r)->r_pcrel)
+#define RELOC_TARGET_SIZE(r)		((r)->r_length)
+#endif
+
+#if defined(sun) && defined(sparc)
+/* Sparc (Sun 4) macros */
+#  undef relocation_info
+#  define relocation_info reloc_info_sparc
+#  define R_RIGHTSHIFT(r)	(reloc_r_rightshift[(r)->r_type])
+#  define R_BITSIZE(r) 		(reloc_r_bitsize[(r)->r_type])
+#  define R_LENGTH(r)		(reloc_r_length[(r)->r_type])
+static int reloc_r_rightshift[] = {
+  0, 0, 0, 0, 0, 0, 2, 2, 10, 0, 0, 0, 0, 0, 0,
+};
+static int reloc_r_bitsize[] = {
+  8, 16, 32, 8, 16, 32, 30, 22, 22, 22, 13, 10, 32, 32, 16,
+};
+static int reloc_r_length[] = {
+  0, 1, 2, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+};
+#  define R_PCREL(r) \
+    ((r)->r_type >= RELOC_DISP8 && (r)->r_type <= RELOC_WDISP22)
+#  define R_SYMBOL(r) ((r)->r_index)
+#endif
+
+#if defined(sequent)
+#define R_SYMBOL(r)		((r)->r_symbolnum)
+#define R_MEMORY_SUB(r)		((r)->r_bsr)
+#define R_PCREL(r)		((r)->r_pcrel || (r)->r_bsr)
+#define R_LENGTH(r)		((r)->r_length)
+#endif
+
+#ifndef R_SYMBOL
+#  define R_SYMBOL(r) 		((r)->r_symbolnum)
+#  define R_MEMORY_SUB(r)	0
+#  define R_PCREL(r)  		((r)->r_pcrel)
+#  define R_LENGTH(r) 		((r)->r_length)
+#endif
+
+static struct relocation_info *
+load_reloc(fd, hdrp, disp)
+     int fd;
+     struct exec *hdrp;
+     long disp;
+{
+    struct relocation_info *reloc;
+    int size;
+
+    lseek(fd, disp + N_TXTOFF(*hdrp) + hdrp->a_text + hdrp->a_data, 0);
+    size = hdrp->a_trsize + hdrp->a_drsize;
+    reloc = (struct relocation_info*)xmalloc(size);
+    if (reloc == NULL) {
+	dln_errno = errno;
+	return NULL;
+    }
+
+    if (read(fd, reloc, size) !=  size) {
+	dln_errno = errno;
+	free(reloc);
+	return NULL;
+    }
+
+    return reloc;
+}
+
+static struct nlist *
+load_sym(fd, hdrp, disp)
+    int fd;
+    struct exec *hdrp;
+    long disp;
+{
+    struct nlist * buffer;
+    struct nlist * sym;
+    struct nlist * end;
+    long displ;
+    int size;
+
+    lseek(fd, N_SYMOFF(*hdrp) + hdrp->a_syms + disp, 0);
+    if (read(fd, &size, sizeof(int)) != sizeof(int)) {
+	goto err_noexec;
+    }
+
+    buffer = (struct nlist*)xmalloc(hdrp->a_syms + size);
+    if (buffer == NULL) {
+	dln_errno = errno;
+	return NULL;
+    }
+
+    lseek(fd, disp + N_SYMOFF(*hdrp), 0);
+    if (read(fd, buffer, hdrp->a_syms + size) != hdrp->a_syms + size) {
+	free(buffer);
+	goto err_noexec;
+    }
+
+    sym = buffer;
+    end = sym + hdrp->a_syms / sizeof(struct nlist);
+    displ = (long)buffer + (long)(hdrp->a_syms);
+
+    while (sym < end) {
+	sym->n_un.n_name = (char*)sym->n_un.n_strx + displ;
+	sym++;
+    }
+    return buffer;
+
+  err_noexec:
+    dln_errno = DLN_ENOEXEC;
+    return NULL;
+}
+
+static st_table *
+sym_hash(hdrp, syms)
+    struct exec *hdrp;
+    struct nlist *syms;
+{
+    st_table *tbl;
+    struct nlist *sym = syms;
+    struct nlist *end = syms + (hdrp->a_syms / sizeof(struct nlist));
+
+    tbl = st_init_strtable();
+    if (tbl == NULL) {
+	dln_errno = errno;
+	return NULL;
+    }
+
+    while (sym < end) {
+	st_insert(tbl, sym->n_un.n_name, sym);
+	sym++;
+    }
+    return tbl;
+}
+
+static int
+dln_init(prog)
+    char *prog;
+{
+    char *file;
+    int fd;
+    struct exec hdr;
+    struct nlist *syms;
+
+    if (dln_init_p == 1) return 0;
+
+    file = dln_find_exe(prog, NULL);
+    if (file == NULL || (fd = open(file, O_RDONLY)) < 0) {
+	dln_errno = errno;
+	return -1;
+    }
+
+    if (load_header(fd, &hdr, 0) == -1) return -1;
+    syms = load_sym(fd, &hdr, 0);
+    if (syms == NULL) {
+	close(fd);
+	return -1;
+    }
+    sym_tbl = sym_hash(&hdr, syms);
+    if (sym_tbl == NULL) {	/* file may be start with #! */
+	char c = '\0';
+	char buf[MAXPATHLEN];
+	char *p;
+
+	free(syms);
+	lseek(fd, 0L, 0);
+	if (read(fd, &c, 1) == -1) {
+	    dln_errno = errno;
+	    return -1;
+	}
+	if (c != '#') goto err_noexec;
+	if (read(fd, &c, 1) == -1) {
+	    dln_errno = errno;
+	    return -1;
+	}
+	if (c != '!') goto err_noexec;
+
+	p = buf;
+	/* skip forwading spaces */
+	while (read(fd, &c, 1) == 1) {
+	    if (c == '\n') goto err_noexec;
+	    if (c != '\t' && c != ' ') {
+		*p++ = c;
+		break;
+	    }
+	}
+	/* read in command name */
+	while (read(fd, p, 1) == 1) {
+	    if (*p == '\n' || *p == '\t' || *p == ' ') break;
+	    p++;
+	}
+	*p = '\0';
+
+	return dln_init(buf);
+    }
+    dln_init_p = 1;
+    undef_tbl = st_init_strtable();
+    close(fd);
+    return 0;
+
+  err_noexec:
+    close(fd);
+    dln_errno = DLN_ENOEXEC;
+    return -1;
+}
+
+static long
+load_text_data(fd, hdrp, bss, disp)
+    int fd;
+    struct exec *hdrp;
+    int bss;
+    long disp;
+{
+    int size;
+    unsigned char* addr;
+
+    lseek(fd, disp + N_TXTOFF(*hdrp), 0);
+    size = hdrp->a_text + hdrp->a_data;
+
+    if (bss == -1) size += hdrp->a_bss;
+    else if (bss > 1) size += bss;
+
+    addr = (unsigned char*)xmalloc(size);
+    if (addr == NULL) {
+	dln_errno = errno;
+	return 0;
+    }
+
+    if (read(fd, addr, size) !=  size) {
+	dln_errno = errno;
+	free(addr);
+	return 0;
+    }
+
+    if (bss == -1) {
+	memset(addr +  hdrp->a_text + hdrp->a_data, 0, hdrp->a_bss);
+    }
+    else if (bss > 0) {
+	memset(addr +  hdrp->a_text + hdrp->a_data, 0, bss);
+    }
+
+    return (long)addr;
+}
+
+static int
+underb_f_print(key, value)
+    char *key, *value;
+{
+    fprintf(stderr, "  %s\n", key);
+    return ST_CONTINUE;
+}
+
+static void
+dln_print_undef()
+{
+    fprintf(stderr, " Undefined symbols:\n");
+    st_foreach(undef_tbl, underb_f_print, NULL);
+}
+
+static void
+dln_undefined()
+{
+    if (undef_tbl->num_entries > 0) {
+	fprintf(stderr, "dln: Calling undefined function\n");
+	dln_print_undef();
+	rb_exit(1);
+    }
+}
+
+struct undef {
+    char *name;
+    struct relocation_info reloc;
+    long base;
+    char *addr;
+    union {
+	char c;
+	short s;
+	long l;
+    } u;
+};
+
+static st_table *reloc_tbl = NULL;
+static void
+link_undef(name, base, reloc)
+    char *name;
+    long base;
+    struct relocation_info *reloc;
+{
+    static int u_no = 0;
+    struct undef *obj;
+    char *addr = (char*)(reloc->r_address + base);
+
+    obj = (struct undef*)xmalloc(sizeof(struct undef));
+    obj->name = strdup(name);
+    obj->reloc = *reloc;
+    obj->base = base;
+    switch (R_LENGTH(reloc)) {
+      case 0:		/* byte */
+	obj->u.c = *addr;
+	break;
+      case 1:		/* word */
+	obj->u.s = *(short*)addr;
+	break;
+      case 2:		/* long */
+	obj->u.l = *(long*)addr;
+	break;
+    }
+    if (reloc_tbl == NULL) {
+	reloc_tbl = st_init_numtable();
+    }
+    st_insert(reloc_tbl, u_no++, obj);
+}
+
+struct reloc_arg {
+    char *name;
+    long value;
+};
+
+static int
+reloc_undef(no, undef, arg)
+    int no;
+    struct undef *undef;
+    struct reloc_arg *arg;
+{
+    int datum;
+    char *address;
+#if defined(sun) && defined(sparc)
+    unsigned int mask = 0;
+#endif
+
+    if (strcmp(arg->name, undef->name) != 0) return ST_CONTINUE;
+    address = (char*)(undef->base + undef->reloc.r_address);
+    datum = arg->value;
+
+    if (R_PCREL(&(undef->reloc))) datum -= undef->base;
+#if defined(sun) && defined(sparc)
+    datum += undef->reloc.r_addend;
+    datum >>= R_RIGHTSHIFT(&(undef->reloc));
+    mask = (1 << R_BITSIZE(&(undef->reloc))) - 1;
+    mask |= mask -1;
+    datum &= mask;
+    switch (R_LENGTH(&(undef->reloc))) {
+      case 0:
+	*address = undef->u.c;
+	*address &= ~mask;
+	*address |= datum;
+	break;
+      case 1:
+	*(short *)address = undef->u.s;
+	*(short *)address &= ~mask;
+	*(short *)address |= datum;
+	break;
+      case 2:
+	*(long *)address = undef->u.l;
+	*(long *)address &= ~mask;
+	*(long *)address |= datum;
+	break;
+    }
+#else
+    switch (R_LENGTH(&(undef->reloc))) {
+      case 0:		/* byte */
+	if (R_MEMORY_SUB(&(undef->reloc)))
+	    *address = datum - *address;
+	else *address = undef->u.c + datum;
+	break;
+      case 1:		/* word */
+	if (R_MEMORY_SUB(&(undef->reloc)))
+	    *(short*)address = datum - *(short*)address;
+	else *(short*)address = undef->u.s + datum;
+	break;
+      case 2:		/* long */
+	if (R_MEMORY_SUB(&(undef->reloc)))
+	    *(long*)address = datum - *(long*)address;
+	else *(long*)address = undef->u.l + datum;
+	break;
+    }
+#endif
+    free(undef->name);
+    free(undef);
+    return ST_DELETE;
+}
+
+static void
+unlink_undef(name, value)
+    char *name;
+    long value;
+{
+    struct reloc_arg arg;
+
+    arg.name = name;
+    arg.value = value;
+    st_foreach(reloc_tbl, reloc_undef, &arg);
+}
+
+#ifdef N_INDR
+struct indr_data {
+    char *name0, *name1;
+};
+
+static int
+reloc_repl(no, undef, data)
+    int no;
+    struct undef *undef;
+    struct indr_data *data;
+{
+    if (strcmp(data->name0, undef->name) == 0) {
+	free(undef->name);
+	undef->name = strdup(data->name1);
+    }
+    return ST_CONTINUE;
+}
+#endif
+
+static int
+load_1(fd, disp, need_init)
+    int fd;
+    long disp;
+    char *need_init;
+{
+    static char *libc = LIBC_NAME;
+    struct exec hdr;
+    struct relocation_info *reloc = NULL;
+    long block = 0;
+    long new_common = 0; /* Length of new common */
+    struct nlist *syms = NULL;
+    struct nlist *sym;
+    struct nlist *end;
+    int init_p = 0;
+    char buf[256];
+
+    if (load_header(fd, &hdr, disp) == -1) return -1;
+    if (INVALID_OBJECT(hdr)) {
+	dln_errno = DLN_ENOEXEC;
+	return -1;
+    }
+    reloc = load_reloc(fd, &hdr, disp);
+    if (reloc == NULL) return -1;
+    syms = load_sym(fd, &hdr, disp);
+    if (syms == NULL) return -1;
+
+    sym = syms;
+    end = syms + (hdr.a_syms / sizeof(struct nlist));
+    while (sym < end) {
+	struct nlist *old_sym;
+	int value = sym->n_value;
+
+#ifdef N_INDR
+	if (sym->n_type == (N_INDR | N_EXT)) {
+	    char *key = sym->n_un.n_name;
+
+	    if (st_lookup(sym_tbl, sym[1].n_un.n_name, &old_sym)) {
+		if (st_delete(undef_tbl, &key, NULL)) {
+		    unlink_undef(key, old_sym->n_value);
+		    free(key);
+		}
+	    }
+	    else {
+		struct indr_data data;
+
+		data.name0 = sym->n_un.n_name;
+		data.name1 = sym[1].n_un.n_name;
+		st_foreach(reloc_tbl, reloc_repl, &data);
+
+		st_insert(undef_tbl, strdup(sym[1].n_un.n_name), NULL);
+		if (st_delete(undef_tbl, &key, NULL)) {
+		    free(key);
+		}
+	    }
+	    sym += 2;
+	    continue;
+	}
+#endif
+	if (sym->n_type == (N_UNDF | N_EXT)) {
+	    if (st_lookup(sym_tbl, sym->n_un.n_name, &old_sym) == 0) {
+		old_sym = NULL;
+	    }
+
+	    if (value) {
+		if (old_sym) {
+		    sym->n_type = N_EXT | N_COMM;
+		    sym->n_value = old_sym->n_value;
+		}
+		else {
+		    int rnd =
+			value >= sizeof(double) ? sizeof(double) - 1
+			    : value >= sizeof(long) ? sizeof(long) - 1
+				: sizeof(short) - 1;
+
+		    sym->n_type = N_COMM;
+		    new_common += rnd;
+		    new_common &= ~(long)rnd;
+		    sym->n_value = new_common;
+		    new_common += value;
+		}
+	    }
+	    else {
+		if (old_sym) {
+		    sym->n_type = N_EXT | N_COMM;
+		    sym->n_value = old_sym->n_value;
+		}
+		else {
+		    sym->n_value = (long)dln_undefined;
+		    st_insert(undef_tbl, strdup(sym->n_un.n_name), NULL);
+		}
+	    }
+	}
+	sym++;
+    }
+
+    block = load_text_data(fd, &hdr, hdr.a_bss + new_common, disp);
+    if (block == 0) goto err_exit;
+
+    sym = syms;
+    while (sym < end) {
+	struct nlist *new_sym;
+	char *key;
+
+	switch (sym->n_type) {
+	  case N_COMM:
+	    sym->n_value += hdr.a_text + hdr.a_data;
+	  case N_TEXT|N_EXT:
+	  case N_DATA|N_EXT:
+
+	    sym->n_value += block;
+
+	    if (st_lookup(sym_tbl, sym->n_un.n_name, &new_sym) != 0
+		&& new_sym->n_value != (long)dln_undefined) {
+		dln_errno = DLN_ECONFL;
+		goto err_exit;
+	    }
+
+	    key = sym->n_un.n_name;
+	    if (st_delete(undef_tbl, &key, NULL) != 0) {
+		unlink_undef(key, sym->n_value);
+		free(key);
+	    }
+
+	    new_sym = (struct nlist*)xmalloc(sizeof(struct nlist));
+	    *new_sym = *sym;
+	    new_sym->n_un.n_name = strdup(sym->n_un.n_name);
+	    st_insert(sym_tbl, new_sym->n_un.n_name, new_sym);
+	    break;
+
+	  case N_TEXT:
+	  case N_DATA:
+	    sym->n_value += block;
+	    break;
+	}
+	sym++;
+    }
+
+    /*
+     * First comes the text-relocation
+     */
+    {
+	struct relocation_info * rel = reloc;
+	struct relocation_info * rel_beg = reloc +
+	    (hdr.a_trsize/sizeof(struct relocation_info));
+	struct relocation_info * rel_end = reloc +
+	    (hdr.a_trsize+hdr.a_drsize)/sizeof(struct relocation_info);
+
+	while (rel < rel_end) {
+	    char *address = (char*)(rel->r_address + block);
+	    long datum = 0;
+#if defined(sun) && defined(sparc)
+	    unsigned int mask = 0;
+#endif
+
+	    if(rel >= rel_beg)
+		address += hdr.a_text;
+
+	    if (rel->r_extern) { /* Look it up in symbol-table */
+		sym = &(syms[R_SYMBOL(rel)]);
+		switch (sym->n_type) {
+		  case N_EXT|N_UNDF:
+		    link_undef(sym->n_un.n_name, block, rel);
+		  case N_EXT|N_COMM:
+		  case N_COMM:
+		    datum = sym->n_value;
+		    break;
+		  default:
+		    goto err_exit;
+		}
+	    } /* end.. look it up */
+	    else { /* is static */
+		switch (R_SYMBOL(rel)) { 
+		  case N_TEXT:
+		  case N_DATA:
+		    datum = block;
+		    break;
+		  case N_BSS:
+		    datum = block +  new_common;
+		    break;
+		  case N_ABS:
+		    break;
+		}
+	    } /* end .. is static */
+	    if (R_PCREL(rel)) datum -= block;
+
+#if defined(sun) && defined(sparc)
+	    datum += rel->r_addend;
+	    datum >>= R_RIGHTSHIFT(rel);
+	    mask = (1 << R_BITSIZE(rel)) - 1;
+	    mask |= mask -1;
+	    datum &= mask;
+
+	    switch (R_LENGTH(rel)) {
+	      case 0:
+		*address &= ~mask;
+		*address |= datum;
+		break;
+	      case 1:
+		*(short *)address &= ~mask;
+		*(short *)address |= datum;
+		break;
+	      case 2:
+		*(long *)address &= ~mask;
+		*(long *)address |= datum;
+		break;
+	    }
+#else
+	    switch (R_LENGTH(rel)) {
+	      case 0:		/* byte */
+		if (datum < -128 || datum > 127) goto err_exit;
+		*address += datum;
+		break;
+	      case 1:		/* word */
+		*(short *)address += datum;
+		break;
+	      case 2:		/* long */
+		*(long *)address += datum;
+		break;
+	    }
+#endif
+	    rel++;
+	}
+    }
+
+    if (need_init) {
+	int len;
+	char **libs_to_be_linked = 0;
+
+	if (undef_tbl->num_entries > 0) {
+	    if (load_lib(libc) == -1) goto err_exit;
+	}
+
+	init_funcname(buf, need_init);
+	len = strlen(buf);
+
+	for (sym = syms; sym<end; sym++) {
+	    char *name = sym->n_un.n_name;
+	    if (name[0] == '_' && sym->n_value >= block) {
+		if (strcmp(name+1, "dln_libs_to_be_linked") == 0) {
+		    libs_to_be_linked = (char**)sym->n_value;
+		}
+		else if (strcmp(name+1, buf) == 0) {
+		    init_p = 1;
+		    ((int (*)())sym->n_value)();
+		}
+	    }
+	}
+	if (libs_to_be_linked && undef_tbl->num_entries > 0) {
+	    while (*libs_to_be_linked) {
+		load_lib(*libs_to_be_linked);
+		libs_to_be_linked++;
+	    }
+	}
+    }
+    free(reloc);
+    free(syms);
+    if (need_init) {
+	if (init_p == 0) {
+	    dln_errno = DLN_ENOINIT;
+	    return -1;
+	}
+	if (undef_tbl->num_entries > 0) {
+	    if (load_lib(libc) == -1) goto err_exit;
+	    if (undef_tbl->num_entries > 0) {
+		dln_errno = DLN_EUNDEF;
+		return -1;
+	    }
+	}
+    }
+    return 0;
+
+  err_exit:
+    if (syms) free(syms);
+    if (reloc) free(reloc);
+    if (block) free((char*)block);
+    return -1;
+}
+
+static int target_offset;
+static int
+search_undef(key, value, lib_tbl)
+    char *key;
+    int value;
+    st_table *lib_tbl;
+{
+    int offset;
+
+    if (st_lookup(lib_tbl, key, &offset) == 0) return ST_CONTINUE;
+    target_offset = offset;
+    return ST_STOP;
+}
+
+struct symdef {
+    int rb_str_index;
+    int lib_offset;
+};
+
+char *dln_librrb_ary_path = DLN_DEFAULT_LIB_PATH;
+
+static int
+load_lib(lib)
+    char *lib;
+{
+    char *path, *file;
+    char armagic[SARMAG];
+    int fd, size;
+    struct ar_hdr ahdr;
+    st_table *lib_tbl = NULL;
+    int *data, nsym;
+    struct symdef *base;
+    char *name_base;
+
+    if (dln_init_p == 0) {
+	dln_errno = DLN_ENOINIT;
+	return -1;
+    }
+
+    if (undef_tbl->num_entries == 0) return 0;
+    dln_errno = DLN_EBADLIB;
+
+    if (lib[0] == '-' && lib[1] == 'l') {
+	char *p = alloca(strlen(lib) + 4);
+	sprintf(p, "lib%s.a", lib+2);
+	lib = p;
+    }
+
+    /* library search path: */
+    /* look for environment variable DLN_LIBRARY_PATH first. */
+    /* then variable dln_librrb_ary_path. */
+    /* if path is still NULL, use "." for path. */
+    path = getenv("DLN_LIBRARY_PATH");
+    if (path == NULL) path = dln_librrb_ary_path;
+
+    file = dln_find_file(lib, path);
+    fd = open(file, O_RDONLY);
+    if (fd == -1) goto syserr;
+    size = read(fd, armagic, SARMAG);
+    if (size == -1) goto syserr;
+
+    if (size != SARMAG) {
+	dln_errno = DLN_ENOTLIB;
+	goto badlib;
+    }
+    size = read(fd, &ahdr, sizeof(ahdr));
+    if (size == -1) goto syserr;
+    if (size != sizeof(ahdr) || sscanf(ahdr.ar_size, "%d", &size) != 1) {
+	goto badlib;
+    }
+
+    if (strncmp(ahdr.ar_name, "__.SYMDEF", 9) == 0) {
+	/* make hash table from __.SYMDEF */
+
+	lib_tbl = st_init_strtable();
+	data = (int*)xmalloc(size);
+	if (data == NULL) goto syserr;
+	size = read(fd, data, size);
+	nsym = *data / sizeof(struct symdef);
+	base = (struct symdef*)(data + 1);
+	name_base = (char*)(base + nsym) + sizeof(int);
+	while (nsym > 0) {
+	    char *name = name_base + base->rb_str_index;
+
+	    st_insert(lib_tbl, name, base->lib_offset + sizeof(ahdr));
+	    nsym--;
+	    base++;
+	}
+	for (;;) {
+	    target_offset = -1;
+	    st_foreach(undef_tbl, search_undef, lib_tbl);
+	    if (target_offset == -1) break;
+	    if (load_1(fd, target_offset, 0) == -1) {
+		st_free_table(lib_tbl);
+		free(data);
+		goto badlib;
+	    }
+	    if (undef_tbl->num_entries == 0) break;
+	}
+	free(data);
+	st_free_table(lib_tbl);
+    }
+    else {
+	/* linear library, need to scan (FUTURE) */
+
+	for (;;) {
+	    int offset = SARMAG;
+	    int found = 0;
+	    struct exec hdr;
+	    struct nlist *syms, *sym, *end;
+
+	    while (undef_tbl->num_entries > 0) {
+		found = 0;
+		lseek(fd, offset, 0);
+		size = read(fd, &ahdr, sizeof(ahdr));
+		if (size == -1) goto syserr;
+		if (size == 0) break;
+		if (size != sizeof(ahdr)
+		    || sscanf(ahdr.ar_size, "%d", &size) != 1) {
+		    goto badlib;
+		}
+		offset += sizeof(ahdr);
+		if (load_header(fd, &hdr, offset) == -1)
+		    goto badlib;
+		syms = load_sym(fd, &hdr, offset);
+		if (syms == NULL) goto badlib;
+		sym = syms;
+		end = syms + (hdr.a_syms / sizeof(struct nlist));
+		while (sym < end) {
+		    if (sym->n_type == N_EXT|N_TEXT
+			&& st_lookup(undef_tbl, sym->n_un.n_name, NULL)) {
+			break;
+		    }
+		    sym++;
+		}
+		if (sym < end) {
+		    found++;
+		    free(syms);
+		    if (load_1(fd, offset, 0) == -1) {
+			goto badlib;
+		    }
+		}
+		offset += size;
+		if (offset & 1) offset++;
+	    }
+	    if (found) break;
+	}
+    }
+    close(fd);
+    return 0;
+
+  syserr:
+    dln_errno = errno;
+  badlib:
+    if (fd >= 0) close(fd);
+    return -1;
+}
+
+static int
+load(file)
+    char *file;
+{
+    int fd;
+    int result;
+
+    if (dln_init_p == 0) {
+	if (dln_init(dln_argv0) == -1) return -1;
+    }
+    result = strlen(file);
+    if (file[result-1] == 'a') {
+	return load_lib(file);
+    }
+
+    fd = open(file, O_RDONLY);
+    if (fd == -1) {
+	dln_errno = errno;
+	return -1;
+    }
+    result = load_1(fd, 0, file);
+    close(fd);
+
+    return result;
+}
+
+void*
+dln_sym(name)
+    char *name;
+{
+    struct nlist *sym;
+
+    if (st_lookup(sym_tbl, name, &sym))
+	return (void*)sym->n_value;
+    return NULL;
+}
+
+#endif /* USE_DLN_A_OUT */
+
+#ifdef USE_DLN_DLOPEN
+# ifdef __NetBSD__
+#  include <nlist.h>
+#  include <link.h>
+# else
+#  include <dlfcn.h>
+# endif
+#endif
+
+#ifdef hpux
+#include <errno.h>
+#include "dl.h"
+#endif
+
+#if defined(_AIX)
+#include <ctype.h>	/* for isdigit()	*/
+#include <errno.h>	/* for global errno	*/
+#include <sys/ldr.h>
+#endif
+
+#ifdef NeXT
+#if NS_TARGET_MAJOR < 4
+#include <mach-o/rld.h>
+#else
+#include <mach-o/dyld.h>
+#endif
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+static char *
+dln_strerror()
+{
+#ifdef USE_DLN_A_OUT
+    char *strerror();
+
+    switch (dln_errno) {
+      case DLN_ECONFL:
+	return "Symbol name conflict";
+      case DLN_ENOINIT:
+	return "No inititalizer given";
+      case DLN_EUNDEF:
+	return "Unresolved symbols";
+      case DLN_ENOTLIB:
+	return "Not a library file";
+      case DLN_EBADLIB:
+	return "Malformed library file";
+      case DLN_EINIT:
+	return "Not initialized";
+      default:
+	return strerror(dln_errno);
+    }
+#endif
+
+#ifdef USE_DLN_DLOPEN
+    return (char*)dlerror();
+#endif
+
+#ifdef _WIN32
+    static char message[1024];
+    int error = GetLastError();
+    char *p = message;
+    p += sprintf(message, "%d: ", error);
+    FormatMessage(
+	FORMAT_MESSAGE_FROM_SYSTEM,
+	NULL,
+	error,
+	MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+	p,
+	sizeof message - strlen(message),
+	NULL);
+
+    for (p = message; *p; p++) {
+	if (*p == '\n' || *p == '\r')
+	    *p = ' ';
+    }
+    return message;
+#endif
+}
+
+
+#if defined(_AIX)
+static void
+aix_loaderror(char *pathname)
+{
+    char *message[8], errbuf[1024];
+    int i,j;
+
+    struct errtab { 
+	int errno;
+	char *errstr;
+    } load_errtab[] = {
+	{L_ERROR_TOOMANY,	"too many errors, rest skipped."},
+	{L_ERROR_NOLIB,		"can't load library:"},
+	{L_ERROR_UNDEF,		"can't find symbol in library:"},
+	{L_ERROR_RLDBAD,
+	     "RLD index out of range or bad relocation type:"},
+	{L_ERROR_FORMAT,	"not a valid, executable xcoff file:"},
+	{L_ERROR_MEMBER,
+	     "file not an archive or does not contain requested member:"},
+	{L_ERROR_TYPE,		"symbol table mismatch:"},
+	{L_ERROR_ALIGN,		"text allignment in file is wrong."},
+	{L_ERROR_SYSTEM,	"System error:"},
+	{L_ERROR_ERRNO,		NULL}
+    };
+
+#define LOAD_ERRTAB_LEN	(sizeof(load_errtab)/sizeof(load_errtab[0]))
+#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
+
+    sprintf(errbuf, "load failed - %.200s ", pathname);
+
+    if (!loadquery(1, &message[0], sizeof(message))) 
+	ERRBUF_APPEND(strerror(errno));
+    for(i = 0; message[i] && *message[i]; i++) {
+	int nerr = atoi(message[i]);
+	for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
+	    if (nerr == load_errtab[i].errno && load_errtab[i].errstr)
+		ERRBUF_APPEND(load_errtab[i].errstr);
+	}
+	while (isdigit(*message[i])) message[i]++ ; 
+	ERRBUF_APPEND(message[i]);
+	ERRBUF_APPEND("\n");
+    }
+    errbuf[strlen(errbuf)-1] = '\0';	/* trim off last newline */
+    rb_loaderror(errbuf);
+    return;
+}
+#endif
+
+void
+dln_load(file)
+    char *file;
+{
+#ifdef _WIN32
+    HINSTANCE handle;
+    char winfile[255];
+    void (*init_fct)();
+    char buf[MAXPATHLEN];
+
+    /* Load the file as an object one */
+    init_funcname(buf, file);
+
+#ifdef __CYGWIN32__
+    cygwin32_conv_to_win32_path(file, winfile);
+#else
+    strcpy(winfile, file);
+#endif
+
+    /* Load file */
+    if ((handle =
+	LoadLibraryExA(winfile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) == NULL) {
+        printf("LoadLibraryExA: %s\n", winfile);
+	goto failed;
+    }
+
+#ifdef __CYGWIN32__
+    init_fct = (void(*)())GetProcAddress(handle, "impure_setup");
+
+    if (init_fct)
+	init_fct(_impure_ptr);
+#endif
+
+    if ((init_fct = (void(*)())GetProcAddress(handle, buf)) == NULL) {
+        printf("GetProcAddress %s\n", buf);
+	goto failed;
+    }
+    /* Call the init code */
+    (*init_fct)();
+    return;
+#else
+#ifdef USE_DLN_A_OUT
+    if (load(file) == -1) {
+	goto failed;
+    }
+    return;
+#else
+
+    char buf[MAXPATHLEN];
+    /* Load the file as an object one */
+    init_funcname(buf, file);
+
+#ifdef USE_DLN_DLOPEN
+#define DLN_DEFINED
+    {
+	void *handle;
+	void (*init_fct)();
+
+# ifndef RTLD_LAZY
+#  define RTLD_LAZY 1
+# endif
+# ifndef RTLD_GLOBAL
+#  define RTLD_GLOBAL 0
+# endif
+
+	/* Load file */
+	if ((handle = (void*)dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == NULL) {
+	    goto failed;
+	}
+
+	if ((init_fct = (void(*)())dlsym(handle, buf)) == NULL) {
+	    goto failed;
+	}
+	/* Call the init code */
+	(*init_fct)();
+	return;
+    }
+#endif /* USE_DLN_DLOPEN */
+
+#ifdef hpux
+#define DLN_DEFINED
+    {
+	shl_t lib = NULL;
+	int flags;
+	void (*init_fct)();
+
+	flags = BIND_DEFERRED;
+	lib = shl_load(file, flags, 0);
+	if (lib == NULL) {
+	    extern int errno;
+	    rb_loaderror("%s - %s", strerror(errno), file);
+	}
+	shl_findsym(&lib, buf, TYPE_PROCEDURE, (void*)&init_fct);
+	if (init_fct == NULL) {
+	    shl_findsym(&lib, buf, TYPE_UNDEFINED, (void*)&init_fct);
+	    if (init_fct == NULL) {
+		errno = ENOSYM;
+		rb_loaderror("%s - %s", strerror(ENOSYM), file);
+	    }
+	}
+	(*init_fct)();
+	return;
+    }
+#endif /* hpux */
+
+#if defined(_AIX)
+#define DLN_DEFINED
+    {
+	void (*init_fct)();
+
+	init_fct = (void(*)())load(file, 1, 0);
+	if (init_fct == NULL) {
+	    aix_loaderror(file);
+	}
+	(*init_fct)();
+	return;
+    }
+#endif /* _AIX */
+
+#ifdef NeXT
+#define DLN_DEFINED
+/*----------------------------------------------------
+   By SHIROYAMA Takayuki Psi@fortune.nest.or.jp
+ 
+   Special Thanks...
+    Yu tomoak-i@is.aist-nara.ac.jp,
+    Mi hisho@tasihara.nest.or.jp,
+    and... Miss ARAI Akino(^^;)
+ ----------------------------------------------------*/
+#if NS_TARGET_MAJOR < 4 /* NeXTSTEP rld functions */
+    {
+	unsigned long init_address;
+	char *object_files[2] = {NULL, NULL};
+
+	void (*init_fct)();
+	
+	object_files[0] = file;
+	
+	/* Load object file, if return value ==0 ,  load failed*/
+	if(rld_load(NULL, NULL, object_files, NULL) == 0) {
+	    rb_loaderror("Failed to load %.200s", file);
+	}
+
+	/* lookup the initial function */
+	if(rld_lookup(NULL, buf, &init_address) == 0) {
+	    rb_loaderror("Failed to lookup Init function %.200s", file);
+	}
+
+	 /* Cannot call *init_address directory, so copy this value to
+	    funtion pointer */
+
+	init_fct = (void(*)())init_address;
+	(*init_fct)();
+	return ;
+    }
+#else/* OPENSTEP dyld functions */
+    {
+	int dyld_result ;
+	NSObjectFileImage obj_file ; /* handle, but not use it */
+	/* "file" is module file name .
+	   "buf" is initial function name with "_" . */
+
+	void (*init_fct)();
+
+
+	dyld_result = NSCreateObjectFileImageFromFile( file, &obj_file );
+
+	if (dyld_result != NSObjectFileImageSuccess) {
+	    rb_loaderror("Failed to load %.200s", file);
+	}
+
+	NSLinkModule(obj_file, file, TRUE);
+
+	/* lookup the initial function */
+	/*NSIsSymbolNameDefined require function name without "_" */
+	if( NSIsSymbolNameDefined( buf + 1 ) ) {
+	    rb_loaderror("Failed to lookup Init function %.200s",file);
+	}
+
+	/* NSLookupAndBindSymbol require function name with "_" !! */
+	init_fct = NSAddressOfSymbol( NSLookupAndBindSymbol( buf ) );
+	(*init_fct)();
+
+	return ;
+    }
+#endif /* rld or dyld */
+#endif
+
+#ifdef __BEOS__
+# define DLN_DEFINED
+    {
+      status_t err_stat;  /* BeOS error status code */
+      image_id img_id;    /* extention module unique id */
+      void (*init_fct)(); /* initialize function for extention module */
+
+      /* load extention module */
+      img_id = load_add_on(file);
+      if (img_id <= 0) {
+	rb_loaderror("Failed to load %.200s", file);
+      }
+      
+      /* find symbol for module initialize function. */
+	  /* The Be Book KernelKit Images section described to use
+		 B_SYMBOL_TYPE_TEXT for symbol of function, not
+		 B_SYMBOL_TYPE_CODE. Why ? */
+	  /* strcat(init_fct_symname, "__Fv"); */  /* parameter nothing. */
+	  /* "__Fv" dont need! The Be Book Bug ? */
+      err_stat = get_image_symbol(img_id, buf,
+				  B_SYMBOL_TYPE_TEXT, &init_fct);
+
+      if (err_stat != B_NO_ERROR) {
+	    char real_name[1024];
+	    strcpy(real_name, buf);
+	    strcat(real_name, "__Fv");
+        err_stat = get_image_symbol(img_id, real_name,
+				  B_SYMBOL_TYPE_TEXT, &init_fct);
+      }
+
+      if ((B_BAD_IMAGE_ID == err_stat) || (B_BAD_INDEX == err_stat)) {
+	unload_add_on(img_id);
+	rb_loaderror("Failed to lookup Init function %.200s", file);
+      }
+      else if (B_NO_ERROR != err_stat) {
+	char errmsg[] = "Internal of BeOS version. %.200s (symbol_name = %s)";
+	unload_add_on(img_id);
+	rb_loaderror(errmsg, strerror(err_stat), buf);
+      }
+
+      /* call module initialize function. */
+      (*init_fct)();
+      return;
+    }
+#endif /* __BEOS__*/
+
+#ifdef __MACOS__
+# define DLN_DEFINED
+    {
+      OSErr err;
+      FSSpec libspec;
+      CFragConnectionID connID;
+      Ptr mainAddr;
+      char errMessage[1024];
+      Boolean isfolder, didsomething;
+      Str63 fragname;
+      Ptr symAddr;
+      CFragSymbolClass class;
+      void (*init_fct)();
+      char fullpath[MAXPATHLEN];
+
+      strcpy(fullpath, file);
+
+      /* resolve any aliases to find the real file */
+      c2pstr(fullpath);
+      (void)FSMakeFSSpec(0, 0, fullpath, &libspec);
+      err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
+      if ( err ) {
+	rb_loaderror("Unresolved Alias - %s", file);
+      }
+
+      /* Load the fragment (or return the connID if it is already loaded */
+      fragname[0] = 0;
+      err = GetDiskFragment(&libspec, 0, 0, fragname, 
+			    kLoadCFrag, &connID, &mainAddr,
+			    errMessage);
+      if ( err ) {
+	p2cstr(errMessage);
+	rb_loaderror("%s - %s",errMessage , file);
+      }
+
+      /* Locate the address of the correct init function */
+      c2pstr(buf);
+      err = FindSymbol(connID, buf, &symAddr, &class);
+      if ( err ) {
+	rb_loaderror("Unresolved symbols - %s" , file);
+      }
+	
+      init_fct = (void (*)())symAddr;
+      (*init_fct)();
+      return;
+    }
+#endif /* __MACOS__ */
+
+#ifndef DLN_DEFINED
+    rb_notimplement("dynamic link not supported");
+#endif
+
+#endif /* USE_DLN_A_OUT */
+#endif
+#if !defined(_AIX) && !defined(NeXT)
+  failed:
+    rb_loaderror("%s - %s", dln_strerror(), file);
+#endif
+}
+
+static char *dln_find_1();
+
+char *
+dln_find_exe(fname, path)
+    char *fname;
+    char *path;
+{
+#if defined(__human68k__)
+    if (!path)
+	path = getenv("path");
+    if (!path)
+	path = "/usr/local/bin;/usr/ucb;/usr/bin;/bin;.";
+#else
+    if (!path) path = getenv("PATH");
+    if (!path) path = "/usr/local/bin:/usr/ucb:/usr/bin:/bin:.";
+#endif
+    return dln_find_1(fname, path, 1);
+}
+
+char *
+dln_find_file(fname, path)
+    char *fname;
+    char *path;
+{
+    if (!path) path = ".";
+    return dln_find_1(fname, path, 0);
+}
+
+#if defined(__CYGWIN32__)
+char *
+conv_to_posix_path(win32, posix)
+    char *win32;
+    char *posix;
+{
+    char *first = win32;
+    char *p = win32;
+    char *dst = posix;
+
+    for (p = win32; *p; p++)
+	if (*p == ';') {
+	    *p = 0;
+	    cygwin32_conv_to_posix_path(first, posix);
+	    posix += strlen(posix);
+	    *posix++ = ':';
+	    first = p + 1;
+	    *p = ';';
+	}
+    cygwin32_conv_to_posix_path(first, posix);
+    return dst;
+}
+#endif
+
+static char fbuf[MAXPATHLEN];
+
+static char *
+dln_find_1(fname, path, exe_flag)
+    char *fname;
+    char *path;
+    int exe_flag;		/* non 0 if looking for executable. */
+{
+    register char *dp;
+    register char *ep;
+    register char *bp;
+    struct stat st;
+
+#if defined(__CYGWIN32__)
+    char rubypath[MAXPATHLEN];
+    conv_to_posix_path(path, rubypath);
+    path = rubypath;
+#endif
+#ifndef __MACOS__
+    if (fname[0] == '/') return fname;
+    if (strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0)
+      return fname;
+    if (exe_flag && strchr(fname, '/')) return fname;
+#if defined(MSDOS) || defined(NT) || defined(__human68k__)
+    if (fname[0] == '\\') return fname;
+    if (strlen(fname) > 2 && fname[1] == ':') return fname;
+    if (strncmp(".\\", fname, 2) == 0 || strncmp("..\\", fname, 3) == 0)
+      return fname;
+    if (exe_flag && strchr(fname, '\\')) return fname;
+#endif
+#endif /* __MACOS__ */
+
+    for (dp = path;; dp = ++ep) {
+	register int l;
+	int i;
+	int fspace;
+
+	/* extract a component */
+#if !defined(MSDOS)  && !defined(NT) && !defined(__human68k__) && !defined(__MACOS__)
+	ep = strchr(dp, ':');
+#else
+	ep = strchr(dp, ';');
+#endif
+	if (ep == NULL)
+	    ep = dp+strlen(dp);
+
+	/* find the length of that component */
+	l = ep - dp;
+	bp = fbuf;
+	fspace = sizeof fbuf - 2;
+	if (l > 0) {
+	    /*
+	    **	If the length of the component is zero length,
+	    **	start from the current directory.  If the
+	    **	component begins with "~", start from the
+	    **	user's $HOME environment variable.  Otherwise
+	    **	take the path literally.
+	    */
+
+	    if (*dp == '~' && (l == 1 ||
+#if defined(MSDOS) || defined(NT) || defined(__human68k__)
+			       dp[1] == '\\' || 
+#endif
+			       dp[1] == '/')) {
+		char *home;
+
+		home = getenv("HOME");
+		if (home != NULL) {
+		    i = strlen(home);
+		    if ((fspace -= i) < 0)
+			goto toolong;
+		    memcpy(bp, home, i);
+		    bp += i;
+		}
+		dp++;
+		l--;
+	    }
+	    if (l > 0) {
+		if ((fspace -= l) < 0)
+		    goto toolong;
+		memcpy(bp, dp, l);
+		bp += l;
+	    }
+
+	    /* add a "/" between directory and filename */
+	    if (ep[-1] != '/')
+#ifdef __MACOS__
+		*bp++ = ':';
+#else
+		*bp++ = '/';
+#endif
+	}
+
+	/* now append the file name */
+	i = strlen(fname);
+	if ((fspace -= i) < 0) {
+	  toolong:
+	    fprintf(stderr, "openpath: pathname too long (ignored)\n");
+	    *bp = '\0';
+	    fprintf(stderr, "\tDirectory \"%s\"\n", fbuf);
+	    fprintf(stderr, "\tFile \"%s\"\n", fname);
+	    continue;
+	}
+	memcpy(bp, fname, i + 1);
+
+	if (stat(fbuf, &st) == 0) {
+	    if (exe_flag == 0) return fbuf;
+	    /* looking for executable */
+	    if (eaccess(fbuf, X_OK) == 0) return fbuf;
+	}
+#if defined(MSDOS) || defined(NT) || defined(__human68k__)
+	if (exe_flag) {
+	    static const char *extension[] = {
+#if defined(MSDOS)
+		".com", ".exe", ".bat",
+#if defined(DJGPP)
+		".btm", ".sh", ".ksh", ".pl", ".sed",
+#endif
+#else
+		".r", ".R", ".x", ".X", ".bat", ".BAT",
+#endif
+		(char *) NULL
+	    };
+	    int j;
+
+	    for (j = 0; extension[j]; j++) {
+		if (fspace < (int)(strlen(extension[j]))) {
+		    fprintf(stderr, "openpath: pathname too long (ignored)\n");
+		    fprintf(stderr, "\tDirectory \"%.*s\"\n", (int) (bp - fbuf), fbuf);
+		    fprintf(stderr, "\tFile \"%s%s\"\n", fname, extension[j]);
+		    continue;
+		}
+		strcpy(bp + i, extension[j]);
+		if (stat(fbuf, &st) == 0)
+		    return fbuf;
+	    }
+	}
+#endif /* MSDOS or NT or __human68k__ */
+	/* if not, and no other alternatives, life is bleak */
+	if (*ep == '\0') {
+	    return NULL;
+	}
+
+	/* otherwise try the next component in the search path */
+    }
+}
diff -iNu ruby-1.3_org/eval.c ruby-1.3/eval.c
--- ruby-1.3_org/eval.c	Thu Dec 24 18:28:47 1998
+++ ruby-1.3/eval.c	Mon Jan 11 22:20:40 1999
@@ -297,7 +297,7 @@
 	rb_raise(rb_eNameError, "undefined method `%s' for `%s'",
 		 rb_id2name(name), rb_class2name(klass));
     }
-    if (body->nd_noex != noex) {
+    if (body->nd_noex != (UINT)noex) {
 	if (klass == origin) {
 	    body->nd_noex = noex;
 	}
@@ -332,7 +332,7 @@
 {
     char *name;
     char *buf;
-    ID attr, attriv;
+    ID attriv;
     int noex;
 
     if (!ex) noex = NOEX_PUBLIC;
@@ -1867,7 +1867,7 @@
 		    POP_ITER();
 		}
 	    }
-	    else if (_block.tag->dst == state) {
+	    else if (_block.tag->dst == (UINT)state) {
 		state &= TAG_MASK;
 		if (state == TAG_RETURN) {
 		    result = prot_tag->retval;
@@ -2887,6 +2887,7 @@
     }
     rb_exit(status);
     /* not reached */
+	return Qnil;
 }
 
 static void
@@ -2904,6 +2905,7 @@
 {
     rb_secure(4);
     rb_abort();
+	return Qnil;
 }
 
 void
@@ -3013,6 +3015,7 @@
     *ruby_frame = *_frame.prev->prev;
     rb_longjmp(TAG_RAISE, mesg);
     POP_FRAME();
+	return Qnil;
 }
 
 int
@@ -3242,7 +3245,7 @@
     if (state == 0) {
 	retval = (*it_proc)(data1);
     }
-    if (ruby_block->tag->dst == state) {
+    if (ruby_block->tag->dst == (UINT)state) {
 	state &= TAG_MASK;
 	if (state == TAG_RETURN) {
 	    retval = prot_tag->retval;
@@ -3565,6 +3568,7 @@
 	rb_raise(rb_eArgError, "too many arguments(%d)", len);
 	break;
     }
+	return Qnil;
 }
 
 static VALUE
@@ -5309,7 +5313,7 @@
     POP_TAG();
 
     POP_ITER();
-    if (ruby_block->tag->dst == state) {
+    if (ruby_block->tag->dst == (UINT)state) {
 	state &= TAG_MASK;
     }
     ruby_block = old_block;
@@ -5375,7 +5379,7 @@
     }
     POP_TAG();
     POP_ITER();
-    if (ruby_block->tag->dst == state) {
+    if (ruby_block->tag->dst == (UINT)state) {
 	state &= TAG_MASK;
 	orphan = 2;
     }
@@ -6023,7 +6027,7 @@
 		else {
 		    delay -= now;
 		    delay_tv.tv_sec = (unsigned int)delay;
-		    delay_tv.tv_usec = (delay - (double)delay_tv.tv_sec) * 1e6;
+		    delay_tv.tv_usec = (long)((delay - (double)delay_tv.tv_sec) * 1e6);
 		    delay_ptr = &delay_tv;
 		}
 
@@ -6039,7 +6043,7 @@
 			if ((th->wait_for&WAIT_FD)
 			    && FD_ISSET(th->fd, &readfds)) {
 			    /* Wake up only one thread per fd. */
-			    FD_CLR(th->fd, &readfds);
+			    FD_CLR((UINT)th->fd, &readfds);
 			    th->status = THREAD_RUNNABLE;
 			    th->fd = 0;
 			    th->wait_for &= ~WAIT_FD;
@@ -6142,7 +6146,7 @@
 	    time.tv_sec = (int)d;
 	    time.tv_usec = (int)((d - (int)d)*1e6);
 	    if (time.tv_usec < 0) {
-		time.tv_usec += 1e6;
+		time.tv_usec += (long)1e6;
 		time.tv_sec -= 1;
 	    }
 	    if (time.tv_sec < 0) return;
@@ -6208,7 +6212,7 @@
 		    double d = timeofday() - limit;
 
 		    tv.tv_sec = (unsigned int)d;
-		    tv.tv_usec = (d - (double)tv.tv_sec) * 1e6;
+		    tv.tv_usec = (long)((d - (double)tv.tv_sec) * 1e6);
 		}
 		continue;
 	    }
@@ -6385,7 +6389,7 @@
 {
     if (curr_thread == curr_thread->next) {
 	TRAP_BEG;
-	sleep((32767L<<16)+32767);
+	sleep((32767L<<16)|32767);
 	TRAP_END;
 	return;
     }
diff -iNu ruby-1.3_org/file.c ruby-1.3/file.c
--- ruby-1.3_org/file.c	Wed Nov 25 12:31:13 1998
+++ ruby-1.3/file.c	Mon Jan 11 21:52:30 1999
@@ -9,6 +9,10 @@
   Copyright (C) 1993-1998 Yukihiro Matsumoto
 
 ************************************************/
+
+#ifdef NT
+#include "missing/file.h"
+#endif
 
 #include "ruby.h"
 #include "rubyio.h"
@@ -287,7 +291,8 @@
     return stat_new(&st);
 #else
     rb_notimplement();
-#endif
+#endif
+	return Qnil;
 }
 
 static VALUE
@@ -307,6 +312,7 @@
 #else
     rb_notimplement();
 #endif
+	return Qnil;
 }
 
 static int
@@ -1047,6 +1053,7 @@
 #else
     rb_notimplement();
 #endif
+	return Qnil;
 }
 
 static VALUE
@@ -1066,6 +1073,7 @@
 #else
     rb_notimplement();
 #endif
+	return Qnil;
 }
 
 static void
diff -iNu ruby-1.3_org/gc.c ruby-1.3/gc.c
--- ruby-1.3_org/gc.c	Thu Dec 24 14:00:20 1998
+++ ruby-1.3/gc.c	Fri Jan 15 21:12:20 1999
@@ -393,7 +393,8 @@
     obj->as.basic.flags |= FL_MARK;
 
     if (FL_TEST(obj, FL_EXIVAR)) {
-	return rb_mark_generic_ivar((VALUE)obj);
+	rb_mark_generic_ivar((VALUE)obj);
+	return ;
     }
 
     switch (obj->as.basic.flags & T_MASK) {
diff -iNu ruby-1.3_org/glob.c ruby-1.3/glob.c
--- ruby-1.3_org/glob.c	Thu Sep 03 16:43:34 1998
+++ ruby-1.3/glob.c	Fri Jan 15 21:47:02 1999
@@ -1,591 +1,592 @@
-/* File-name wildcard pattern matching for GNU.
-   Copyright (C) 1985, 1988, 1989 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 1, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-/* To whomever it may concern: I have never seen the code which most
-   Unix programs use to perform this function.  I wrote this from scratch
-   based on specifications for the pattern matching.  --RMS.  */
-
-#include "config.h"
-
-#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
-  #pragma alloca
-#endif /* _AIX && RISC6000 && !__GNUC__ */
-
-#if defined (HAVE_ALLOCA_H)
-#  include <alloca.h>
-#endif
-
-#if defined (HAVE_UNISTD_H)
-#  include <unistd.h>
-#endif
-
-#if defined (HAVE_STDLIB_H)
-#  include <stdlib.h>
-#else
-#  if defined (SHELL)
-#    include "ansi_stdlib.h"
-#  endif /* SHELL */
-#endif
-
-#include <sys/types.h>
-
-#if defined (HAVE_DIRENT_H)
-#  include <dirent.h>
-#  define D_NAMLEN(d) strlen ((d)->d_name)
-#elif HAVE_DIRECT_H
-#  include <direct.h>
-#  define D_NAMLEN(d) strlen ((d)->d_name)
-#else /* !HAVE_DIRENT_H */
-#  define D_NAMLEN(d) ((d)->d_namlen)
-#  if defined (HAVE_SYS_NDIR_H)
-#    include <sys/ndir.h>
-#  endif
-#  if defined (HAVE_SYS_DIR_H)
-#    include <sys/dir.h>
-#  endif /* HAVE_SYS_DIR_H */
-#  if defined (HAVE_NDIR_H)
-#    include <ndir.h>
-#  endif
-#  if !defined (dirent)
-#    define dirent direct
-#  endif
-#endif /* !HAVE_DIRENT_H */
-
-#if defined (_POSIX_SOURCE) || defined(DJGPP) || defined(USE_CWGUSI)
-/* Posix does not require that the d_ino field be present, and some
-   systems do not provide it. */
-#  define REAL_DIR_ENTRY(dp) 1
-#elif defined (__BORLANDC__)
-#  define REAL_DIR_ENTRY(dp) 1
-#else
-#  define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
-#endif /* _POSIX_SOURCE */
-
-#if defined (HAVE_STRING_H)
-#  include <string.h>
-#else /* !HAVE_STRING_H */
-#  include <strings.h>
-#endif /* !HAVE_STRING_H */
-
-#if !defined (HAVE_BCOPY) && !defined (bcopy)
-#  define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
-#endif /* !HAVE_BCOPY */
-
-/* If the opendir () on your system lets you open non-directory files,
-   then we consider that not robust. */
-#if defined (OPENDIR_NOT_ROBUST)
-#  if defined (SHELL)
-#    include "posixstat.h"
-#  else /* !SHELL */
-#    include <sys/stat.h>
-#  endif /* !SHELL */
-#endif /* OPENDIR_NOT_ROBUST */
-
-#include "fnmatch.h"
-
-extern void *xmalloc (), *xrealloc ();
-#if !defined (HAVE_STDLIB_H)
-extern void free ();
-#endif /* !HAVE_STDLIB_H */
-
-#if !defined (NULL)
-#  if defined (__STDC__)
-#    define NULL ((void *) 0)
-#  else
-#    define NULL 0x0
-#  endif /* __STDC__ */
-#endif /* !NULL */
-
-#if defined (SHELL)
-extern void throw_to_top_level ();
-
-extern int interrupt_state;
-#endif /* SHELL */
-
-#if defined(NT) && defined(_MSC_VER)
-#include "missing/dir.h"
-#endif
-
-/* Global variable which controls whether or not * matches .*.
-   Non-zero means don't match .*.  */
-int noglob_dot_filenames = 1;
-
-/* Global variable to return to signify an error in globbing. */
-char *glob_error_return;
-
-/* Return nonzero if PATTERN has any special globbing chars in it.  */
-int
-glob_pattern_p (pattern)
-     char *pattern;
-{
-  register char *p = pattern;
-  register char c;
-  int open = 0;
-
-  while ((c = *p++) != '\0')
-    switch (c)
-      {
-      case '?':
-      case '*':
-	return (1);
-
-      case '[':		/* Only accept an open brace if there is a close */
-	open++;		/* brace to match it.  Bracket expressions must be */
-	continue;	/* complete, according to Posix.2 */
-      case ']':
-	if (open)
-	  return (1);
-	continue;      
-
-      case '\\':
-	if (*p++ == '\0')
-	  return (0);
-      }
-
-  return (0);
-}
-
-/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
-static void
-dequote_pathname (pathname)
-     char *pathname;
-{
-  register int i, j;
-
-  for (i = j = 0; pathname && pathname[i]; )
-    {
-      if (pathname[i] == '\\')
-	i++;
-
-      pathname[j++] = pathname[i++];
-
-      if (!pathname[i - 1])
-	break;
-    }
-  pathname[j] = '\0';
-}
-
-
-/* Return a vector of names of files in directory DIR
-   whose names match glob pattern PAT.
-   The names are not in any particular order.
-   Wildcards at the beginning of PAT do not match an initial period.
-
-   The vector is terminated by an element that is a null pointer.
-
-   To free the space allocated, first free the vector's elements,
-   then free the vector.
-
-   Return 0 if cannot get enough memory to hold the pointer
-   and the names.
-
-   Return -1 if cannot access directory DIR.
-   Look in errno for more information.  */
-
-char **
-glob_vector (pat, dir)
-     char *pat;
-     char *dir;
-{
-  struct globval
-    {
-      struct globval *next;
-      char *name;
-    };
-
-  DIR *d;
-  register struct dirent *dp;
-  struct globval *lastlink;
-  register struct globval *nextlink;
-  register char *nextname;
-  unsigned int count;
-  int lose, skip;
-  register char **name_vector;
-  register unsigned int i;
-#if defined (OPENDIR_NOT_ROBUST)
-  struct stat finfo;
-
-  if (stat (dir, &finfo) < 0)
-    return ((char **) &glob_error_return);
-
-  if (!S_ISDIR (finfo.st_mode))
-    return ((char **) &glob_error_return);
-#endif /* OPENDIR_NOT_ROBUST */
-
-  d = opendir (dir);
-  if (d == NULL)
-    return ((char **) &glob_error_return);
-
-  lastlink = 0;
-  count = 0;
-  lose = 0;
-  skip = 0;
-
-  /* If PAT is empty, skip the loop, but return one (empty) filename. */
-  if (!pat || !*pat)
-    {
-      nextlink = (struct globval *)alloca (sizeof (struct globval));
-      nextlink->next = lastlink;
-      nextname = (char *) xmalloc (1);
-      if (!nextname)
-	lose = 1;
-      else
-	{
-	  lastlink = nextlink;
-	  nextlink->name = nextname;
-	  nextname[0] = '\0';
-	  count++;
-	}
-      skip = 1;
-    }
-
-  /* Scan the directory, finding all names that match.
-     For each name that matches, allocate a struct globval
-     on the stack and store the name in it.
-     Chain those structs together; lastlink is the front of the chain.  */
-  while (!skip)
-    {
-      int flags;		/* Flags passed to fnmatch (). */
-#if defined (SHELL)
-      /* Make globbing interruptible in the bash shell. */
-      if (interrupt_state)
-	{
-	  closedir (d);
-	  lose = 1;
-	  goto lost;
-	}
-#endif /* SHELL */
-	  
-      dp = readdir (d);
-      if (dp == NULL)
-	break;
-
-      /* If this directory entry is not to be used, try again. */
-      if (!REAL_DIR_ENTRY (dp))
-	continue;
-
-      /* If a dot must be explicity matched, check to see if they do. */
-      if (noglob_dot_filenames && dp->d_name[0] == '.' && pat[0] != '.' &&
-	    (pat[0] != '\\' || pat[1] != '.'))
-	continue;
-
-      flags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
-
-      if (fnmatch (pat, dp->d_name, flags) != FNM_NOMATCH)
-	{
-	  nextlink = (struct globval *) alloca (sizeof (struct globval));
-	  nextlink->next = lastlink;
-	  nextname = (char *) xmalloc (D_NAMLEN (dp) + 1);
-	  if (nextname == NULL)
-	    {
-	      lose = 1;
-	      break;
-	    }
-	  lastlink = nextlink;
-	  nextlink->name = nextname;
-	  bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
-	  ++count;
-	}
-    }
-  (void) closedir (d);
-
-  if (!lose)
-    {
-      name_vector = (char **) xmalloc ((count + 1) * sizeof (char *));
-      lose |= name_vector == NULL;
-    }
-
-  /* Have we run out of memory?	 */
-#if defined (SHELL)
- lost:
-#endif
-  if (lose)
-    {
-      /* Here free the strings we have got.  */
-      while (lastlink)
-	{
-	  free (lastlink->name);
-	  lastlink = lastlink->next;
-	}
-#if defined (SHELL)
-      if (interrupt_state)
-	throw_to_top_level ();
-#endif /* SHELL */
-      return (NULL);
-    }
-
-  /* Copy the name pointers from the linked list into the vector.  */
-  for (i = 0; i < count; ++i)
-    {
-      name_vector[i] = lastlink->name;
-      lastlink = lastlink->next;
-    }
-
-  name_vector[count] = NULL;
-  return (name_vector);
-}
-
-/* Return a new array which is the concatenation of each string in ARRAY
-   to DIR.  This function expects you to pass in an allocated ARRAY, and
-   it takes care of free()ing that array.  Thus, you might think of this
-   function as side-effecting ARRAY. */
-static char **
-glob_dir_to_array (dir, array)
-     char *dir, **array;
-{
-  register unsigned int i, l;
-  int add_slash;
-  char **result;
-
-  l = strlen (dir);
-  if (l == 0)
-    return (array);
-
-  add_slash = dir[l - 1] != '/';
-
-  i = 0;
-  while (array[i] != NULL)
-    ++i;
-
-  result = (char **) xmalloc ((i + 1) * sizeof (char *));
-  if (result == NULL)
-    return (NULL);
-
-  for (i = 0; array[i] != NULL; i++)
-    {
-      result[i] = (char *) xmalloc (l + (add_slash ? 1 : 0)
-				   + strlen (array[i]) + 1);
-      if (result[i] == NULL)
-	return (NULL);
-#if 1
-      strcpy (result[i], dir);
-      if (add_slash)
-        result[i][l] = '/';
-      strcpy (result[i] + l + add_slash, array[i]);
-#else
-      (void)sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]);
-#endif
-    }
-  result[i] = NULL;
-
-  /* Free the input array.  */
-  for (i = 0; array[i] != NULL; i++)
-    free (array[i]);
-  free ((char *) array);
-
-  return (result);
-}
-
-/* Do globbing on PATHNAME.  Return an array of pathnames that match,
-   marking the end of the array with a null-pointer as an element.
-   If no pathnames match, then the array is empty (first element is null).
-   If there isn't enough memory, then return NULL.
-   If a file system error occurs, return -1; `errno' has the error code.  */
-char **
-glob_filename (pathname)
-     char *pathname;
-{
-#ifndef strrchr
-  char *strrchr();
-#endif
-
-  char **result;
-  unsigned int result_size;
-  char *directory_name, *filename;
-  unsigned int directory_len;
-
-  result = (char **) xmalloc (sizeof (char *));
-  result_size = 1;
-  if (result == NULL)
-    return (NULL);
-
-  result[0] = NULL;
-
-  /* Find the filename.  */
-  filename = strrchr (pathname, '/');
-  if (filename == NULL)
-    {
-      filename = pathname;
-      directory_name = "";
-      directory_len = 0;
-    }
-  else
-    {
-      directory_len = (filename - pathname) + 1;
-      directory_name = (char *) alloca (directory_len + 1);
-
-      bcopy (pathname, directory_name, directory_len);
-      directory_name[directory_len] = '\0';
-      ++filename;
-    }
-
-  /* If directory_name contains globbing characters, then we
-     have to expand the previous levels.  Just recurse. */
-  if (glob_pattern_p (directory_name))
-    {
-      char **directories;
-      register unsigned int i;
-
-      if (directory_name[directory_len - 1] == '/')
-	directory_name[directory_len - 1] = '\0';
-
-      directories = glob_filename (directory_name);
-
-      if (directories == NULL)
-	goto memory_error;
-      else if (directories == (char **)&glob_error_return)
-	{
-	  free ((char *) result);
-	  return ((char **) &glob_error_return);
-	}
-      else if (*directories == NULL)
-	{
-	  free ((char *) directories);
-	  free ((char *) result);
-	  return ((char **) &glob_error_return);
-	}
-
-      /* We have successfully globbed the preceding directory name.
-	 For each name in DIRECTORIES, call glob_vector on it and
-	 FILENAME.  Concatenate the results together.  */
-      for (i = 0; directories[i] != NULL; ++i)
-	{
-	  char **temp_results;
-
-	  /* Scan directory even on a NULL pathname.  That way, `*h/'
-	     returns only directories ending in `h', instead of all
-	     files ending in `h' with a `/' appended. */
-	  temp_results = glob_vector (filename, directories[i]);
-
-	  /* Handle error cases. */
-	  if (temp_results == NULL)
-	    goto memory_error;
-	  else if (temp_results == (char **)&glob_error_return)
-	    /* This filename is probably not a directory.  Ignore it.  */
-	    ;
-	  else
-	    {
-	      char **array;
-	      register unsigned int l;
-
-	      array = glob_dir_to_array (directories[i], temp_results);
-	      l = 0;
-	      while (array[l] != NULL)
-		++l;
-
-	      result =
-		(char **)xrealloc(result, (result_size + l) * sizeof (char *));
-
-	      if (result == NULL)
-		goto memory_error;
-
-	      for (l = 0; array[l] != NULL; ++l)
-		result[result_size++ - 1] = array[l];
-
-	      result[result_size - 1] = NULL;
-
-	      /* Note that the elements of ARRAY are not freed.  */
-	      free ((char *) array);
-	    }
-	}
-      /* Free the directories.  */
-      for (i = 0; directories[i]; i++)
-	free (directories[i]);
-
-      free ((char *) directories);
-
-      return (result);
-    }
-
-  /* If there is only a directory name, return it. */
-  if (*filename == '\0')
-    {
-      result = (char **) xrealloc ((char *) result, 2 * sizeof (char *));
-      if (result == NULL)
-	return (NULL);
-      result[0] = (char *) xmalloc (directory_len + 1);
-      if (result[0] == NULL)
-	goto memory_error;
-      bcopy (directory_name, result[0], directory_len + 1);
-      result[1] = NULL;
-      return (result);
-    }
-  else
-    {
-      char **temp_results;
-
-      /* There are no unquoted globbing characters in DIRECTORY_NAME.
-	 Dequote it before we try to open the directory since there may
-	 be quoted globbing characters which should be treated verbatim. */
-      if (directory_len > 0)
-	dequote_pathname (directory_name);
-
-      /* We allocated a small array called RESULT, which we won't be using.
-	 Free that memory now. */
-      free (result);
-
-      /* Just return what glob_vector () returns appended to the
-	 directory name. */
-      temp_results =
-	glob_vector (filename, (directory_len == 0 ? "." : directory_name));
-
-      if (temp_results == NULL || temp_results == (char **)&glob_error_return)
-	return (temp_results);
-
-      return (glob_dir_to_array (directory_name, temp_results));
-    }
-
-  /* We get to memory_error if the program has run out of memory, or
-     if this is the shell, and we have been interrupted. */
- memory_error:
-  if (result != NULL)
-    {
-      register unsigned int i;
-      for (i = 0; result[i] != NULL; ++i)
-	free (result[i]);
-      free ((char *) result);
-    }
-#if defined (SHELL)
-  if (interrupt_state)
-    throw_to_top_level ();
-#endif /* SHELL */
-  return (NULL);
-}
-
-#if defined (TEST)
-
-main (argc, argv)
-     int argc;
-     char **argv;
-{
-  unsigned int i;
-
-  for (i = 1; i < argc; ++i)
-    {
-      char **value = glob_filename (argv[i]);
-      if (value == NULL)
-	puts ("Out of memory.");
-      else if (value == &glob_error_return)
-	perror (argv[i]);
-      else
-	for (i = 0; value[i] != NULL; i++)
-	  puts (value[i]);
-    }
-
-  exit (0);
-}
-#endif	/* TEST.  */
+/* File-name wildcard pattern matching for GNU.
+   Copyright (C) 1985, 1988, 1989 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* To whomever it may concern: I have never seen the code which most
+   Unix programs use to perform this function.  I wrote this from scratch
+   based on specifications for the pattern matching.  --RMS.  */
+
+/*#include "config.h"*/
+#include "ruby.h"
+
+#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
+  #pragma alloca
+#endif /* _AIX && RISC6000 && !__GNUC__ */
+
+#if defined (HAVE_ALLOCA_H)
+#  include <alloca.h>
+#endif
+
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif
+
+#if defined (HAVE_STDLIB_H)
+#  include <stdlib.h>
+#else
+#  if defined (SHELL)
+#    include "ansi_stdlib.h"
+#  endif /* SHELL */
+#endif
+
+#include <sys/types.h>
+
+#if defined (HAVE_DIRENT_H)
+#  include <dirent.h>
+#  define D_NAMLEN(d) strlen ((d)->d_name)
+#elif HAVE_DIRECT_H
+#  include <direct.h>
+#  define D_NAMLEN(d) strlen ((d)->d_name)
+#else /* !HAVE_DIRENT_H */
+#  define D_NAMLEN(d) ((d)->d_namlen)
+#  if defined (HAVE_SYS_NDIR_H)
+#    include <sys/ndir.h>
+#  endif
+#  if defined (HAVE_SYS_DIR_H)
+#    include <sys/dir.h>
+#  endif /* HAVE_SYS_DIR_H */
+#  if defined (HAVE_NDIR_H)
+#    include <ndir.h>
+#  endif
+#  if !defined (dirent)
+#    define dirent direct
+#  endif
+#endif /* !HAVE_DIRENT_H */
+
+#if defined (_POSIX_SOURCE) || defined(DJGPP) || defined(USE_CWGUSI)
+/* Posix does not require that the d_ino field be present, and some
+   systems do not provide it. */
+#  define REAL_DIR_ENTRY(dp) 1
+#elif defined (__BORLANDC__)
+#  define REAL_DIR_ENTRY(dp) 1
+#else
+#  define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
+#endif /* _POSIX_SOURCE */
+
+#if defined (HAVE_STRING_H)
+#  include <string.h>
+#else /* !HAVE_STRING_H */
+#  include <strings.h>
+#endif /* !HAVE_STRING_H */
+
+#if !defined (HAVE_BCOPY) && !defined (bcopy)
+#  define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
+#endif /* !HAVE_BCOPY */
+
+/* If the opendir () on your system lets you open non-directory files,
+   then we consider that not robust. */
+#if defined (OPENDIR_NOT_ROBUST)
+#  if defined (SHELL)
+#    include "posixstat.h"
+#  else /* !SHELL */
+#    include <sys/stat.h>
+#  endif /* !SHELL */
+#endif /* OPENDIR_NOT_ROBUST */
+
+#include "fnmatch.h"
+
+extern void *xmalloc (), *xrealloc ();
+#if !defined (HAVE_STDLIB_H)
+extern void free ();
+#endif /* !HAVE_STDLIB_H */
+
+#if !defined (NULL)
+#  if defined (__STDC__)
+#    define NULL ((void *) 0)
+#  else
+#    define NULL 0x0
+#  endif /* __STDC__ */
+#endif /* !NULL */
+
+#if defined (SHELL)
+extern void throw_to_top_level ();
+
+extern int interrupt_state;
+#endif /* SHELL */
+
+#if defined(NT) && defined(_MSC_VER)
+#include "missing/dir.h"
+#endif
+
+/* Global variable which controls whether or not * matches .*.
+   Non-zero means don't match .*.  */
+int noglob_dot_filenames = 1;
+
+/* Global variable to return to signify an error in globbing. */
+char *glob_error_return;
+
+/* Return nonzero if PATTERN has any special globbing chars in it.  */
+int
+glob_pattern_p (pattern)
+     char *pattern;
+{
+  register char *p = pattern;
+  register char c;
+  int open = 0;
+
+  while ((c = *p++) != '\0')
+    switch (c)
+      {
+      case '?':
+      case '*':
+	return (1);
+
+      case '[':		/* Only accept an open brace if there is a close */
+	open++;		/* brace to match it.  Bracket expressions must be */
+	continue;	/* complete, according to Posix.2 */
+      case ']':
+	if (open)
+	  return (1);
+	continue;      
+
+      case '\\':
+	if (*p++ == '\0')
+	  return (0);
+      }
+
+  return (0);
+}
+
+/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
+static void
+dequote_pathname (pathname)
+     char *pathname;
+{
+  register int i, j;
+
+  for (i = j = 0; pathname && pathname[i]; )
+    {
+      if (pathname[i] == '\\')
+	i++;
+
+      pathname[j++] = pathname[i++];
+
+      if (!pathname[i - 1])
+	break;
+    }
+  pathname[j] = '\0';
+}
+
+
+/* Return a vector of names of files in directory DIR
+   whose names match glob pattern PAT.
+   The names are not in any particular order.
+   Wildcards at the beginning of PAT do not match an initial period.
+
+   The vector is terminated by an element that is a null pointer.
+
+   To free the space allocated, first free the vector's elements,
+   then free the vector.
+
+   Return 0 if cannot get enough memory to hold the pointer
+   and the names.
+
+   Return -1 if cannot access directory DIR.
+   Look in errno for more information.  */
+
+char **
+glob_vector (pat, dir)
+     char *pat;
+     char *dir;
+{
+  struct globval
+    {
+      struct globval *next;
+      char *name;
+    };
+
+  DIR *d;
+  register struct dirent *dp;
+  struct globval *lastlink;
+  register struct globval *nextlink;
+  register char *nextname;
+  unsigned int count;
+  int lose, skip;
+  register char **name_vector;
+  register unsigned int i;
+#if defined (OPENDIR_NOT_ROBUST)
+  struct stat finfo;
+
+  if (stat (dir, &finfo) < 0)
+    return ((char **) &glob_error_return);
+
+  if (!S_ISDIR (finfo.st_mode))
+    return ((char **) &glob_error_return);
+#endif /* OPENDIR_NOT_ROBUST */
+
+  d = opendir (dir);
+  if (d == NULL)
+    return ((char **) &glob_error_return);
+
+  lastlink = 0;
+  count = 0;
+  lose = 0;
+  skip = 0;
+
+  /* If PAT is empty, skip the loop, but return one (empty) filename. */
+  if (!pat || !*pat)
+    {
+      nextlink = (struct globval *)alloca (sizeof (struct globval));
+      nextlink->next = lastlink;
+      nextname = (char *) xmalloc (1);
+      if (!nextname)
+	lose = 1;
+      else
+	{
+	  lastlink = nextlink;
+	  nextlink->name = nextname;
+	  nextname[0] = '\0';
+	  count++;
+	}
+      skip = 1;
+    }
+
+  /* Scan the directory, finding all names that match.
+     For each name that matches, allocate a struct globval
+     on the stack and store the name in it.
+     Chain those structs together; lastlink is the front of the chain.  */
+  while (!skip)
+    {
+      int flags;		/* Flags passed to fnmatch (). */
+#if defined (SHELL)
+      /* Make globbing interruptible in the bash shell. */
+      if (interrupt_state)
+	{
+	  closedir (d);
+	  lose = 1;
+	  goto lost;
+	}
+#endif /* SHELL */
+	  
+      dp = readdir (d);
+      if (dp == NULL)
+	break;
+
+      /* If this directory entry is not to be used, try again. */
+      if (!REAL_DIR_ENTRY (dp))
+	continue;
+
+      /* If a dot must be explicity matched, check to see if they do. */
+      if (noglob_dot_filenames && dp->d_name[0] == '.' && pat[0] != '.' &&
+	    (pat[0] != '\\' || pat[1] != '.'))
+	continue;
+
+      flags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
+
+      if (fnmatch (pat, dp->d_name, flags) != FNM_NOMATCH)
+	{
+	  nextlink = (struct globval *) alloca (sizeof (struct globval));
+	  nextlink->next = lastlink;
+	  nextname = (char *) xmalloc (D_NAMLEN (dp) + 1);
+	  if (nextname == NULL)
+	    {
+	      lose = 1;
+	      break;
+	    }
+	  lastlink = nextlink;
+	  nextlink->name = nextname;
+	  bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
+	  ++count;
+	}
+    }
+  (void) closedir (d);
+
+  if (!lose)
+    {
+      name_vector = (char **) xmalloc ((count + 1) * sizeof (char *));
+      lose |= name_vector == NULL;
+    }
+
+  /* Have we run out of memory?	 */
+#if defined (SHELL)
+ lost:
+#endif
+  if (lose)
+    {
+      /* Here free the strings we have got.  */
+      while (lastlink)
+	{
+	  free (lastlink->name);
+	  lastlink = lastlink->next;
+	}
+#if defined (SHELL)
+      if (interrupt_state)
+	throw_to_top_level ();
+#endif /* SHELL */
+      return (NULL);
+    }
+
+  /* Copy the name pointers from the linked list into the vector.  */
+  for (i = 0; i < count; ++i)
+    {
+      name_vector[i] = lastlink->name;
+      lastlink = lastlink->next;
+    }
+
+  name_vector[count] = NULL;
+  return (name_vector);
+}
+
+/* Return a new array which is the concatenation of each string in ARRAY
+   to DIR.  This function expects you to pass in an allocated ARRAY, and
+   it takes care of free()ing that array.  Thus, you might think of this
+   function as side-effecting ARRAY. */
+static char **
+glob_dir_to_array (dir, array)
+     char *dir, **array;
+{
+  register unsigned int i, l;
+  int add_slash;
+  char **result;
+
+  l = strlen (dir);
+  if (l == 0)
+    return (array);
+
+  add_slash = dir[l - 1] != '/';
+
+  i = 0;
+  while (array[i] != NULL)
+    ++i;
+
+  result = (char **) xmalloc ((i + 1) * sizeof (char *));
+  if (result == NULL)
+    return (NULL);
+
+  for (i = 0; array[i] != NULL; i++)
+    {
+      result[i] = (char *) xmalloc (l + (add_slash ? 1 : 0)
+				   + strlen (array[i]) + 1);
+      if (result[i] == NULL)
+	return (NULL);
+#if 1
+      strcpy (result[i], dir);
+      if (add_slash)
+        result[i][l] = '/';
+      strcpy (result[i] + l + add_slash, array[i]);
+#else
+      (void)sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]);
+#endif
+    }
+  result[i] = NULL;
+
+  /* Free the input array.  */
+  for (i = 0; array[i] != NULL; i++)
+    free (array[i]);
+  free ((char *) array);
+
+  return (result);
+}
+
+/* Do globbing on PATHNAME.  Return an array of pathnames that match,
+   marking the end of the array with a null-pointer as an element.
+   If no pathnames match, then the array is empty (first element is null).
+   If there isn't enough memory, then return NULL.
+   If a file system error occurs, return -1; `errno' has the error code.  */
+char **
+glob_filename (pathname)
+     char *pathname;
+{
+#ifndef strrchr
+  char *strrchr();
+#endif
+
+  char **result;
+  unsigned int result_size;
+  char *directory_name, *filename;
+  unsigned int directory_len;
+
+  result = (char **) xmalloc (sizeof (char *));
+  result_size = 1;
+  if (result == NULL)
+    return (NULL);
+
+  result[0] = NULL;
+
+  /* Find the filename.  */
+  filename = strrchr (pathname, '/');
+  if (filename == NULL)
+    {
+      filename = pathname;
+      directory_name = "";
+      directory_len = 0;
+    }
+  else
+    {
+      directory_len = (filename - pathname) + 1;
+      directory_name = (char *) alloca (directory_len + 1);
+
+      bcopy (pathname, directory_name, directory_len);
+      directory_name[directory_len] = '\0';
+      ++filename;
+    }
+
+  /* If directory_name contains globbing characters, then we
+     have to expand the previous levels.  Just recurse. */
+  if (glob_pattern_p (directory_name))
+    {
+      char **directories;
+      register unsigned int i;
+
+      if (directory_name[directory_len - 1] == '/')
+	directory_name[directory_len - 1] = '\0';
+
+      directories = glob_filename (directory_name);
+
+      if (directories == NULL)
+	goto memory_error;
+      else if (directories == (char **)&glob_error_return)
+	{
+	  free ((char *) result);
+	  return ((char **) &glob_error_return);
+	}
+      else if (*directories == NULL)
+	{
+	  free ((char *) directories);
+	  free ((char *) result);
+	  return ((char **) &glob_error_return);
+	}
+
+      /* We have successfully globbed the preceding directory name.
+	 For each name in DIRECTORIES, call glob_vector on it and
+	 FILENAME.  Concatenate the results together.  */
+      for (i = 0; directories[i] != NULL; ++i)
+	{
+	  char **temp_results;
+
+	  /* Scan directory even on a NULL pathname.  That way, `*h/'
+	     returns only directories ending in `h', instead of all
+	     files ending in `h' with a `/' appended. */
+	  temp_results = glob_vector (filename, directories[i]);
+
+	  /* Handle error cases. */
+	  if (temp_results == NULL)
+	    goto memory_error;
+	  else if (temp_results == (char **)&glob_error_return)
+	    /* This filename is probably not a directory.  Ignore it.  */
+	    ;
+	  else
+	    {
+	      char **array;
+	      register unsigned int l;
+
+	      array = glob_dir_to_array (directories[i], temp_results);
+	      l = 0;
+	      while (array[l] != NULL)
+		++l;
+
+	      result =
+		(char **)xrealloc(result, (result_size + l) * sizeof (char *));
+
+	      if (result == NULL)
+		goto memory_error;
+
+	      for (l = 0; array[l] != NULL; ++l)
+		result[result_size++ - 1] = array[l];
+
+	      result[result_size - 1] = NULL;
+
+	      /* Note that the elements of ARRAY are not freed.  */
+	      free ((char *) array);
+	    }
+	}
+      /* Free the directories.  */
+      for (i = 0; directories[i]; i++)
+	free (directories[i]);
+
+      free ((char *) directories);
+
+      return (result);
+    }
+
+  /* If there is only a directory name, return it. */
+  if (*filename == '\0')
+    {
+      result = (char **) xrealloc ((char *) result, 2 * sizeof (char *));
+      if (result == NULL)
+	return (NULL);
+      result[0] = (char *) xmalloc (directory_len + 1);
+      if (result[0] == NULL)
+	goto memory_error;
+      bcopy (directory_name, result[0], directory_len + 1);
+      result[1] = NULL;
+      return (result);
+    }
+  else
+    {
+      char **temp_results;
+
+      /* There are no unquoted globbing characters in DIRECTORY_NAME.
+	 Dequote it before we try to open the directory since there may
+	 be quoted globbing characters which should be treated verbatim. */
+      if (directory_len > 0)
+	dequote_pathname (directory_name);
+
+      /* We allocated a small array called RESULT, which we won't be using.
+	 Free that memory now. */
+      free (result);
+
+      /* Just return what glob_vector () returns appended to the
+	 directory name. */
+      temp_results =
+	glob_vector (filename, (directory_len == 0 ? "." : directory_name));
+
+      if (temp_results == NULL || temp_results == (char **)&glob_error_return)
+	return (temp_results);
+
+      return (glob_dir_to_array (directory_name, temp_results));
+    }
+
+  /* We get to memory_error if the program has run out of memory, or
+     if this is the shell, and we have been interrupted. */
+ memory_error:
+  if (result != NULL)
+    {
+      register unsigned int i;
+      for (i = 0; result[i] != NULL; ++i)
+	free (result[i]);
+      free ((char *) result);
+    }
+#if defined (SHELL)
+  if (interrupt_state)
+    throw_to_top_level ();
+#endif /* SHELL */
+  return (NULL);
+}
+
+#if defined (TEST)
+
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  unsigned int i;
+
+  for (i = 1; i < argc; ++i)
+    {
+      char **value = glob_filename (argv[i]);
+      if (value == NULL)
+	puts ("Out of memory.");
+      else if (value == &glob_error_return)
+	perror (argv[i]);
+      else
+	for (i = 0; value[i] != NULL; i++)
+	  puts (value[i]);
+    }
+
+  exit (0);
+}
+#endif	/* TEST.  */
diff -iNu ruby-1.3_org/hash.c ruby-1.3/hash.c
--- ruby-1.3_org/hash.c	Tue Dec 22 18:01:51 1998
+++ ruby-1.3/hash.c	Tue Jan 12 21:56:14 1999
@@ -873,7 +873,7 @@
     VALUE obj, name;
 {
     char *nam, *env;
-    int len;
+    unsigned int len;
 
     nam = str2cstr(name, &len);
     if (strlen(nam) != len) {
@@ -1093,9 +1093,9 @@
 
     Check_SafeStr(name);
     Check_SafeStr(value);
-    if (strlen(RSTRING(name)->ptr) != RSTRING(name)->len)
+    if (strlen(RSTRING(name)->ptr) != (UINT)(RSTRING(name)->len))
 	rb_raise(rb_eArgError, "Bad environment name");
-    if (strlen(RSTRING(value)->ptr) != RSTRING(value)->len)
+    if (strlen(RSTRING(value)->ptr) != (UINT)(RSTRING(value)->len))
 	rb_raise(rb_eArgError, "Bad environment value");
 
     my_setenv(RSTRING(name)->ptr, RSTRING(value)->ptr);
diff -iNu ruby-1.3_org/inits.c ruby-1.3/inits.c
--- ruby-1.3_org/inits.c	Tue Oct 06 12:28:10 1998
+++ ruby-1.3/inits.c	Fri Jan 15 21:19:26 1999
@@ -12,36 +12,36 @@
 
 #include "ruby.h"
 
-void Init_Array _((void));
-void Init_Bignum _((void));
-void Init_Comparable _((void));
-void Init_Dir _((void));
-void Init_Enumerable _((void));
-void Init_Exception _((void));
-void Init_eval _((void));
-void Init_load _((void));
-void Init_Proc _((void));
-void Init_Thread _((void));
-void Init_File _((void));
-void Init_GC _((void));
-void Init_Hash _((void));
-void Init_IO _((void));
-void Init_Math _((void));
-void Init_marshal _((void));
-void Init_Numeric _((void));
-void Init_Object _((void));
-void Init_pack _((void));
-void Init_sym _((void));
-void Init_process _((void));
-void Init_Random _((void));
-void Init_Range _((void));
-void Init_Regexp _((void));
-void Init_signal _((void));
-void Init_String _((void));
-void Init_Struct _((void));
-void Init_Time _((void));
-void Init_var_tables _((void));
-void Init_version _((void));
+extern void Init_Array _((void));
+extern void Init_Bignum _((void));
+extern void Init_Comparable _((void));
+extern void Init_Dir _((void));
+extern void Init_Enumerable _((void));
+extern void Init_Exception _((void));
+extern void Init_eval _((void));
+extern void Init_load _((void));
+extern void Init_Proc _((void));
+extern void Init_Thread _((void));
+extern void Init_File _((void));
+extern void Init_GC _((void));
+extern void Init_Hash _((void));
+extern void Init_IO _((void));
+extern void Init_Math _((void));
+extern void Init_marshal _((void));
+extern void Init_Numeric _((void));
+extern void Init_Object _((void));
+extern void Init_pack _((void));
+extern void Init_sym _((void));
+extern void Init_process _((void));
+extern void Init_Random _((void));
+extern void Init_Range _((void));
+extern void Init_Regexp _((void));
+extern void Init_signal _((void));
+extern void Init_String _((void));
+extern void Init_Struct _((void));
+extern void Init_Time _((void));
+extern void Init_var_tables _((void));
+extern void Init_version _((void));
 
 void
 rb_call_inits()
diff -iNu ruby-1.3_org/intern.h ruby-1.3/intern.h
--- ruby-1.3_org/intern.h	Thu Dec 24 18:09:15 1998
+++ ruby-1.3/intern.h	Fri Jan 15 21:10:28 1999
@@ -1,310 +1,311 @@
-/* Functions and variables that are used by more than one source file of
- * the kernel.  Not available to extensions and applications.
- */
-
-/* array.c */
-void rb_mem_clear _((register VALUE*, register int));
-VALUE rb_assoc_new _((VALUE, VALUE));
-VALUE rb_ary_new _((void));
-VALUE rb_ary_new2 _((int));
-VALUE rb_ary_new3 __((int,...));
-VALUE rb_ary_new4 _((int, VALUE *));
-VALUE rb_ary_freeze _((VALUE));
-VALUE rb_ary_aref _((int, VALUE*, VALUE));
-void rb_ary_store _((VALUE, int, VALUE));
-VALUE rb_ary_to_s _((VALUE));
-VALUE rb_ary_push _((VALUE, VALUE));
-VALUE rb_ary_pop _((VALUE));
-VALUE rb_ary_shift _((VALUE));
-VALUE rb_ary_unshift _((VALUE, VALUE));
-VALUE rb_ary_entry _((VALUE, int));
-VALUE rb_ary_each _((VALUE));
-VALUE rb_ary_join _((VALUE, VALUE));
-VALUE rb_ary_print_on _((VALUE, VALUE));
-VALUE rb_ary_reverse _((VALUE));
-VALUE rb_ary_sort _((VALUE));
-VALUE rb_ary_sort_bang _((VALUE));
-VALUE rb_ary_delete _((VALUE, VALUE));
-VALUE rb_ary_delete_at _((VALUE, VALUE));
-VALUE rb_ary_plus _((VALUE, VALUE));
-VALUE rb_ary_concat _((VALUE, VALUE));
-VALUE rb_ary_assoc _((VALUE, VALUE));
-VALUE rb_ary_rassoc _((VALUE, VALUE));
-VALUE rb_ary_includes _((VALUE, VALUE));
-/* bignum.c */
-VALUE rb_big_clone _((VALUE));
-void rb_big_2comp _((VALUE));
-VALUE rb_big_norm _((VALUE));
-VALUE rb_uint2big _((unsigned long));
-VALUE rb_int2big _((long));
-VALUE rb_uint2inum _((unsigned long));
-VALUE rb_int2inum _((long));
-VALUE rb_str2inum _((char*, int));
-VALUE rb_big2str _((VALUE, int));
-long rb_big2long _((VALUE));
-#define rb_big2int(x) rb_big2long(x)
-unsigned long rb_big2ulong _((VALUE));
-#define rb_big2uint(x) rb_big2ulong(x)
-VALUE rb_dbl2big _((double));
-double rb_big2dbl _((VALUE));
-VALUE rb_big_plus _((VALUE, VALUE));
-VALUE rb_big_minus _((VALUE, VALUE));
-VALUE rb_big_mul _((VALUE, VALUE));
-VALUE rb_big_pow _((VALUE, VALUE));
-VALUE rb_big_and _((VALUE, VALUE));
-VALUE rb_big_or _((VALUE, VALUE));
-VALUE rb_big_xor _((VALUE, VALUE));
-VALUE rb_big_lshift _((VALUE, VALUE));
-VALUE rb_big_rand _((VALUE));
-/* class.c */
-VALUE rb_class_new _((VALUE));
-VALUE rb_singleton_class_new _((VALUE));
-VALUE rb_singleton_class_clone _((VALUE));
-void rb_singleton_class_attached _((VALUE,VALUE));
-VALUE rb_define_class_id _((ID, VALUE));
-VALUE rb_module_new _((void));
-VALUE rb_define_module_id _((ID));
-VALUE rb_mod_included_modules _((VALUE));
-VALUE rb_mod_ancestors _((VALUE));
-VALUE rb_class_instance_methods _((int, VALUE*, VALUE));
-VALUE rb_class_protected_instance_methods _((int, VALUE*, VALUE));
-VALUE rb_class_private_instance_methods _((int, VALUE*, VALUE));
-VALUE rb_obj_singleton_methods _((VALUE));
-void rb_define_method_id _((VALUE, ID, VALUE (*)(), int));
-void rb_undef_method _((VALUE, char*));
-void rb_define_protected_method _((VALUE, char*, VALUE (*)(), int));
-void rb_define_private_method _((VALUE, char*, VALUE (*)(), int));
-void rb_define_singleton_method _((VALUE,char*,VALUE(*)(),int));
-void rb_define_private_method _((VALUE,char*,VALUE(*)(),int));
-VALUE rb_singleton_class _((VALUE));
-/* enum.c */
-VALUE rb_enum_length _((VALUE));
-/* error.c */
-extern int ruby_nerrs;
-VALUE rb_exc_new _((VALUE, char*, int));
-VALUE rb_exc_new2 _((VALUE, char*));
-VALUE rb_exc_new3 _((VALUE, VALUE));
-void rb_loaderror __((char*, ...)) NORETURN;
-void rb_compile_error __((char*, ...));
-void rb_compile_append __((char*, ...));
-/* eval.c */
-void rb_exc_raise _((VALUE)) NORETURN;
-void rb_exc_fatal _((VALUE)) NORETURN;
-void rb_remove_method _((VALUE, char*));
-void rb_disable_super _((VALUE, char*));
-void rb_enable_super _((VALUE, char*));
-void rb_clear_cache _((void));
-void rb_alias _((VALUE, ID, ID));
-void rb_attr _((VALUE,ID,int,int,int));
-int rb_method_boundp _((VALUE, ID, int));
-VALUE rb_dvar_defined _((ID));
-VALUE rb_dvar_ref _((ID));
-void rb_dvar_asgn _((ID, VALUE));
-void rb_dvar_push _((ID, VALUE));
-VALUE rb_eval_cmd _((VALUE, VALUE));
-VALUE rb_trap_eval _((VALUE, int));
-int rb_respond_to _((VALUE, ID));
-void rb_interrupt _((void));
-VALUE rb_apply _((VALUE, ID, VALUE));
-VALUE rb_funcall2 _((VALUE, ID, int, VALUE*));
-void rb_backtrace _((void));
-ID rb_frame_last_func _((void));
-VALUE rb_obj_instance_eval _((int, VALUE*, VALUE));
-void rb_load _((VALUE, VALUE));
-void rb_provide _((char*));
-VALUE rb_f_require _((VALUE, VALUE));
-void rb_obj_call_init _((VALUE));
-VALUE rb_class_new_instance _((int, VALUE*, VALUE));
-VALUE rb_f_lambda _((void));
-void rb_set_end_proc _((void (*)(),VALUE));
-void rb_gc_mark_threads _((void));
-void thread_start_timer _((void));
-void thread_stop_timer _((void));
-void rb_thread_schedule _((void));
-void rb_thread_wait_fd _((int));
-void rb_thread_fd_writable _((int));
-int rb_thread_alone _((void));
-void rb_thread_sleep _((int));
-void rb_thread_sleep_forever _((void));
-VALUE rb_thread_create _((VALUE (*)(), void*));
-int rb_thread_scope_shared_p _((void));
-void rb_thread_interrupt _((void));
-void rb_thread_trap_eval _((VALUE, int));
-int rb_thread_select();
-void rb_thread_wait_for();
-/* file.c */
-VALUE rb_file_open _((char*, char*));
-int eaccess _((char*, int));
-VALUE rb_file_s_expand_path _((int, VALUE *));
-/* gc.c */
-void rb_global_variable _((VALUE*));
-void rb_gc_mark_locations _((VALUE*, VALUE*));
-void rb_gc_mark_maybe();
-void rb_gc_mark();
-void rb_gc_force_recycle _((VALUE));
-void rb_gc _((void));
-void rb_gc_call_finalizer_at_exit _((void));
-/* hash.c */
-VALUE rb_hash _((VALUE));
-VALUE rb_hash_new _((void));
-VALUE rb_hash_freeze _((VALUE));
-VALUE rb_hash_aref _((VALUE, VALUE));
-VALUE rb_hash_aset _((VALUE, VALUE, VALUE));
-int rb_path_check _((char *));
-int rb_env_path_tainted _((void));
-/* io.c */
-extern VALUE rb_fs;
-extern VALUE rb_output_fs;
-extern VALUE rb_rs;
-extern VALUE rb_default_rs;
-extern VALUE rb_output_rs;
-VALUE rb_io_write _((VALUE, VALUE));
-VALUE rb_io_gets _((VALUE));
-VALUE rb_io_getc _((VALUE));
-VALUE rb_io_ungetc _((VALUE, VALUE));
-VALUE rb_io_close _((VALUE));
-VALUE rb_io_binmode _((VALUE));
-int rb_io_mode_flags _((char*));
-VALUE rb_io_reopen _((VALUE, VALUE));
-VALUE rb_gets _((void));
-void rb_str_setter _((VALUE, ID, VALUE*));
-/* numeric.c */
-void rb_num_zerodiv _((void));
-VALUE rb_num_coerce_bin _((VALUE, VALUE));
-VALUE rb_float_new _((double));
-VALUE rb_num2fix _((VALUE));
-VALUE rb_fix2str _((VALUE, int));
-VALUE rb_fix_upto _((VALUE, VALUE));
-/* object.c */
-int rb_eql _((VALUE, VALUE));
-VALUE rb_any_to_s _((VALUE));
-VALUE rb_inspect _((VALUE));
-VALUE rb_obj_is_instance_of _((VALUE, VALUE));
-VALUE rb_obj_is_kind_of _((VALUE, VALUE));
-VALUE rb_obj_alloc _((VALUE));
-VALUE rb_obj_clone _((VALUE));
-VALUE rb_obj_taint _((VALUE));
-VALUE rb_obj_tainted _((VALUE));
-VALUE rb_obj_untaint _((VALUE));
-VALUE rb_convert_type _((VALUE,int,char*,char*));
-VALUE rb_Integer _((VALUE));
-VALUE rb_Float _((VALUE));
-VALUE rb_String _((VALUE));
-VALUE rb_Array _((VALUE));
-/* parse.y */
-extern int   ruby_sourceline;
-extern char *ruby_sourcefile;
-int yyparse _((void));
-ID rb_id_attrset _((ID));
-void rb_parser_append_print _((void));
-void rb_parser_while_loop _((int, int));
-int rb_is_const_id _((ID));
-int rb_is_instance_id _((ID));
-VALUE rb_backref_get _((void));
-void rb_backref_set _((VALUE));
-VALUE rb_lastline_get _((void));
-void rb_lastline_set _((VALUE));
-/* process.c */
-int rb_proc_exec _((char*));
-void rb_syswait _((int));
-/* range.c */
-VALUE rb_range_new _((VALUE, VALUE));
-VALUE rb_range_beg_end _((VALUE, int*, int*));
-/* re.c */
-VALUE rb_reg_nth_defined _((int, VALUE));
-VALUE rb_reg_nth_match _((int, VALUE));
-VALUE rb_reg_last_match _((VALUE));
-VALUE rb_reg_match_pre _((VALUE));
-VALUE rb_reg_match_post _((VALUE));
-VALUE rb_reg_match_last _((VALUE));
-VALUE rb_reg_new _((char*, int, int));
-VALUE rb_reg_match _((VALUE, VALUE));
-VALUE rb_reg_match2 _((VALUE));
-int rb_reg_options _((VALUE));
-char*rb_get_kcode _((void));
-void rb_set_kcode _((char*));
-int rb_ignorecase_p _((void));
-/* ruby.c */
-void rb_load_file _((char*));
-void ruby_script _((char*));
-void ruby_prog_init _((void));
-void ruby_set_argv _((int, char**));
-void ruby_process_options _((int, char**));
-void ruby_require_modules _((void));
-void ruby_load_script _((void));
-/* signal.c */
-VALUE rb_f_kill _((int, VALUE*));
-void rb_gc_mark_trap_list _((void));
-#ifdef POSIX_SIGNAL
-#define posix_signal ruby_posix_signal
-void posix_signal _((int, void (*)()));
-#endif
-void rb_trap_exit _((void));
-void rb_trap_exec _((void));
-/* sprintf.c */
-VALUE rb_f_sprintf _((int, VALUE*));
-/* string.c */
-VALUE rb_str_new _((char*, int));
-VALUE rb_str_new2 _((char*));
-VALUE rb_str_new3 _((VALUE));
-VALUE rb_str_new4 _((VALUE));
-VALUE rb_tainted_str_new _((char*, int));
-VALUE rb_tainted_str_new2 _((char*));
-VALUE rb_obj_as_string _((VALUE));
-VALUE rb_str_to_str _((VALUE));
-VALUE rb_str_dup _((VALUE));
-VALUE rb_str_plus _((VALUE, VALUE));
-VALUE rb_str_times _((VALUE, VALUE));
-VALUE rb_str_substr _((VALUE, int, int));
-void rb_str_modify _((VALUE));
-VALUE rb_str_freeze _((VALUE));
-VALUE rb_str_dup_frozen _((VALUE));
-VALUE rb_str_resize _((VALUE, int));
-VALUE rb_str_cat _((VALUE, char*, int));
-VALUE rb_str_concat _((VALUE, VALUE));
-int rb_str_hash _((VALUE));
-int rb_str_cmp _((VALUE, VALUE));
-VALUE rb_str_upto _((VALUE, VALUE));
-VALUE rb_str_inspect _((VALUE));
-VALUE rb_str_split _((VALUE, char*));
-/* struct.c */
-VALUE rb_struct_new __((VALUE, ...));
-VALUE rb_struct_define __((char*, ...));
-VALUE rb_struct_alloc _((VALUE, VALUE));
-VALUE rb_struct_aref _((VALUE, VALUE));
-VALUE rb_struct_aset _((VALUE, VALUE, VALUE));
-VALUE rb_struct_getmember _((VALUE, ID));
-/* time.c */
-VALUE rb_time_new _((int, int));
-/* variable.c */
-VALUE rb_mod_name _((VALUE));
-VALUE rb_class_path _((VALUE));
-void rb_set_class_path _((VALUE, VALUE, char*));
-VALUE rb_path2class _((char*));
-void rb_name_class _((VALUE, ID));
-void rb_autoload _((char*, char*));
-VALUE rb_f_autoload _((VALUE, VALUE, VALUE));
-void rb_gc_mark_global_tbl _((void));
-VALUE rb_f_trace_var _((int, VALUE*));
-VALUE rb_f_untrace_var _((int, VALUE*));
-VALUE rb_gvar_set2 _((char*, VALUE));
-VALUE rb_f_global_variables _((void));
-void rb_alias_variable _((ID, ID));
-void rb_mark_generic_ivar _((VALUE));
-void rb_mark_generic_ivar_tbl _((void));
-void rb_free_generic_ivar _((VALUE));
-VALUE rb_ivar_get _((VALUE, ID));
-VALUE rb_ivar_set _((VALUE, ID, VALUE));
-VALUE rb_ivar_defined _((VALUE, ID));
-VALUE rb_obj_instance_variables _((VALUE));
-VALUE rb_obj_remove_instance_variable _((VALUE, VALUE));
-VALUE rb_mod_const_at _((VALUE, VALUE));
-VALUE rb_mod_constants _((VALUE));
-VALUE rb_mod_const_of _((VALUE, VALUE));
-VALUE rb_mod_remove_const _((VALUE, VALUE));
-int rb_const_defined_at _((VALUE, ID));
-int rb_autoload_defined _((ID));
-int rb_const_defined _((VALUE, ID));
-/* version.c */
-void ruby_show_version _((void));
-void ruby_show_copyright _((void));
+/* Functions and variables that are used by more than one source file of
+ * the kernel.  Not available to extensions and applications.
+ */
+
+/* array.c */
+EXTERN void rb_mem_clear _((register VALUE*, register int));
+EXTERN VALUE rb_assoc_new _((VALUE, VALUE));
+EXTERN VALUE rb_ary_new _((void));
+EXTERN VALUE rb_ary_new2 _((int));
+EXTERN VALUE rb_ary_new3 __((int,...));
+EXTERN VALUE rb_ary_new4 _((int, VALUE *));
+EXTERN VALUE rb_ary_freeze _((VALUE));
+EXTERN VALUE rb_ary_aref _((int, VALUE*, VALUE));
+EXTERN void rb_ary_store _((VALUE, int, VALUE));
+EXTERN VALUE rb_ary_to_s _((VALUE));
+EXTERN VALUE rb_ary_push _((VALUE, VALUE));
+EXTERN VALUE rb_ary_pop _((VALUE));
+EXTERN VALUE rb_ary_shift _((VALUE));
+EXTERN VALUE rb_ary_unshift _((VALUE, VALUE));
+EXTERN VALUE rb_ary_entry _((VALUE, int));
+EXTERN VALUE rb_ary_each _((VALUE));
+EXTERN VALUE rb_ary_join _((VALUE, VALUE));
+EXTERN VALUE rb_ary_print_on _((VALUE, VALUE));
+EXTERN VALUE rb_ary_reverse _((VALUE));
+EXTERN VALUE rb_ary_sort _((VALUE));
+EXTERN VALUE rb_ary_sort_bang _((VALUE));
+EXTERN VALUE rb_ary_delete _((VALUE, VALUE));
+EXTERN VALUE rb_ary_delete_at _((VALUE, VALUE));
+EXTERN VALUE rb_ary_plus _((VALUE, VALUE));
+EXTERN VALUE rb_ary_concat _((VALUE, VALUE));
+EXTERN VALUE rb_ary_assoc _((VALUE, VALUE));
+EXTERN VALUE rb_ary_rassoc _((VALUE, VALUE));
+EXTERN VALUE rb_ary_includes _((VALUE, VALUE));
+/* bignum.c */
+EXTERN VALUE rb_big_clone _((VALUE));
+EXTERN void rb_big_2comp _((VALUE));
+EXTERN VALUE rb_big_norm _((VALUE));
+EXTERN VALUE rb_uint2big _((unsigned long));
+EXTERN VALUE rb_int2big _((long));
+EXTERN VALUE rb_uint2inum _((unsigned long));
+EXTERN VALUE rb_int2inum _((long));
+EXTERN VALUE rb_str2inum _((char*, int));
+EXTERN VALUE rb_big2str _((VALUE, int));
+EXTERN long rb_big2long _((VALUE));
+#define rb_big2int(x) rb_big2long(x)
+EXTERN unsigned long rb_big2ulong _((VALUE));
+#define rb_big2uint(x) rb_big2ulong(x)
+EXTERN VALUE rb_dbl2big _((double));
+EXTERN double rb_big2dbl _((VALUE));
+EXTERN VALUE rb_big_plus _((VALUE, VALUE));
+EXTERN VALUE rb_big_minus _((VALUE, VALUE));
+EXTERN VALUE rb_big_mul _((VALUE, VALUE));
+EXTERN VALUE rb_big_pow _((VALUE, VALUE));
+EXTERN VALUE rb_big_and _((VALUE, VALUE));
+EXTERN VALUE rb_big_or _((VALUE, VALUE));
+EXTERN VALUE rb_big_xor _((VALUE, VALUE));
+EXTERN VALUE rb_big_lshift _((VALUE, VALUE));
+EXTERN VALUE rb_big_rand _((VALUE));
+/* class.c */
+EXTERN VALUE rb_class_new _((VALUE));
+EXTERN VALUE rb_singleton_class_new _((VALUE));
+EXTERN VALUE rb_singleton_class_clone _((VALUE));
+EXTERN void rb_singleton_class_attached _((VALUE,VALUE));
+EXTERN VALUE rb_define_class_id _((ID, VALUE));
+EXTERN VALUE rb_module_new _((void));
+EXTERN VALUE rb_define_module_id _((ID));
+EXTERN VALUE rb_mod_included_modules _((VALUE));
+EXTERN VALUE rb_mod_ancestors _((VALUE));
+EXTERN VALUE rb_class_instance_methods _((int, VALUE*, VALUE));
+EXTERN VALUE rb_class_protected_instance_methods _((int, VALUE*, VALUE));
+EXTERN VALUE rb_class_private_instance_methods _((int, VALUE*, VALUE));
+EXTERN VALUE rb_obj_singleton_methods _((VALUE));
+EXTERN void rb_define_method_id _((VALUE, ID, VALUE (*)(), int));
+EXTERN void rb_undef_method _((VALUE, char*));
+EXTERN void rb_define_protected_method _((VALUE, char*, VALUE (*)(), int));
+EXTERN void rb_define_private_method _((VALUE, char*, VALUE (*)(), int));
+EXTERN void rb_define_singleton_method _((VALUE,char*,VALUE(*)(),int));
+EXTERN void rb_define_private_method _((VALUE,char*,VALUE(*)(),int));
+EXTERN VALUE rb_singleton_class _((VALUE));
+/* enum.c */
+EXTERN VALUE rb_enum_length _((VALUE));
+/* error.c */
+extern int ruby_nerrs;
+EXTERN VALUE rb_exc_new _((VALUE, char*, int));
+EXTERN VALUE rb_exc_new2 _((VALUE, char*));
+EXTERN VALUE rb_exc_new3 _((VALUE, VALUE));
+EXTERN void rb_loaderror __((char*, ...)) NORETURN;
+EXTERN void rb_compile_error __((char*, ...));
+EXTERN void rb_compile_error_append __((char *, ...));
+EXTERN void rb_compile_append __((char*, ...));
+/* eval.c */
+EXTERN void rb_exc_raise _((VALUE)) NORETURN;
+EXTERN void rb_exc_fatal _((VALUE)) NORETURN;
+EXTERN void rb_remove_method _((VALUE, char*));
+EXTERN void rb_disable_super _((VALUE, char*));
+EXTERN void rb_enable_super _((VALUE, char*));
+EXTERN void rb_clear_cache _((void));
+EXTERN void rb_alias _((VALUE, ID, ID));
+EXTERN void rb_attr _((VALUE,ID,int,int,int));
+EXTERN int rb_method_boundp _((VALUE, ID, int));
+EXTERN VALUE rb_dvar_defined _((ID));
+EXTERN VALUE rb_dvar_ref _((ID));
+EXTERN void rb_dvar_asgn _((ID, VALUE));
+EXTERN void rb_dvar_push _((ID, VALUE));
+EXTERN VALUE rb_eval_cmd _((VALUE, VALUE));
+EXTERN VALUE rb_trap_eval _((VALUE, int));
+EXTERN int rb_respond_to _((VALUE, ID));
+EXTERN void rb_interrupt _((void));
+EXTERN VALUE rb_apply _((VALUE, ID, VALUE));
+EXTERN VALUE rb_funcall2 _((VALUE, ID, int, VALUE*));
+EXTERN void rb_backtrace _((void));
+EXTERN ID rb_frame_last_func _((void));
+EXTERN VALUE rb_obj_instance_eval _((int, VALUE*, VALUE));
+EXTERN void rb_load _((VALUE, VALUE));
+EXTERN void rb_provide _((char*));
+EXTERN VALUE rb_f_require _((VALUE, VALUE));
+EXTERN void rb_obj_call_init _((VALUE));
+EXTERN VALUE rb_class_new_instance _((int, VALUE*, VALUE));
+EXTERN VALUE rb_f_lambda _((void));
+EXTERN void rb_set_end_proc _((void (*)(),VALUE));
+EXTERN void rb_gc_mark_threads _((void));
+EXTERN void thread_start_timer _((void));
+EXTERN void thread_stop_timer _((void));
+EXTERN void rb_thread_schedule _((void));
+EXTERN void rb_thread_wait_fd _((int));
+EXTERN void rb_thread_fd_writable _((int));
+EXTERN int rb_thread_alone _((void));
+EXTERN void rb_thread_sleep _((int));
+EXTERN void rb_thread_sleep_forever _((void));
+EXTERN VALUE rb_thread_create _((VALUE (*)(), void*));
+EXTERN int rb_thread_scope_shared_p _((void));
+EXTERN void rb_thread_interrupt _((void));
+EXTERN void rb_thread_trap_eval _((VALUE, int));
+EXTERN int rb_thread_select();
+EXTERN void rb_thread_wait_for();
+/* file.c */
+EXTERN VALUE rb_file_open _((char*, char*));
+EXTERN int eaccess _((char*, int));
+EXTERN VALUE rb_file_s_expand_path _((int, VALUE *));
+/* gc.c */
+EXTERN void rb_global_variable _((VALUE*));
+EXTERN void rb_gc_mark_locations _((VALUE*, VALUE*));
+EXTERN void rb_gc_mark_maybe();
+EXTERN void rb_gc_mark();
+EXTERN void rb_gc_force_recycle _((VALUE));
+EXTERN void rb_gc _((void));
+EXTERN void rb_gc_call_finalizer_at_exit _((void));
+/* hash.c */
+EXTERN VALUE rb_hash _((VALUE));
+EXTERN VALUE rb_hash_new _((void));
+EXTERN VALUE rb_hash_freeze _((VALUE));
+EXTERN VALUE rb_hash_aref _((VALUE, VALUE));
+EXTERN VALUE rb_hash_aset _((VALUE, VALUE, VALUE));
+EXTERN int rb_path_check _((char *));
+EXTERN int rb_env_path_tainted _((void));
+/* io.c */
+extern VALUE rb_fs;
+extern VALUE rb_output_fs;
+extern VALUE rb_rs;
+extern VALUE rb_default_rs;
+extern VALUE rb_output_rs;
+EXTERN VALUE rb_io_write _((VALUE, VALUE));
+EXTERN VALUE rb_io_gets _((VALUE));
+EXTERN VALUE rb_io_getc _((VALUE));
+EXTERN VALUE rb_io_ungetc _((VALUE, VALUE));
+EXTERN VALUE rb_io_close _((VALUE));
+EXTERN VALUE rb_io_binmode _((VALUE));
+EXTERN int rb_io_mode_flags _((char*));
+EXTERN VALUE rb_io_reopen _((VALUE, VALUE));
+EXTERN VALUE rb_gets _((void));
+EXTERN void rb_str_setter _((VALUE, ID, VALUE*));
+/* numeric.c */
+EXTERN void rb_num_zerodiv _((void));
+EXTERN VALUE rb_num_coerce_bin _((VALUE, VALUE));
+EXTERN VALUE rb_float_new _((double));
+EXTERN VALUE rb_num2fix _((VALUE));
+EXTERN VALUE rb_fix2str _((VALUE, int));
+EXTERN VALUE rb_fix_upto _((VALUE, VALUE));
+/* object.c */
+EXTERN int rb_eql _((VALUE, VALUE));
+EXTERN VALUE rb_any_to_s _((VALUE));
+EXTERN VALUE rb_inspect _((VALUE));
+EXTERN VALUE rb_obj_is_instance_of _((VALUE, VALUE));
+EXTERN VALUE rb_obj_is_kind_of _((VALUE, VALUE));
+EXTERN VALUE rb_obj_alloc _((VALUE));
+EXTERN VALUE rb_obj_clone _((VALUE));
+EXTERN VALUE rb_obj_taint _((VALUE));
+EXTERN VALUE rb_obj_tainted _((VALUE));
+EXTERN VALUE rb_obj_untaint _((VALUE));
+EXTERN VALUE rb_convert_type _((VALUE,int,char*,char*));
+EXTERN VALUE rb_Integer _((VALUE));
+EXTERN VALUE rb_Float _((VALUE));
+EXTERN VALUE rb_String _((VALUE));
+EXTERN VALUE rb_Array _((VALUE));
+/* parse.y */
+extern int   ruby_sourceline;
+extern char *ruby_sourcefile;
+EXTERN int yyparse _((void));
+EXTERN ID rb_id_attrset _((ID));
+EXTERN void rb_parser_append_print _((void));
+EXTERN void rb_parser_while_loop _((int, int));
+EXTERN int rb_is_const_id _((ID));
+EXTERN int rb_is_instance_id _((ID));
+EXTERN VALUE rb_backref_get _((void));
+EXTERN void rb_backref_set _((VALUE));
+EXTERN VALUE rb_lastline_get _((void));
+EXTERN void rb_lastline_set _((VALUE));
+/* process.c */
+EXTERN int rb_proc_exec _((char*));
+EXTERN void rb_syswait _((int));
+/* range.c */
+EXTERN VALUE rb_range_new _((VALUE, VALUE));
+EXTERN VALUE rb_range_beg_end _((VALUE, int*, int*));
+/* re.c */
+EXTERN VALUE rb_reg_nth_defined _((int, VALUE));
+EXTERN VALUE rb_reg_nth_match _((int, VALUE));
+EXTERN VALUE rb_reg_last_match _((VALUE));
+EXTERN VALUE rb_reg_match_pre _((VALUE));
+EXTERN VALUE rb_reg_match_post _((VALUE));
+EXTERN VALUE rb_reg_match_last _((VALUE));
+EXTERN VALUE rb_reg_new _((char*, int, int));
+EXTERN VALUE rb_reg_match _((VALUE, VALUE));
+EXTERN VALUE rb_reg_match2 _((VALUE));
+EXTERN int rb_reg_options _((VALUE));
+EXTERN char*rb_get_kcode _((void));
+EXTERN void rb_set_kcode _((char*));
+EXTERN int rb_ignorecase_p _((void));
+/* ruby.c */
+EXTERN void rb_load_file _((char*));
+EXTERN void ruby_script _((char*));
+EXTERN void ruby_prog_init _((void));
+EXTERN void ruby_set_argv _((int, char**));
+EXTERN void ruby_process_options _((int, char**));
+EXTERN void ruby_require_modules _((void));
+EXTERN void ruby_load_script _((void));
+/* signal.c */
+EXTERN VALUE rb_f_kill _((int, VALUE*));
+EXTERN void rb_gc_mark_trap_list _((void));
+#ifdef POSIX_SIGNAL
+#define posix_signal ruby_posix_signal
+EXTERN void posix_signal _((int, void (*)()));
+#endif
+EXTERN void rb_trap_exit _((void));
+EXTERN void rb_trap_exec _((void));
+/* sprintf.c */
+EXTERN VALUE rb_f_sprintf _((int, VALUE*));
+/* string.c */
+EXTERN VALUE rb_str_new _((char*, int));
+EXTERN VALUE rb_str_new2 _((char*));
+EXTERN VALUE rb_str_new3 _((VALUE));
+EXTERN VALUE rb_str_new4 _((VALUE));
+EXTERN VALUE rb_tainted_str_new _((char*, int));
+EXTERN VALUE rb_tainted_str_new2 _((char*));
+EXTERN VALUE rb_obj_as_string _((VALUE));
+EXTERN VALUE rb_str_to_str _((VALUE));
+EXTERN VALUE rb_str_dup _((VALUE));
+EXTERN VALUE rb_str_plus _((VALUE, VALUE));
+EXTERN VALUE rb_str_times _((VALUE, VALUE));
+EXTERN VALUE rb_str_substr _((VALUE, int, int));
+EXTERN void rb_str_modify _((VALUE));
+EXTERN VALUE rb_str_freeze _((VALUE));
+EXTERN VALUE rb_str_dup_frozen _((VALUE));
+EXTERN VALUE rb_str_resize _((VALUE, int));
+EXTERN VALUE rb_str_cat _((VALUE, char*, int));
+EXTERN VALUE rb_str_concat _((VALUE, VALUE));
+EXTERN int rb_str_hash _((VALUE));
+EXTERN int rb_str_cmp _((VALUE, VALUE));
+EXTERN VALUE rb_str_upto _((VALUE, VALUE));
+EXTERN VALUE rb_str_inspect _((VALUE));
+EXTERN VALUE rb_str_split _((VALUE, char*));
+/* struct.c */
+EXTERN VALUE rb_struct_new __((VALUE, ...));
+EXTERN VALUE rb_struct_define __((char*, ...));
+EXTERN VALUE rb_struct_alloc _((VALUE, VALUE));
+EXTERN VALUE rb_struct_aref _((VALUE, VALUE));
+EXTERN VALUE rb_struct_aset _((VALUE, VALUE, VALUE));
+EXTERN VALUE rb_struct_getmember _((VALUE, ID));
+/* time.c */
+EXTERN VALUE rb_time_new _((int, int));
+/* variable.c */
+EXTERN VALUE rb_mod_name _((VALUE));
+EXTERN VALUE rb_class_path _((VALUE));
+EXTERN void rb_set_class_path _((VALUE, VALUE, char*));
+EXTERN VALUE rb_path2class _((char*));
+EXTERN void rb_name_class _((VALUE, ID));
+EXTERN void rb_autoload _((char*, char*));
+EXTERN VALUE rb_f_autoload _((VALUE, VALUE, VALUE));
+EXTERN void rb_gc_mark_global_tbl _((void));
+EXTERN VALUE rb_f_trace_var _((int, VALUE*));
+EXTERN VALUE rb_f_untrace_var _((int, VALUE*));
+EXTERN VALUE rb_gvar_set2 _((char*, VALUE));
+EXTERN VALUE rb_f_global_variables _((void));
+EXTERN void rb_alias_variable _((ID, ID));
+EXTERN void rb_mark_generic_ivar _((VALUE));
+EXTERN void rb_mark_generic_ivar_tbl _((void));
+EXTERN void rb_free_generic_ivar _((VALUE));
+EXTERN VALUE rb_ivar_get _((VALUE, ID));
+EXTERN VALUE rb_ivar_set _((VALUE, ID, VALUE));
+EXTERN VALUE rb_ivar_defined _((VALUE, ID));
+EXTERN VALUE rb_obj_instance_variables _((VALUE));
+EXTERN VALUE rb_obj_remove_instance_variable _((VALUE, VALUE));
+EXTERN VALUE rb_mod_const_at _((VALUE, VALUE));
+EXTERN VALUE rb_mod_constants _((VALUE));
+EXTERN VALUE rb_mod_const_of _((VALUE, VALUE));
+EXTERN VALUE rb_mod_remove_const _((VALUE, VALUE));
+EXTERN int rb_const_defined_at _((VALUE, ID));
+EXTERN int rb_autoload_defined _((ID));
+EXTERN int rb_const_defined _((VALUE, ID));
+/* version.c */
+EXTERN void ruby_show_version _((void));
+EXTERN void ruby_show_copyright _((void));
diff -iNu ruby-1.3_org/io.c ruby-1.3/io.c
--- ruby-1.3_org/io.c	Thu Dec 24 13:44:15 1998
+++ ruby-1.3/io.c	Fri Jan 15 21:21:36 1999
@@ -54,8 +54,9 @@
  #include <sys/errno.h>
  #include <unix.mac.h>
  #include <compat.h>
- extern void Init_File();
 #endif
+
+extern void Init_File _((void));
 
 #ifdef __BEOS__
 #include <net/socket.h>
@@ -675,6 +676,7 @@
     GetOpenFile(io, fptr);
     rb_io_check_readable(fptr);
     fptr->lineno = NUM2INT(lineno);
+	return Qnil;
 }
 
 static void
@@ -895,7 +897,6 @@
     VALUE io;
 {
     OpenFile *fptr;
-    FILE *save;
 
     rb_secure(4);
     GetOpenFile(io, fptr);
@@ -1298,6 +1299,7 @@
 #else /* USE_CWGUSI */
 	rb_notimplement();  
 #endif
+	return Qnil;
 }
 
 static VALUE
@@ -1798,7 +1800,9 @@
 	gets_lineno = 0;
     }
 
+#if !defined(MSDOS) && !defined(__BOW__) && !defined(__CYGWIN32__) && !defined(NT) && !defined(__human68k__)
   retry:
+#endif
     if (next_p == 1) {
 	next_p = 0;
 	if (RARRAY(rb_argv)->len > 0) {
@@ -1814,8 +1818,12 @@
 		FILE *fr = rb_fopen(fn, "r");
 
 		if (ruby_inplace_mode) {
-		    struct stat st, st2;
-		    VALUE str;
+		    struct stat st;
+#if !defined(MSDOS) && !defined(__CYGWIN32__) && !(NT) && !defined(__human68k__)\
+ && !defined(USE_CWGUSI) && !defined(__BEOS__)
+		    struct stat st2;
+#endif
+			VALUE str;
 		    FILE *fw;
 
 		    if (TYPE(rb_defout) == T_FILE && rb_defout != rb_stdout) {
@@ -2323,6 +2331,7 @@
 #else
     rb_notimplement();
 #endif
+	return Qnil;
 }
 
 static VALUE
@@ -2420,6 +2429,7 @@
 #else
     rb_notimplement();
 #endif
+	return Qnil;
 }
 
 static VALUE
@@ -2845,7 +2855,7 @@
     rb_define_virtual_variable("$-i", opt_i_get, opt_i_set);
 
 #if defined (NT) || defined(DJGPP) || defined(__CYGWIN32__) || defined(__human68k__)
-    atexit(pipe_atexit);
+    atexit((void (__cdecl *)(void))pipe_atexit);
 #endif
 
     Init_File();
diff -iNu ruby-1.3_org/marshal.c ruby-1.3/marshal.c
--- ruby-1.3_org/marshal.c	Wed Nov 25 12:31:14 1998
+++ ruby-1.3/marshal.c	Mon Jan 11 15:16:46 1999
@@ -792,6 +792,7 @@
 	rb_raise(rb_eArgError, "dump format error(0x%x)", type);
 	break;
     }
+	return Qnil;
 }
 
 static VALUE
diff -iNu ruby-1.3_org/signal.c ruby-1.3/signal.c
--- ruby-1.3_org/signal.c	Wed Nov 25 12:31:17 1998
+++ ruby-1.3/signal.c	Mon Jan 11 21:43:28 1999
@@ -299,7 +299,7 @@
 	rb_bug("trap_handler: Bad signal %d", sig);
 
 #if !defined(POSIX_SIGNAL) && !defined(BSD_SIGNAL)
-    signal(sig, sighandle);
+    signal(sig, (void (__cdecl *)(int))sighandle);
 #endif
 
     if (rb_trap_immediate) {
@@ -471,7 +471,7 @@
 #ifdef POSIX_SIGNAL
     posix_signal(sig, func);
 #else
-    signal(sig, func);
+    signal(sig, (void (__cdecl *)(int))func);
 #endif
     old = trap_list[sig];
     if (!old) old = Qnil;
@@ -559,13 +559,13 @@
 #ifdef POSIX_SIGNAL
     posix_signal(SIGINT, sighandle);
 #else
-    signal(SIGINT, sighandle);
+    signal(SIGINT, (void (__cdecl *)(int))sighandle);
 #endif
 #ifdef SIGBUS
     signal(SIGBUS, sigbus);
 #endif
 #ifdef SIGSEGV
-    signal(SIGSEGV, sigsegv);
+    signal(SIGSEGV, (void (__cdecl *)(int))sigsegv);
 #endif
 #endif /* MACOS_UNUSE_SIGNAL */
 }
diff -iNu ruby-1.3_org/st.c ruby-1.3/st.c
--- ruby-1.3_org/st.c	Wed Dec 16 16:30:33 1998
+++ ruby-1.3/st.c	Mon Jan 11 16:08:56 1999
@@ -3,7 +3,8 @@
 static	char	sccsid[] = "@(#) st.c 5.1 89/12/14 Crucible";
 
 #include "config.h"
-#include <stdio.h>
+#include <stdio.h>
+#include <malloc.h>
 #include "st.h"
 
 #ifdef USE_CWGUSI
@@ -265,7 +266,6 @@
     char *value;
 {
     unsigned int hash_val, bin_pos;
-    st_table_entry *tbl;
 
     hash_val = do_hash(key, table);
     bin_pos = hash_val % table->num_bins;
diff -iNu ruby-1.3_org/string.c ruby-1.3/string.c
--- ruby-1.3_org/string.c	Thu Dec 24 13:39:55 1998
+++ ruby-1.3/string.c	Mon Jan 11 16:05:38 1999
@@ -468,7 +468,9 @@
     return INT2FIX(key);
 }
 
+#ifndef min
 #define min(a,b) (((a)>(b))?(b):(a))
+#endif
 
 int
 rb_str_cmp(str1, str2)
@@ -805,6 +807,7 @@
 	}
 	rb_raise(rb_eIndexError, "Invalid index for string");
     }
+	return Qnil;
 }
 
 static VALUE
@@ -889,7 +892,7 @@
     VALUE str;
     VALUE indx, val;
 {
-    int idx, beg, end, offset;
+    int idx, beg, end;
 
     switch (TYPE(indx)) {
       case T_FIXNUM:
@@ -938,6 +941,7 @@
 	}
 	rb_raise(rb_eIndexError, "Invalid index for string");
     }
+	return Qnil;
 }
 
 static VALUE
@@ -2019,7 +2023,7 @@
     else {
 	int start = beg;
 	int last_null = 0;
-	int idx;
+	unsigned int idx;
 	struct re_registers *regs;
 
 	while ((end = rb_reg_search(spat, str, start, 0)) >= 0) {
@@ -2328,7 +2332,7 @@
 {
     VALUE result, match;
     struct re_registers *regs;
-    int i;
+    unsigned int i;
 
     if (rb_reg_search(pat, str, *start, 0) >= 0) {
 	match = rb_backref_get();
@@ -2416,7 +2420,7 @@
 {
     ID id;
 
-    if (strlen(RSTRING(str)->ptr) != RSTRING(str)->len)
+    if (strlen(RSTRING(str)->ptr) != (UINT)(RSTRING(str)->len))
 	rb_raise(rb_eArgError, "string contains `\\0'");
     id = rb_intern(RSTRING(str)->ptr);
     return INT2FIX(id);
diff -iNu ruby-1.3_org/struct.c ruby-1.3/struct.c
--- ruby-1.3_org/struct.c	Tue Sep 08 16:09:21 1998
+++ ruby-1.3/struct.c	Mon Jan 11 16:05:02 1999
@@ -74,6 +74,7 @@
     }
     rb_raise(rb_eNameError, "%s is not struct member", rb_id2name(id));
     /* not reached */
+	return Qnil;
 }
 
 static VALUE
@@ -126,6 +127,7 @@
     }
     rb_raise(rb_eNameError, "not struct member");
     /* not reached */
+	return Qnil;
 }
 
 static VALUE
@@ -245,6 +247,7 @@
 	return (VALUE)st;
     }
     /* not reached */
+	return Qnil;
 }
 
 VALUE
@@ -363,11 +366,12 @@
 
     len = RARRAY(member)->len;
     for (i=0; i<len; i++) {
-	if (FIX2INT(RARRAY(member)->ptr[i]) == id) {
+	if (FIX2INT(RARRAY(member)->ptr[i]) == (int)id) {
 	    return RSTRUCT(s)->ptr[i];
 	}
     }
     rb_raise(rb_eNameError, "no member '%s' in struct", rb_id2name(id));
+	return Qnil;
 }
 
 VALUE
@@ -406,12 +410,13 @@
 
     len = RARRAY(member)->len;
     for (i=0; i<len; i++) {
-	if (FIX2INT(RARRAY(member)->ptr[i]) == id) {
+	if (FIX2INT(RARRAY(member)->ptr[i]) == (int)id) {
 	    RSTRUCT(s)->ptr[i] = val;
 	    return val;
 	}
     }
     rb_raise(rb_eNameError, "no member '%s' in struct", rb_id2name(id));
+	return Qnil;
 }
 
 VALUE
diff -iNu ruby-1.3_org/time.c ruby-1.3/time.c
--- ruby-1.3_org/time.c	Wed Dec 16 16:30:34 1998
+++ ruby-1.3/time.c	Mon Jan 11 23:26:40 1999
@@ -114,8 +114,8 @@
       case T_FLOAT:
 	if (RFLOAT(time)->value < 0.0)
 	    rb_raise(rb_eArgError, "time must be positive");
-	t.tv_sec = floor(RFLOAT(time)->value);
-	t.tv_usec = (RFLOAT(time)->value - t.tv_sec) * 1000000.0;
+	t.tv_sec = (long)(floor(RFLOAT(time)->value));
+	t.tv_usec = (long)((RFLOAT(time)->value - t.tv_sec) * 1000000.0);
 	break;
 
       case T_BIGNUM:
@@ -283,6 +283,7 @@
 
   error:
     rb_raise(rb_eArgError, "gmtime/localtime error");
+	return Qnil;
 }
 
 static VALUE
@@ -490,7 +491,7 @@
     if (TYPE(time2) == T_FLOAT) {
 	unsigned int nsec = (unsigned int)RFLOAT(time2)->value;
 	sec = tobj1->tv.tv_sec + nsec;
-	usec = tobj1->tv.tv_usec + (RFLOAT(time2)->value - (double)nsec)*1e6;
+	usec = (int)(tobj1->tv.tv_usec + (RFLOAT(time2)->value - (double)nsec)*1e6);
     }
     else if (rb_obj_is_instance_of(time2, rb_cTime)) {
 	GetTimeval(time2, tobj2);
@@ -529,7 +530,7 @@
     }
     else if (TYPE(time2) == T_FLOAT) {
 	sec = tobj1->tv.tv_sec - (int)RFLOAT(time2)->value;
-	usec = tobj1->tv.tv_usec - (RFLOAT(time2)->value - (double)sec)*1e6;
+	usec = (int)(tobj1->tv.tv_usec - (RFLOAT(time2)->value - (double)sec)*1e6);
     }
     else {
 	sec = tobj1->tv.tv_sec - NUM2INT(time2);
@@ -723,6 +724,7 @@
     }
 
     rb_raise(rb_eArgError, "bad strftime format or result too long");
+	return Qnil;
 }
 
 static VALUE
@@ -733,7 +735,7 @@
     char buffer[SMALLBUF];
     char *fmt;
     char *buf = buffer;
-    int len;
+    unsigned int len;
     VALUE str;
 
     GetTimeval(time, tobj);
diff -iNu ruby-1.3_org/util.c ruby-1.3/util.c
--- ruby-1.3_org/util.c	Thu Dec 24 13:44:21 1998
+++ ruby-1.3/util.c	Mon Jan 11 15:59:30 1999
@@ -13,11 +13,12 @@
 #include <stdio.h>
 
 #define RUBY_NO_INLINE
-#include "ruby.h"
 
 #ifdef NT
 #include "missing/file.h"
 #endif
+
+#include "ruby.h"
 
 VALUE
 rb_class_of(obj)
diff -iNu ruby-1.3_org/util.h ruby-1.3/util.h
--- ruby-1.3_org/util.h	Tue Oct 06 12:28:17 1998
+++ ruby-1.3/util.h	Fri Jan 15 21:07:04 1999
@@ -27,7 +27,7 @@
 
 #if defined(MSDOS) || defined(__CYGWIN32__) || defined(NT)
 #define add_suffix ruby_add_suffix
-void add_suffix();
+void rb_add_suffix _((VALUE, char*));
 #endif
 
 char *ruby_mktemp _((void));
diff -iNu ruby-1.3_org/variable.c ruby-1.3/variable.c
--- ruby-1.3_org/variable.c	Thu Dec 24 14:08:47 1998
+++ ruby-1.3/variable.c	Mon Jan 11 15:20:02 1999
@@ -594,6 +594,7 @@
 	(*trace->func)(trace->data, data->val);
 	trace = trace->next;
     }
+	return Qnil;
 }
 
 static VALUE
@@ -602,6 +603,7 @@
 {
     entry->block_trace = 0;
     remove_trace(entry);
+	return Qnil;
 }
 
 VALUE
@@ -973,6 +975,7 @@
 	     RSTRING(rb_class_path(klass))->ptr,
 	     rb_id2name(id));
     /* not reached */
+	return Qnil;
 }
 
 
@@ -1019,6 +1022,7 @@
 	rb_raise(rb_eNameError, "Uninitialized constant %s",rb_id2name(id));
     }
     /* not reached */
+	return Qnil;
 }
 
 static int
@@ -1056,6 +1060,7 @@
     }
     rb_raise(rb_eNameError, "constant %s::%s not defined", 
 	     rb_class2name(mod), rb_id2name(id));
+	return Qnil;
 }
 
 static int
diff -iNu ruby-1.3_org/missing/nt.c ruby-1.3/missing/nt.c
--- ruby-1.3_org/missing/nt.c	Thu Dec 24 13:44:10 1998
+++ ruby-1.3/missing/nt.c	Sun Jan 17 22:03:40 1999
@@ -1,2210 +1,2203 @@
-/*
- *  Copyright (c) 1993, Intergraph Corporation
- *
- *  You may distribute under the terms of either the GNU General Public
- *  License or the Artistic License, as specified in the perl README file.
- *
- *  Various Unix compatibility functions and NT specific functions.
- *
- *  Some of this code was derived from the MSDOS port(s) and the OS/2 port.
- *
- */
-
-#include "ruby.h"
-#include <fcntl.h>
-#include <process.h>
-#include <sys/stat.h>
-/* #include <sys/wait.h> */
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-
-#include <windows.h>
-#include <winbase.h>
-#include <wincon.h>
-#include "nt.h"
-#include "dir.h"
-#ifndef index
-#define index(x, y) strchr((x), (y))
-#endif
-
-#ifndef bool
-#define bool int
-#endif
-
-bool NtSyncProcess = TRUE;
-#if 0  // declared in header file
-extern char **environ;
-#define environ _environ
-#endif
-
-static bool NtHasRedirection (char *);
-static int valid_filename(char *s);
-static void StartSockets ();
-static char *str_grow(struct RString *str, size_t new_size);
-
-char *NTLoginName;
-
-DWORD Win32System = (DWORD)-1;
-
-static DWORD
-IdOS(void)
-{
-    static OSVERSIONINFO osver;
-
-    if (osver.dwPlatformId != Win32System) {
-	memset(&osver, 0, sizeof(OSVERSIONINFO));
-	osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-	GetVersionEx(&osver);
-	Win32System = osver.dwPlatformId;
-    }
-    return (Win32System);
-}
-
-static int 
-IsWin95(void) {
-    return (IdOS() == VER_PLATFORM_WIN32_WINDOWS);
-}
-
-static int
-IsWinNT(void) {
-    return (IdOS() == VER_PLATFORM_WIN32_NT);
-}
-
-
-/* simulate flock by locking a range on the file */
-
-
-#define LK_ERR(f,i) ((f) ? (i = 0) : (errno = GetLastError()))
-#define LK_LEN      0xffff0000
-
-int
-flock(int fd, int oper)
-{
-    OVERLAPPED o;
-    int i = -1;
-    HANDLE fh;
-
-    fh = (HANDLE)_get_osfhandle(fd);
-    memset(&o, 0, sizeof(o));
-
-    if(IsWinNT()) {
-        switch(oper) {
-        case LOCK_SH:       /* shared lock */
-            LK_ERR(LockFileEx(fh, 0, 0, LK_LEN, 0, &o),i);
-            break;
-        case LOCK_EX:       /* exclusive lock */
-            LK_ERR(LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, 0, &o),i);
-            break;
-        case LOCK_SH|LOCK_NB:   /* non-blocking shared lock */
-            LK_ERR(LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, 0, &o),i);
-            break;
-        case LOCK_EX|LOCK_NB:   /* non-blocking exclusive lock */
-            LK_ERR(LockFileEx(fh,
-                   LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
-                   0, LK_LEN, 0, &o),i);
-	    if(errno == EDOM) errno = EWOULDBLOCK;
-            break;
-        case LOCK_UN:       /* unlock lock */
-	    if (UnlockFileEx(fh, 0, LK_LEN, 0, &o)) {
-		i = 0;
-	    }
-	    else {
-		/* GetLastError() must returns `ERROR_NOT_LOCKED' */
-		errno = EWOULDBLOCK;
-	    }
-	    if(errno == EDOM) errno = EWOULDBLOCK;
-            break;
-        default:            /* unknown */
-            errno = EINVAL;
-            break;
-        }
-    }
-    else if(IsWin95()) {
-        switch(oper) {
-        case LOCK_EX:
-	    while(i == -1) {
-	        LK_ERR(LockFile(fh, 0, 0, LK_LEN, 0), i);
-		if(errno != EDOM && i == -1) break;
-	    }
-	    break;
-	case LOCK_EX | LOCK_NB:
-	    LK_ERR(LockFile(fh, 0, 0, LK_LEN, 0), i);
-	    if(errno == EDOM) errno = EWOULDBLOCK;
-            break;
-        case LOCK_UN:
-            LK_ERR(UnlockFile(fh, 0, 0, LK_LEN, 0), i);
-	    if(errno == EDOM) errno = EWOULDBLOCK;
-            break;
-        default:
-            errno = EINVAL;
-            break;
-        }
-    }
-    return i;
-}
-
-#undef LK_ERR
-#undef LK_LEN
-
-
-//#undef const
-//FILE *fdopen(int, const char *);
-
-#if 0
-void
-sleep(unsigned int len)
-{
-	time_t end;
-
-	end = time((time_t *)0) + len;
-	while (time((time_t *)0) < end)
-		;
-}
-#endif
-
-//
-// Initialization stuff
-//
-void
-NtInitialize(int *argc, char ***argv) {
-
-    WORD version;
-    int ret;
-
-    //
-    // subvert cmd.exe\'s feeble attempt at command line parsing
-    //
-    *argc = NtMakeCmdVector((char *)GetCommandLine(), argv, TRUE);
-
-    //
-    // Now set up the correct time stuff
-    //
-
-    tzset();
-
-    // Initialize Winsock
-    StartSockets();
-}
-
-
-char *getlogin()
-{
-    char buffer[200];
-    int len = 200;
-    extern char *NTLoginName;
-
-    if (NTLoginName == NULL) {
-	if (GetUserName(buffer, &len)) {
-	    NTLoginName = ALLOC_N(char, len+1);
-	    strncpy(NTLoginName, buffer, len);
-	    NTLoginName[len] = '\0';
-	}
-	else {
-	    NTLoginName = "<Unknown>";
-	}
-    }
-    return NTLoginName;
-}
-
-
-
-#if 1
-// popen stuff
-
-//
-// use these so I can remember which index is which
-//
-
-#define NtPipeRead  0	   // index of pipe read descriptor
-#define NtPipeWrite 1	   // index of pipe write descriptor
-
-#define NtPipeSize  1024   // size of pipe buffer
-
-#define MYPOPENSIZE 256	   // size of book keeping structure
-
-struct {
-    int inuse;
-    int pid;
-    HANDLE oshandle;
-    FILE *pipe;
-} MyPopenRecord[MYPOPENSIZE];
-
-int SafeFree(char **vec, int vecc)
-{
-    //   vec
-    //   |
-    //   V       ^---------------------V
-    //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
-    //   |   |       | ....  |  NULL |   | ..... |\0 |   | ..... |\0 |...
-    //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
-    //   |-  elements+1             -| ^ 1st element   ^ 2nd element
-
-	char *p;
-
-	p = (char *)vec;
-	free(p);
-
-	return 0;
-}
-
-
-static char *szInternalCmds[] = {
-  "append",
-  "break",
-  "call",
-  "cd",
-  "chdir",
-  "cls",
-  "copy",
-  "date",
-  "del",
-  "dir",
-  "echo",
-  "erase",
-  "label",
-  "md",
-  "mkdir",
-  "path",
-  "pause",
-  "rd",
-  "rem",
-  "ren",
-  "rename",
-  "rmdir",
-  "set",
-  "start",
-  "time",
-  "type",
-  "ver",
-  "vol",
-  NULL
-};
-
-int
-isInternalCmd(char *cmd)
-{
-#if 0
-        return 0;
-#else
-        int i, fRet=0;
-	char **vec;
-        int vecc = NtMakeCmdVector(cmd, &vec, FALSE);
-
-        for( i = 0; szInternalCmds[i] ; i++){
-	    if(!strcmp(szInternalCmds[i], vec[0])){
-		fRet = 1;
-		break;
-	    }
-        }
- 
-	SafeFree (vec, vecc);
-
-	return fRet;
-#endif
-}
-
-
-FILE *
-mypopen (char *cmd, char *mode) 
-{
-    FILE *fp;
-    int saved, reading;
-    int pipemode;
-    int pipes[2];
-    int pid;
-    int slot;
-    static initialized = 0;
-
-    //
-    // if first time through, intialize our book keeping structure
-    //
-
-    if (!initialized++) {
-	for (slot = 0; slot < MYPOPENSIZE; slot++)
-	    MyPopenRecord[slot].inuse = FALSE;
-    }
-
-    //printf("mypopen %s\n", cmd);
-    
-    //
-    // find a free popen slot
-    //
-
-    for (slot = 0; slot < MYPOPENSIZE && MyPopenRecord[slot].inuse; slot++)
-	;
-
-    if (slot > MYPOPENSIZE) {
-	return NULL;
-    }
-
-    //
-    // Figure out what we\'re doing...
-    //
-
-    reading = (*mode == 'r') ? TRUE : FALSE;
-    pipemode = (*(mode+1) == 'b') ? O_BINARY : O_TEXT;
-
-    //
-    // Now get a pipe
-    //
-
-#if 0    
-    if (_pipe(pipes, NtPipeSize, pipemode) == -1) {
-	return NULL;
-    }
-
-    if (reading) {
-
-	//
-	// we\'re reading from the pipe, so we must hook up the
-	// write end of the pipe to the new processes stdout.
-	// To do this we must save our file handle from stdout
-	// by _dup\'ing it, then setting our stdout to be the pipe\'s 
-	// write descriptor. We must also make the write handle 
-	// inheritable so the new process can use it.
-
-	if ((saved = _dup(fileno(stdout))) == -1) {
-	    _close(pipes[NtPipeRead]);
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
-	if (_dup2 (pipes[NtPipeWrite], fileno(stdout)) == -1) {
-	    _close(pipes[NtPipeRead]);
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
-    }
-    else {
-	//
-	// must be writing to the new process. Do the opposite of
-	// the above, i.e. hook up the processes stdin to the read
-	// end of the pipe.
-	//
-
-	if ((saved = _dup(fileno(stdin))) == -1) {
-	    _close(pipes[NtPipeRead]);
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
-	if (_dup2(pipes[NtPipeRead], fileno(stdin)) == -1) {
-	    _close(pipes[NtPipeRead]);
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
-    }
-
-    //
-    // Start the new process. Must set _fileinfo to non-zero value
-    // for file descriptors to be inherited. Reset after the process
-    // is started.
-    //
-
-    if (NtHasRedirection(cmd)) {
-      docmd:
-	pid = spawnlpe(_P_NOWAIT, "cmd.exe", "/c", cmd, 0, environ);
-	if (pid == -1) {
-	    _close(pipes[NtPipeRead]);
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
-    }
-    else {
-	char **vec;
-	int vecc = NtMakeCmdVector(cmd, &vec, FALSE);
-
-	//pid = spawnvpe (_P_NOWAIT, vec[0], vec, environ);
-	pid = spawnvpe (_P_WAIT, vec[0], vec, environ);
-	if (pid == -1) {
-	    goto docmd;
-	}
-		Safefree (vec, vecc);
-    }
-
-    if (reading) {
-
-	//
-	// We need to close our instance of the inherited pipe write
-	// handle now that it's been inherited so that it will actually close
-	// when the child process ends.
-	//
-
-	if (_close(pipes[NtPipeWrite]) == -1) {
-	    _close(pipes[NtPipeRead]);
-	    return NULL;
-	}
-	if (_dup2 (saved, fileno(stdout)) == -1) {
-	    _close(pipes[NtPipeRead]);
-	    return NULL;
-	}
-	_close(saved);
-
-	// 
-	// Now get a stream pointer to return to the calling program.
-	//
-
-	if ((fp = (FILE *) fdopen(pipes[NtPipeRead], mode)) == NULL) {
-	    return NULL;
-	}
-    }
-    else {
-
-	//
-	// need to close our read end of the pipe so that it will go 
-	// away when the write end is closed.
-	//
-
-	if (_close(pipes[NtPipeRead]) == -1) {
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
-	if (_dup2 (saved, fileno(stdin)) == -1) {
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
-	_close(saved);
-
-	// 
-	// Now get a stream pointer to return to the calling program.
-	//
-
-	if ((fp = (FILE *) fdopen(pipes[NtPipeWrite], mode)) == NULL) {
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
-    }
-
-    //
-    // do the book keeping
-    //
-
-    MyPopenRecord[slot].inuse = TRUE;
-    MyPopenRecord[slot].pipe = fp;
-    MyPopenRecord[slot].pid = pid;
-
-    return fp;
-#else
-    {
-		int p[2];
-
-		BOOL fRet;
-		HANDLE hInFile, hOutFile, hStdin, hStdout;
-		LPCSTR lpApplicationName = NULL;
-		LPTSTR lpCommandLine;
-		LPTSTR lpCmd2 = NULL;
-		DWORD  dwCreationFlags;
-		STARTUPINFO aStartupInfo;
-		PROCESS_INFORMATION     aProcessInformation;
-		SECURITY_ATTRIBUTES sa;
-		int fd;
-
-		sa.nLength              = sizeof (SECURITY_ATTRIBUTES);
-		sa.lpSecurityDescriptor = NULL;
-		sa.bInheritHandle       = TRUE;
-
-		if (!reading) {
-        	FILE *fp;
-
-			fp = (_popen)(cmd, mode);
-
-			MyPopenRecord[slot].inuse = TRUE;
-			MyPopenRecord[slot].pipe = fp;
-			MyPopenRecord[slot].pid = -1;
-
-			if (!fp)
-                        rb_fatal("cannot open pipe \"%s\" (%s)", cmd, strerror(errno));
-				return fp;
-		}
-
-		fRet = CreatePipe(&hInFile, &hOutFile, &sa, 2048L);
-		if (!fRet)
-                        rb_fatal("cannot open pipe \"%s\" (%s)", cmd, strerror(errno));
-
-		memset(&aStartupInfo, 0, sizeof (STARTUPINFO));
-		memset(&aProcessInformation, 0, sizeof (PROCESS_INFORMATION));
-		aStartupInfo.cb = sizeof (STARTUPINFO);
-		aStartupInfo.dwFlags    = STARTF_USESTDHANDLES;
-
-		if (reading) {
-			aStartupInfo.hStdInput  = GetStdHandle(STD_OUTPUT_HANDLE);//hStdin;
-			aStartupInfo.hStdError  = INVALID_HANDLE_VALUE;
-			//for save
-			DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE),
-			  GetCurrentProcess(), &hStdout,
-			  0, FALSE, DUPLICATE_SAME_ACCESS
-			);
-			//for redirect
-			DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE),
-			  GetCurrentProcess(), &hStdin,
-			  0, TRUE, DUPLICATE_SAME_ACCESS
-			);
-			aStartupInfo.hStdOutput = hOutFile;
-		}
-		else {
-			aStartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); //hStdout;
-			aStartupInfo.hStdError  = INVALID_HANDLE_VALUE;
-			// for save
-			DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE),
-			  GetCurrentProcess(), &hStdin,
-			  0, FALSE, DUPLICATE_SAME_ACCESS
-			);
-			//for redirect
-			DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE),
-			  GetCurrentProcess(), &hStdout,
-			  0, TRUE, DUPLICATE_SAME_ACCESS
-			);
-			aStartupInfo.hStdInput = hInFile;
-		}
-
-		dwCreationFlags = (NORMAL_PRIORITY_CLASS);
-
-		lpCommandLine = cmd;
-		if (NtHasRedirection(cmd) || isInternalCmd(cmd)) {
-		  lpApplicationName = getenv("COMSPEC");
-		  lpCmd2 = malloc(strlen(lpApplicationName) + 1 + strlen(cmd) + sizeof (" /c "));
-		  if (lpCmd2 == NULL)
-                     rb_fatal("Mypopen: malloc failed");
-		  sprintf(lpCmd2, "%s %s%s", lpApplicationName, " /c ", cmd);
-		  lpCommandLine = lpCmd2;
-		}
-
-		fRet = CreateProcess(lpApplicationName, lpCommandLine, &sa, &sa,
-			sa.bInheritHandle, dwCreationFlags, NULL, NULL, &aStartupInfo, &aProcessInformation);
-
-		if (!fRet) {
-			CloseHandle(hInFile);
-			CloseHandle(hOutFile);
-                        rb_fatal("cannot fork for \"%s\" (%s)", cmd, strerror(errno));
-		}
-
-		CloseHandle(aProcessInformation.hThread);
-
-		if (reading) {
-			HANDLE hDummy;
-
-			fd = _open_osfhandle((long)hInFile,  (_O_RDONLY | pipemode));
-			CloseHandle(hOutFile);
-			DuplicateHandle(GetCurrentProcess(), hStdout,
-			  GetCurrentProcess(), &hDummy,
-			  0, TRUE, (DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)
-			);
-		}
-		else {
-			HANDLE hDummy;
-
-		    fd = _open_osfhandle((long)hOutFile, (_O_WRONLY | pipemode));
-			CloseHandle(hInFile);
-			DuplicateHandle(GetCurrentProcess(), hStdin,
-			  GetCurrentProcess(), &hDummy,
-			  0, TRUE, (DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)
-			);
-		}
-
-		if (fd == -1) 
-                  rb_fatal("cannot open pipe \"%s\" (%s)", cmd, strerror(errno));
-
-
-		if ((fp = (FILE *) fdopen(fd, mode)) == NULL)
-			return NULL;
-
-		if (lpCmd2)
-			free(lpCmd2);
-
-		MyPopenRecord[slot].inuse = TRUE;
-		MyPopenRecord[slot].pipe  = fp;
-		MyPopenRecord[slot].oshandle = (reading ? hInFile : hOutFile);
-		MyPopenRecord[slot].pid   = (int)aProcessInformation.hProcess;
-		return fp;
-    }
-#endif
-}
-
-int
-mypclose(FILE *fp)
-{
-    int i;
-    int exitcode;
-
-    Sleep(100);
-    for (i = 0; i < MYPOPENSIZE; i++) {
-	if (MyPopenRecord[i].inuse && MyPopenRecord[i].pipe == fp)
-	    break;
-    }
-    if (i >= MYPOPENSIZE) {
-                rb_fatal("Invalid file pointer passed to mypclose!\n");
-    }
-
-    //
-    // get the return status of the process
-    //
-
-#if 0
-    if (_cwait(&exitcode, MyPopenRecord[i].pid, WAIT_CHILD) == -1) {
-	if (errno == ECHILD) {
-	    fprintf(stderr, "mypclose: nosuch child as pid %x\n", 
-		    MyPopenRecord[i].pid);
-	}
-    }
-#else
-	for (;;) {
-		if (GetExitCodeProcess((HANDLE)MyPopenRecord[i].pid, &exitcode)) {
-			if (exitcode == STILL_ACTIVE) {
-				//printf("Process is Active.\n");
-				Sleep(100);
-				TerminateProcess((HANDLE)MyPopenRecord[i].pid, 0); // ugly...
-				continue;
-			}
-			else if (exitcode == 0) {
-				//printf("done.\n");
-				break;
-			}
-			else {
-				//printf("never.\n");
-				break;
-			}
-		}
-	}
-#endif
-
-
-    //
-    // close the pipe
-    //
-    CloseHandle(MyPopenRecord[i].oshandle);
-    fflush(fp);
-    fclose(fp);
-
-    //
-    // free this slot
-    //
-
-    MyPopenRecord[i].inuse = FALSE;
-    MyPopenRecord[i].pipe  = NULL;
-    MyPopenRecord[i].pid   = 0;
-
-    return exitcode;
-}
-#endif
-
-#if 1
-
-
-typedef char* CHARP;
-/*
- * The following code is based on the do_exec and do_aexec functions
- * in file doio.c
- */
-
-int
-do_spawn(cmd)
-char *cmd;
-{
-    register char **a;
-    register char *s;
-    char **argv;
-    int status;
-    char *shell, *cmd2;
-    int mode = NtSyncProcess ? P_WAIT : P_NOWAIT;
-
-    /* save an extra exec if possible */
-    if ((shell = getenv("RUBYSHELL")) != 0) {
-	if (NtHasRedirection(cmd)) {
-	    int  i;
-	    char *p;
-	    char *argv[4];
-	    char *cmdline = ALLOC_N(char, (strlen(cmd) * 2 + 1));
-
-	    p=cmdline;           
-	    *p++ = '"';
-	    for (s=cmd; *s;) {
-		if (*s == '"') 
-		    *p++ = '\\'; /* Escape d-quote */
-		*p++ = *s++;
-	    }
-	    *p++ = '"';
-	    *p   = '\0';
-
-	    /* fprintf(stderr, "do_spawn: %s %s\n", shell, cmdline); */
-	    argv[0] = shell;
-	    argv[1] = "-c";
-	    argv[2] = cmdline;
-	    argv[4] = NULL;
-	    status = spawnvpe(mode, argv[0], argv, environ);
-	    /* return spawnle(mode, shell, shell, "-c", cmd, (char*)0, environ); */
-	    free(cmdline);
-	    return status;
-	} 
-    }
-    else if ((shell = getenv("COMSPEC")) != 0) {
-	if (NtHasRedirection(cmd) /* || isInternalCmd(cmd) */) {
-	  do_comspec_shell:
-	    return spawnle(mode, shell, shell, "/c", cmd, (char*)0, environ);
-	}
-    }
-
-    argv = ALLOC_N(CHARP, (strlen(cmd) / 2 + 2));
-    cmd2 = ALLOC_N(char, (strlen(cmd) + 1));
-    strcpy(cmd2, cmd);
-    a = argv;
-    for (s = cmd2; *s;) {
-	while (*s && isspace(*s)) s++;
-	if (*s)
-	    *(a++) = s;
-	while (*s && !isspace(*s)) s++;
-	if (*s)
-	    *s++ = '\0';
-    }
-    *a = NULL;
-    if (argv[0]) {
-	if ((status = spawnvpe(mode, argv[0], argv, environ)) == -1) {
-	    free(argv);
-	    free(cmd2);
-	    return -1;
-	}
-    }
-    free(cmd2);
-    free(argv);
-    return status;
-}
-
-#endif
-
-typedef struct _NtCmdLineElement {
-    struct _NtCmdLineElement *next, *prev;
-    char *str;
-    int len;
-    int flags;
-} NtCmdLineElement;
-
-//
-// Possible values for flags
-//
-
-#define NTGLOB   0x1	// element contains a wildcard
-#define NTMALLOC 0x2	// string in element was malloc'ed
-#define NTSTRING 0x4	// element contains a quoted string
-
-NtCmdLineElement *NtCmdHead = NULL, *NtCmdTail = NULL;
-
-void
-NtFreeCmdLine(void)
-{
-    NtCmdLineElement *ptr;
-    
-    while(NtCmdHead) {
-	ptr = NtCmdHead;
-	NtCmdHead = NtCmdHead->next;
-	free(ptr);
-    }
-    NtCmdHead = NtCmdTail = NULL;
-}
-
-//
-// This function expands wild card characters that were spotted 
-// during the parse phase. The idea here is to call FindFirstFile and
-// FindNextFile with the wildcard pattern specified, and splice in the
-// resulting list of new names. If the wildcard pattern doesn\'t match 
-// any existing files, just leave it in the list.
-//
-
-void
-NtCmdGlob (NtCmdLineElement *patt)
-{
-    WIN32_FIND_DATA fd;
-    HANDLE fh;
-    char buffer[512];
-    NtCmdLineElement *tmphead, *tmptail, *tmpcurr;
-
-    strncpy(buffer, patt->str, patt->len);
-    buffer[patt->len] = '\0';
-    if ((fh = FindFirstFile (buffer, &fd)) == INVALID_HANDLE_VALUE) {
-	return;
-    }
-    tmphead = tmptail = NULL;
-    do {
-	tmpcurr = ALLOC(NtCmdLineElement);
-	if (tmpcurr == NULL) {
-	    fprintf(stderr, "Out of Memory in globbing!\n");
-	    while (tmphead) {
-		tmpcurr = tmphead;
-		tmphead = tmphead->next;
-		free(tmpcurr->str);
-		free(tmpcurr);
-	    }
-	    return;
-	}
-	memset (tmpcurr, 0, sizeof(*tmpcurr));
-	tmpcurr->len = strlen(fd.cFileName);
-	tmpcurr->str = ALLOC_N(char, tmpcurr->len+1);
-	if (tmpcurr->str == NULL) {
-	    fprintf(stderr, "Out of Memory in globbing!\n");
-	    while (tmphead) {
-		tmpcurr = tmphead;
-		tmphead = tmphead->next;
-		free(tmpcurr->str);
-		free(tmpcurr);
-	    }
-	    return;
-	}
-	strcpy(tmpcurr->str, fd.cFileName);
-	tmpcurr->flags |= NTMALLOC;
-	if (tmptail) {
-	    tmptail->next = tmpcurr;
-	    tmpcurr->prev = tmptail;
-	    tmptail = tmpcurr;
-	}
-	else {
-	    tmptail = tmphead = tmpcurr;
-	}
-    } while(FindNextFile(fh, &fd));
-
-    //
-    // ok, now we\'ve got a list of files that matched the wildcard
-    // specification. Put it in place of the pattern structure.
-    //
-    
-    tmphead->prev = patt->prev;
-    tmptail->next = patt->next;
-
-    if (tmphead->prev)
-	tmphead->prev->next = tmphead;
-
-    if (tmptail->next)
-	tmptail->next->prev = tmptail;
-
-    //
-    // Now get rid of the pattern structure
-    //
-
-    if (patt->flags & NTMALLOC)
-	free(patt->str);
-    // free(patt);  //TODO:  memory leak occures here. we have to fix it.
-}
-
-// 
-// Check a command string to determine if it has I/O redirection
-// characters that require it to be executed by a command interpreter
-//
-
-static bool
-NtHasRedirection (char *cmd)
-{
-    int inquote = 0;
-    char quote = '\0';
-    char *ptr ;
-    
-    //
-    // Scan the string, looking for redirection (< or >) or pipe 
-    // characters (|) that are not in a quoted string
-    //
-
-    for (ptr = cmd; *ptr; ptr++) {
-
-	switch (*ptr) {
-
-	  case '\'':
-	  case '\"':
-	    if (inquote) {
-		if (quote == *ptr) {
-		    inquote = 0;
-		    quote = '\0';
-		}
-	    }
-	    else {
-		quote = *ptr;
-		inquote++;
-	    }
-	    break;
-
-	  case '>':
-	  case '<':
-
-	    if (!inquote)
-		return TRUE;
-	}
-    }
-    return FALSE;
-}
-
-
-int 
-NtMakeCmdVector (char *cmdline, char ***vec, int InputCmd)
-{
-    int cmdlen = strlen(cmdline);
-    int done, instring, globbing, quoted, len;
-    int newline, need_free = 0, i;
-    int elements, strsz;
-    int slashes = 0;
-    char *ptr, *base, *buffer;
-    char **vptr;
-    char quote;
-    NtCmdLineElement *curr;
-
-    //
-    // just return if we don\'t have a command line
-    //
-
-    if (cmdlen == 0) {
-	*vec = NULL;
-	return 0;
-    }
-
-    //
-    // strip trailing white space
-    //
-
-    ptr = cmdline+(cmdlen - 1);
-    while(ptr >= cmdline && isspace(*ptr))
-        --ptr;
-    *++ptr = '\0';
-
-    //
-    // check for newlines and formfeeds. If we find any, make a new
-    // command string that replaces them with escaped sequences (\n or \f)
-    //
-
-    for (ptr = cmdline, newline = 0; *ptr; ptr++) {
-	if (*ptr == '\n' || *ptr == '\f')
-	    newline++;
-    }
-
-    if (newline) {
-	base = ALLOC_N(char, strlen(cmdline) + 1 + newline + slashes);
-	if (base == NULL) {
-	    fprintf(stderr, "malloc failed!\n");
-	    return 0;
-	}
-	for (i = 0, ptr = base; (unsigned) i < strlen(cmdline); i++) {
-	    switch (cmdline[i]) {
-	      case '\n':
-		*ptr++ = '\\';
-		*ptr++ = 'n';
-		break;
-	      default:
-		*ptr++ = cmdline[i];
-	    }
-	}
-	*ptr = '\0';
-	cmdline = base;
-	need_free++;
-    }
-
-    //
-    // Ok, parse the command line, building a list of CmdLineElements.
-    // When we\'ve finished, and it\'s an input command (meaning that it\'s
-    // the processes argv), we\'ll do globing and then build the argument 
-    // vector.
-    // The outer loop does one interation for each element seen. 
-    // The inner loop does one interation for each character in the element.
-    //
-
-    for (done = 0, ptr = cmdline; *ptr;) {
-
-	//
-	// zap any leading whitespace
-	//
-
-	while(isspace(*ptr))
-	    ptr++;
-	base = ptr;
-
-	for (done = newline = globbing = instring = quoted = 0; 
-	     *ptr && !done; ptr++) {
-
-	    //
-	    // Switch on the current character. We only care about the
-	    // white-space characters, the  wild-card characters, and the
-	    // quote characters.
-	    //
-
-	    switch (*ptr) {
-	      case ' ':
-	      case '\t':
-#if 0
-	      case '/':  // have to do this for NT/DOS option strings
-
-		//
-		// check to see if we\'re parsing an option switch
-		//
-
-		if (*ptr == '/' && base == ptr)
-		    continue;
-#endif
-		//
-		// if we\'re not in a string, then we\'re finished with this
-		// element
-		//
-
-		if (!instring)
-		    done++;
-		break;
-
-	      case '*':
-	      case '?':
-
-		// 
-		// record the fact that this element has a wildcard character
-		// N.B. Don\'t glob if inside a single quoted string
-		//
-
-		if (!(instring && quote == '\''))
-		    globbing++;
-		break;
-
-	      case '\n':
-
-		//
-		// If this string contains a newline, mark it as such so
-		// we can replace it with the two character sequence "\n"
-		// (cmd.exe doesn\'t like raw newlines in strings...sigh).
-		//
-
-		newline++;
-		break;
-
-	      case '\'':
-	      case '\"':
-
-		//
-		// if we\'re already in a string, see if this is the
-		// terminating close-quote. If it is, we\'re finished with 
-		// the string, but not neccessarily with the element.
-		// If we\'re not already in a string, start one.
-		//
-
-		if (instring) {
-		    if (quote == *ptr) {
-			instring = 0;
-			quote = '\0';
-		    }
-		}
-		else {
-		    instring++;
-		    quote = *ptr;
-		    quoted++;
-		}
-		break;
-	    }
-	}
-
-	//
-	// need to back up ptr by one due to last increment of for loop
-	// (if we got out by seeing white space)
-	//
-
-	if (*ptr)
-	    ptr--;
-
-	//
-	// when we get here, we\'ve got a pair of pointers to the element,
-	// base and ptr. Base points to the start of the element while ptr
-	// points to the character following the element.
-	//
-
-	curr = ALLOC(NtCmdLineElement);
-	if (curr == NULL) {
-	    NtFreeCmdLine();
-	    fprintf(stderr, "Out of memory!!\n");
-	    *vec = NULL;
-	    return 0;
-	}
-	memset (curr, 0, sizeof(*curr));
-
-	len = ptr - base;
-
-	//
-	// if it\'s an input vector element and it\'s enclosed by quotes, 
-	// we can remove them.
-	//
-
-	if (InputCmd &&
-	    ((base[0] == '\"' && base[len-1] == '\"') ||
-	     (base[0] == '\'' && base[len-1] == '\''))) {
-	    base++;
-	    len -= 2;
-	}
-
-	curr->str = base;
-	curr->len = len;
-	curr->flags |= (globbing ? NTGLOB : 0);
-
-	//
-	// Now put it in the list of elements
-	//
-	if (NtCmdTail) {
-	    NtCmdTail->next = curr;
-	    curr->prev = NtCmdTail;
-	    NtCmdTail = curr;
-	}
-	else {
-	    NtCmdHead = NtCmdTail = curr;
-	}
-    }
-
-    if (InputCmd) {
-
-	//
-	// When we get here we\'ve finished parsing the command line. Now 
-	// we need to run the list, expanding any globbing patterns.
-	//
-	
-	for(curr = NtCmdHead; curr; curr = curr->next) {
-	    if (curr->flags & NTGLOB) {
-		NtCmdGlob(curr);
-	    }
-	}
-    }
-
-    //
-    // Almost done! 
-    // Count up the elements, then allocate space for a vector of pointers
-    // (argv) and a string table for the elements.
-    // 
-
-    for (elements = 0, strsz = 0, curr = NtCmdHead; curr; curr = curr->next) {
-	elements++;
-	strsz += (curr->len + 1);
-    }
-
-    len = (elements+1)*sizeof(char *) + strsz;
-    buffer = ALLOC_N(char, len);
-    if (buffer == NULL) {
-	fprintf(stderr, "Out of memory!!\n");
-	NtFreeCmdLine();
-	*vec = NULL;
-	return 0;
-    }
-    
-    memset (buffer, 0, len);
-
-    //
-    // make vptr point to the start of the buffer
-    // and ptr point to the area we\'ll consider the string table.
-    //
-    //   buffer (*vec)
-    //   |
-    //   V       ^---------------------V
-    //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
-    //   |   |       | ....  | NULL  |   | ..... |\0 |   | ..... |\0 |...
-    //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
-    //   |-  elements+1             -| ^ 1st element   ^ 2nd element
-
-    vptr = (char **) buffer;
-
-    ptr = buffer + (elements+1) * sizeof(char *);
-
-    for (curr =  NtCmdHead; curr;  curr = curr->next) {
-	strncpy (ptr, curr->str, curr->len);
-	ptr[curr->len] = '\0';
-	*vptr++ = ptr;
-	ptr += curr->len + 1;
-    }
-    NtFreeCmdLine();
-    *vec = (char **) buffer;
-    return elements;
-}
-
-
-#if 1
-//
-// UNIX compatible directory access functions for NT
-//
-
-//
-// File names are converted to lowercase if the
-// CONVERT_TO_LOWER_CASE variable is defined.
-//
-
-#define CONVERT_TO_LOWER_CASE
-#define PATHLEN 1024
-
-//
-// The idea here is to read all the directory names into a string table
-// (separated by nulls) and when one of the other dir functions is called
-// return the pointer to the current file name. 
-//
-
-DIR *
-opendir(char *filename)
-{
-    DIR            *p;
-    long            len;
-    long            idx;
-    char            scannamespc[PATHLEN];
-    char	   *scanname = scannamespc;
-    struct stat	    sbuf;
-    WIN32_FIND_DATA FindData;
-    HANDLE          fh;
-    char            root[PATHLEN];
-    char            volname[PATHLEN];
-    DWORD           serial, maxname, flags;
-    BOOL            downcase;
-    char           *dummy;
-
-    //
-    // check to see if we\'ve got a directory
-    //
-
-    if (stat (filename, &sbuf) < 0 ||
-	sbuf.st_mode & _S_IFDIR == 0) {
-	return NULL;
-    }
-
-    //
-    // check out the file system characteristics
-    //
-    if (GetFullPathName(filename, PATHLEN, root, &dummy)) {
-	if (dummy = strchr(root, '\\'))
-	    *++dummy = '\0';
-	if (GetVolumeInformation(root, volname, PATHLEN, 
-				 &serial, &maxname, &flags, 0, 0)) {
-	    downcase = !(flags & FS_CASE_SENSITIVE);
-	}
-    }
-    else {
-	downcase = TRUE;
-    }
-
-    //
-    // Get us a DIR structure
-    //
-
-    p = xcalloc(sizeof(DIR), 1);
-    if (p == NULL)
-	return NULL;
-    
-    //
-    // Create the search pattern
-    //
-
-    strcpy(scanname, filename);
-
-    if (index("/\\", *(scanname + strlen(scanname) - 1)) == NULL)
-	strcat(scanname, "/*");
-    else
-	strcat(scanname, "*");
-
-    //
-    // do the FindFirstFile call
-    //
-
-    fh = FindFirstFile (scanname, &FindData);
-    if (fh == INVALID_HANDLE_VALUE) {
-	return NULL;
-    }
-
-    //
-    // now allocate the first part of the string table for the
-    // filenames that we find.
-    //
-
-    idx = strlen(FindData.cFileName)+1;
-    p->start = ALLOC_N(char, idx);
-    strcpy (p->start, FindData.cFileName);
-    if (downcase)
-	strlwr(p->start);
-    p->nfiles++;
-    
-    //
-    // loop finding all the files that match the wildcard
-    // (which should be all of them in this directory!).
-    // the variable idx should point one past the null terminator
-    // of the previous string found.
-    //
-    while (FindNextFile(fh, &FindData)) {
-	len = strlen (FindData.cFileName);
-
-	//
-	// bump the string table size by enough for the
-	// new name and it's null terminator 
-	//
-
-	#define Renew(x, y, z) (x = (z *)realloc(x, y))
-
-	Renew (p->start, idx+len+1, char);
-	if (p->start == NULL) {
-            rb_fatal ("opendir: malloc failed!\n");
-	}
-	strcpy(&p->start[idx], FindData.cFileName);
-	if (downcase) 
-	    strlwr(&p->start[idx]);
-	p->nfiles++;
-	idx += len+1;
-    }
-    FindClose(fh);
-    p->size = idx;
-    p->curr = p->start;
-    return p;
-}
-
-
-//
-// Readdir just returns the current string pointer and bumps the
-// string pointer to the next entry.
-//
-
-struct direct  *
-readdir(DIR *dirp)
-{
-    int         len;
-    static int  dummy = 0;
-
-    if (dirp->curr) {
-
-	//
-	// first set up the structure to return
-	//
-
-	len = strlen(dirp->curr);
-	strcpy(dirp->dirstr.d_name, dirp->curr);
-	dirp->dirstr.d_namlen = len;
-
-	//
-	// Fake inode
-	//
-	dirp->dirstr.d_ino = dummy++;
-
-	//
-	// Now set up for the next call to readdir
-	//
-
-	dirp->curr += len + 1;
-	if (dirp->curr >= (dirp->start + dirp->size)) {
-	    dirp->curr = NULL;
-	}
-
-	return &(dirp->dirstr);
-
-    } else
-	return NULL;
-}
-
-//
-// Telldir returns the current string pointer position
-//
-
-long
-telldir(DIR *dirp)
-{
-	return (long) dirp->curr;	/* ouch! pointer to long cast */
-}
-
-//
-// Seekdir moves the string pointer to a previously saved position
-// (Saved by telldir).
-
-void
-seekdir(DIR *dirp, long loc)
-{
-	dirp->curr = (char *) loc;	/* ouch! long to pointer cast */
-}
-
-//
-// Rewinddir resets the string pointer to the start
-//
-
-void
-rewinddir(DIR *dirp)
-{
-	dirp->curr = dirp->start;
-}
-
-//
-// This just free\'s the memory allocated by opendir
-//
-
-void
-closedir(DIR *dirp)
-{
-	free(dirp->start);
-	free(dirp);
-}
-#endif
-
-
-//
-// 98.2% of this code was lifted from the OS2 port. (JCW)
-//
-
-#if 0
-// add_suffix is in util.c too.
-/*
- * Suffix appending for in-place editing under MS-DOS and OS/2 (and now NT!).
- *
- * Here are the rules:
- *
- * Style 0:  Append the suffix exactly as standard perl would do it.
- *           If the filesystem groks it, use it.  (HPFS will always
- *           grok it.  So will NTFS. FAT will rarely accept it.)
- *
- * Style 1:  The suffix begins with a '.'.  The extension is replaced.
- *           If the name matches the original name, use the fallback method.
- *
- * Style 2:  The suffix is a single character, not a '.'.  Try to add the 
- *           suffix to the following places, using the first one that works.
- *               [1] Append to extension.  
- *               [2] Append to filename, 
- *               [3] Replace end of extension, 
- *               [4] Replace end of filename.
- *           If the name matches the original name, use the fallback method.
- *
- * Style 3:  Any other case:  Ignore the suffix completely and use the
- *           fallback method.
- *
- * Fallback method:  Change the extension to ".$$$".  If that matches the
- *           original name, then change the extension to ".~~~".
- *
- * If filename is more than 1000 characters long, we die a horrible
- * death.  Sorry.
- *
- * The filename restriction is a cheat so that we can use buf[] to store
- * assorted temporary goo.
- *
- * Examples, assuming style 0 failed.
- *
- * suffix = ".bak" (style 1)
- *                foo.bar => foo.bak
- *                foo.bak => foo.$$$	(fallback)
- *                foo.$$$ => foo.~~~	(fallback)
- *                makefile => makefile.bak
- *
- * suffix = "~" (style 2)
- *                foo.c => foo.c~
- *                foo.c~ => foo.c~~
- *                foo.c~~ => foo~.c~~
- *                foo~.c~~ => foo~~.c~~
- *                foo~~~~~.c~~ => foo~~~~~.$$$ (fallback)
- *
- *                foo.pas => foo~.pas
- *                makefile => makefile.~
- *                longname.fil => longname.fi~
- *                longname.fi~ => longnam~.fi~
- *                longnam~.fi~ => longnam~.$$$
- *                
- */
-
-
-static char suffix1[] = ".$$$";
-static char suffix2[] = ".~~~";
-
-#define ext (&buf[1000])
-
-#define strEQ(s1,s2) (strcmp(s1,s2) == 0)
-
-void
-add_suffix(struct RString *str, char *suffix)
-{
-    int baselen;
-    int extlen = strlen(suffix);
-    char *s, *t, *p;
-    int slen;
-    char buf[1024];
-
-    if (str->len > 1000)
-        rb_fatal("Cannot do inplace edit on long filename (%d characters)", str->len);
-
-    /* Style 0 */
-    slen = str->len;
-    str_cat(str, suffix, extlen);
-    if (valid_filename(str->ptr)) return;
-
-    /* Fooey, style 0 failed.  Fix str before continuing. */
-    str->ptr[str->len = slen] = '\0';
-
-    slen = extlen;
-    t = buf; baselen = 0; s = str->ptr;
-    while ( (*t = *s) && *s != '.') {
-	baselen++;
-	if (*s == '\\' || *s == '/') baselen = 0;
- 	s++; t++;
-    }
-    p = t;
-
-    t = ext; extlen = 0;
-    while (*t++ = *s++) extlen++;
-    if (extlen == 0) { ext[0] = '.'; ext[1] = 0; extlen++; }
-
-    if (*suffix == '.') {        /* Style 1 */
-        if (strEQ(ext, suffix)) goto fallback;
-	strcpy(p, suffix);
-    } else if (suffix[1] == '\0') {  /* Style 2 */
-        if (extlen < 4) { 
-	    ext[extlen] = *suffix;
-	    ext[++extlen] = '\0';
-        } else if (baselen < 8) {
-   	    *p++ = *suffix;
-	} else if (ext[3] != *suffix) {
-	    ext[3] = *suffix;
-	} else if (buf[7] != *suffix) {
-	    buf[7] = *suffix;
-	} else goto fallback;
-	strcpy(p, ext);
-    } else { /* Style 3:  Panic */
-fallback:
-	(void)memcpy(p, strEQ(ext, suffix1) ? suffix2 : suffix1, 5);
-    }
-    str_grow(str, strlen(buf));
-    memcpy(str->ptr, buf, str->len);
-}
-#endif
-
-static int 
-valid_filename(char *s)
-{
-    int fd;
-
-    //
-    // if the file exists, then it\'s a valid filename!
-    //
-
-    if (_access(s, 0) == 0) {
-	return 1;
-    }
-
-    //
-    // It doesn\'t exist, so see if we can open it.
-    //
-    
-    if ((fd = _open(s, _O_CREAT, 0666)) >= 0) {
-	close(fd);
-	_unlink (s);	// don\'t leave it laying around
-	return 1;
-    }
-    return 0;
-}
-
-
-//
-// This is a clone of fdopen so that we can handle the 
-// brain damaged version of sockets that NT gets to use.
-//
-// The problem is that sockets are not real file handles and 
-// cannot be fdopen\'ed. This causes problems in the do_socket
-// routine in doio.c, since it tries to create two file pointers
-// for the socket just created. We\'ll fake out an fdopen and see
-// if we can prevent perl from trying to do stdio on sockets.
-//
-
-FILE *
-myfdopen (int fd, const char *mode)
-{
-    FILE *fp;
-    char sockbuf[80];
-    int optlen;
-    int retval;
-    extern int errno;
-
-    //fprintf(stderr, "myfdopen()\n");
-
-    retval = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
-    if (retval == SOCKET_ERROR) {
-	int iRet;
-
-	iRet = WSAGetLastError();
-	if (iRet == WSAENOTSOCK || iRet == WSANOTINITIALISED)
-	return (_fdopen(fd, mode));
-    }
-
-    //
-    // If we get here, then fd is actually a socket.
-    //
-    fp = xcalloc(sizeof(FILE), 1);
-#if _MSC_VER < 800
-    fileno(fp) = fd;
-#else
-    fp->_file = fd;
-#endif
-    if (*mode == 'r')
-	fp->_flag = _IOREAD;
-    else
-	fp->_flag = _IOWRT;
-    return fp;
-}
-
-
-//
-// Since the errors returned by the socket error function 
-// WSAGetLastError() are not known by the library routine strerror
-// we have to roll our own.
-//
-
-#undef strerror
-
-char * 
-mystrerror(int e) 
-{
-    static char buffer[512];
-    extern int sys_nerr;
-    DWORD source = 0;
-
-    if (e < 0 || e > sys_nerr) {
-	if (e < 0)
-	    e = GetLastError();
-	if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, &source, e, 0,
-			  buffer, 512, NULL) == 0) {
-	    strcpy (buffer, "Unknown Error");
-	}
-	return buffer;
-    }
-    return strerror(e);
-	
-}
-
-//
-// various stubs
-//
-
-
-// Ownership
-//
-// Just pretend that everyone is a superuser. NT will let us know if
-// we don\'t really have permission to do something.
-//
-
-#define ROOT_UID	0
-#define ROOT_GID	0
-
-UIDTYPE
-getuid(void)
-{
-	return ROOT_UID;
-}
-
-UIDTYPE
-geteuid(void)
-{
-	return ROOT_UID;
-}
-
-GIDTYPE
-getgid(void)
-{
-	return ROOT_GID;
-}
-
-GIDTYPE
-getegid(void)
-{
-    return ROOT_GID;
-}
-
-int
-setuid(int uid)
-{ 
-    return (uid == ROOT_UID ? 0 : -1);
-}
-
-int
-setgid(int gid)
-{
-    return (gid == ROOT_GID ? 0 : -1);
-}
-
-//
-// File system stuff
-//
-
-int
-/* ioctl(int i, unsigned int u, char *data) */
-ioctl(int i, unsigned int u, long data)
-{
-    return -1;
-}
-
-
-//
-// Networking trampolines
-// These are used to avoid socket startup/shutdown overhead in case 
-// the socket routines aren\'t used.
-//
-
-#undef select
-
-static int NtSocketsInitialized = 0;
-
-long 
-myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
-	       struct timeval *timeout)
-{
-    long r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-
-static void
-StartSockets () {
-    WORD version;
-    WSADATA retdata;
-    int ret;
-    
-    //
-    // initalize the winsock interface and insure that it\'s
-    // cleaned up at exit.
-    //
-    version = MAKEWORD(1, 1);
-    if (ret = WSAStartup(version, &retdata))
-        rb_fatal ("Unable to locate winsock library!\n");
-    if (LOBYTE(retdata.wVersion) != 1)
-        rb_fatal("could not find version 1 of winsock dll\n");
-
-    if (HIBYTE(retdata.wVersion) != 1)
-        rb_fatal("could not find version 1 of winsock dll\n");
-
-    atexit((void (*)(void)) WSACleanup);
-}
-
-#undef accept
-
-SOCKET 
-myaccept (SOCKET s, struct sockaddr *addr, int *addrlen)
-{
-    SOCKET r;
-
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = accept (s, addr, addrlen)) == INVALID_SOCKET)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef bind
-
-int 
-mybind (SOCKET s, struct sockaddr *addr, int addrlen)
-{
-    int r;
-
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = bind (s, addr, addrlen)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef connect
-
-int 
-myconnect (SOCKET s, struct sockaddr *addr, int addrlen)
-{
-    int r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = connect (s, addr, addrlen)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-
-
-#undef getpeername
-
-int 
-mygetpeername (SOCKET s, struct sockaddr *addr, int *addrlen)
-{
-    int r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = getpeername (s, addr, addrlen)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef getsockname
-
-int 
-mygetsockname (SOCKET s, struct sockaddr *addr, int *addrlen)
-{
-    int r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = getsockname (s, addr, addrlen)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef getsockopt
-
-int 
-mygetsockopt (SOCKET s, int level, int optname, char *optval, int *optlen)
-{
-    int r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = getsockopt (s, level, optname, optval, optlen)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef ioctlsocket
-
-int 
-myioctlsocket (SOCKET s, long cmd, u_long *argp)
-{
-    int r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = ioctlsocket (s, cmd, argp)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef listen
-
-int 
-mylisten (SOCKET s, int backlog)
-{
-    int r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = listen (s, backlog)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef recv
-
-int 
-myrecv (SOCKET s, char *buf, int len, int flags)
-{
-    int r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = recv (s, buf, len, flags)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef recvfrom
-
-int 
-myrecvfrom (SOCKET s, char *buf, int len, int flags, 
-		struct sockaddr *from, int *fromlen)
-{
-    int r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = recvfrom (s, buf, len, flags, from, fromlen)) == SOCKET_ERROR)
-	errno =  WSAGetLastError();
-    return r;
-}
-
-#undef send
-
-int 
-mysend (SOCKET s, char *buf, int len, int flags)
-{
-    int r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = send (s, buf, len, flags)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef sendto
-
-int 
-mysendto (SOCKET s, char *buf, int len, int flags, 
-		struct sockaddr *to, int tolen)
-{
-    int r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = sendto (s, buf, len, flags, to, tolen)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef setsockopt
-
-int 
-mysetsockopt (SOCKET s, int level, int optname, char *optval, int optlen)
-{
-    int r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = setsockopt (s, level, optname, optval, optlen)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-    
-#undef shutdown
-
-int 
-myshutdown (SOCKET s, int how)
-{
-    int r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = shutdown (s, how)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef socket
-
-SOCKET 
-mysocket (int af, int type, int protocol)
-{
-    SOCKET s;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((s = socket (af, type, protocol)) == INVALID_SOCKET) {
-	errno = WSAGetLastError();
-	//fprintf(stderr, "socket fail (%d)", WSAGetLastError());
-    }
-    return s;
-}
-
-#undef gethostbyaddr
-
-struct hostent *
-mygethostbyaddr (char *addr, int len, int type)
-{
-    struct hostent *r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = gethostbyaddr (addr, len, type)) == NULL)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef gethostbyname
-
-struct hostent *
-mygethostbyname (char *name)
-{
-    struct hostent *r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = gethostbyname (name)) == NULL)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef gethostname
-
-int
-mygethostname (char *name, int len)
-{
-    int r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = gethostname (name, len)) == SOCKET_ERROR)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef getprotobyname
-
-struct protoent *
-mygetprotobyname (char *name)
-{
-    struct protoent *r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = getprotobyname (name)) == NULL)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef getprotobynumber
-
-struct protoent *
-mygetprotobynumber (int num)
-{
-    struct protoent *r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = getprotobynumber (num)) == NULL)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef getservbyname
-
-struct servent *
-mygetservbyname (char *name, char *proto)
-{
-    struct servent *r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = getservbyname (name, proto)) == NULL)
-	errno = WSAGetLastError();
-    return r;
-}
-
-#undef getservbyport
-
-struct servent *
-mygetservbyport (int port, char *proto)
-{
-    struct servent *r;
-    if (!NtSocketsInitialized++) {
-	StartSockets();
-    }
-    if ((r = getservbyport (port, proto)) == NULL)
-	errno = WSAGetLastError();
-    return r;
-}
-
-//
-// Networking stubs
-//
-
-void endhostent() {}
-void endnetent() {}
-void endprotoent() {}
-void endservent() {}
-
-struct netent *getnetent (void) {return (struct netent *) NULL;}
-
-struct netent *getnetbyaddr(char *name) {return (struct netent *)NULL;}
-
-struct netent *getnetbyname(long net, int type) {return (struct netent *)NULL;}
-
-struct protoent *getprotoent (void) {return (struct protoent *) NULL;}
-
-struct servent *getservent (void) {return (struct servent *) NULL;}
-
-void sethostent (int stayopen) {}
-
-void setnetent (int stayopen) {}
-
-void setprotoent (int stayopen) {}
-
-void setservent (int stayopen) {}
-
-
-#ifndef WNOHANG
-#define WNOHANG -1
-#endif
-
-pid_t
-waitpid (pid_t pid, int *stat_loc, int options)
-{
-    DWORD timeout;
-
-    if (options == WNOHANG) {
-	timeout = 0;
-    } else {
-	timeout = INFINITE;
-    }
-    if (WaitForSingleObject((HANDLE) pid, timeout) == WAIT_OBJECT_0) {
-	pid = _cwait(stat_loc, pid, 0);
-	return pid;
-    }
-    return 0;
-}
-
-#include <sys/timeb.h>
-
-void _cdecl
-gettimeofday(struct timeval *tv, struct timezone *tz)
-{                                
-    struct timeb tb;
-
-    ftime(&tb);
-    tv->tv_sec = tb.time;
-    tv->tv_usec = tb.millitm * 1000;
-}
-
-char *
-getcwd(buffer, size)
-    char *buffer;
-    int size;
-{
-    int length;
-    char *bp;
-
-    if (_getcwd(buffer, size) == NULL) {
-        return NULL;
-    }
-    length = strlen(buffer);
-    if (length >= size) {
-        return NULL;
-    }
-
-    for (bp = buffer; *bp != '\0'; bp++) {
-	if (*bp == '\\') {
-	    *bp = '/';
-	}
-    }
-    return buffer;
-}
-
-static char *
-str_grow(struct RString *str, size_t new_size)
-{
-	char *p;
-
-	p = realloc(str->ptr, new_size);
-	if (p == NULL)
-                rb_fatal("cannot grow string\n");
-
-	str->len = new_size;
-	str->ptr = p;
-
-	return p;
-}
-
-int
-chown(char *path, int owner, int group)
-{
-	return 0;
-}
-
-int
-kill(int pid, int sig)
-{
-#if 1
-	if (pid == GetCurrentProcessId())
-		return raise(sig);
-
-	if (sig == 2 && pid > 0)
-		if (GenerateConsoleCtrlEvent(CTRL_C_EVENT, (DWORD)pid))
-			return 0;
-
-	return -1;
-#else
-	return 0;
-#endif
-}
-
-int
-link(char *from, char *to)
-{
-	return -1;
-}
-
-int
-wait()
-{
-	return 0;
-}
-
+/*
+ *  Copyright (c) 1993, Intergraph Corporation
+ *
+ *  You may distribute under the terms of either the GNU General Public
+ *  License or the Artistic License, as specified in the perl README file.
+ *
+ *  Various Unix compatibility functions and NT specific functions.
+ *
+ *  Some of this code was derived from the MSDOS port(s) and the OS/2 port.
+ *
+ */
+
+#include <fcntl.h>
+#include <process.h>
+#include <sys/stat.h>
+/* #include <sys/wait.h> */
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <windows.h>
+#include <winbase.h>
+#include <wincon.h>
+#include <signal.h>
+#include "ruby.h"
+#include "dir.h"
+#ifndef index
+#define index(x, y) strchr((x), (y))
+#endif
+
+#ifndef bool
+#define bool int
+#endif
+
+bool NtSyncProcess = TRUE;
+#if 0  // declared in header file
+extern char **environ;
+#define environ _environ
+#endif
+
+static bool NtHasRedirection (char *);
+static int valid_filename(char *s);
+static void StartSockets ();
+static char *str_grow(struct RString *str, size_t new_size);
+
+char *NTLoginName;
+
+DWORD Win32System = (DWORD)-1;
+
+static DWORD
+IdOS(void)
+{
+    static OSVERSIONINFO osver;
+
+    if (osver.dwPlatformId != Win32System) {
+	memset(&osver, 0, sizeof(OSVERSIONINFO));
+	osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+	GetVersionEx(&osver);
+	Win32System = osver.dwPlatformId;
+    }
+    return (Win32System);
+}
+
+static int 
+IsWin95(void) {
+    return (IdOS() == VER_PLATFORM_WIN32_WINDOWS);
+}
+
+static int
+IsWinNT(void) {
+    return (IdOS() == VER_PLATFORM_WIN32_NT);
+}
+
+
+/* simulate flock by locking a range on the file */
+
+
+#define LK_ERR(f,i) ((f) ? (i = 0) : (errno = GetLastError()))
+#define LK_LEN      0xffff0000
+
+int
+flock(int fd, int oper)
+{
+    OVERLAPPED o;
+    int i = -1;
+    HANDLE fh;
+
+    fh = (HANDLE)_get_osfhandle(fd);
+    memset(&o, 0, sizeof(o));
+
+    if(IsWinNT()) {
+        switch(oper) {
+        case LOCK_SH:       /* shared lock */
+            LK_ERR(LockFileEx(fh, 0, 0, LK_LEN, 0, &o),i);
+            break;
+        case LOCK_EX:       /* exclusive lock */
+            LK_ERR(LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, 0, &o),i);
+            break;
+        case LOCK_SH|LOCK_NB:   /* non-blocking shared lock */
+            LK_ERR(LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, 0, &o),i);
+            break;
+        case LOCK_EX|LOCK_NB:   /* non-blocking exclusive lock */
+            LK_ERR(LockFileEx(fh,
+                   LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
+                   0, LK_LEN, 0, &o),i);
+	    if(errno == EDOM) errno = EWOULDBLOCK;
+            break;
+        case LOCK_UN:       /* unlock lock */
+	    if (UnlockFileEx(fh, 0, LK_LEN, 0, &o)) {
+		i = 0;
+	    }
+	    else {
+		/* GetLastError() must returns `ERROR_NOT_LOCKED' */
+		errno = EWOULDBLOCK;
+	    }
+	    if(errno == EDOM) errno = EWOULDBLOCK;
+            break;
+        default:            /* unknown */
+            errno = EINVAL;
+            break;
+        }
+    }
+    else if(IsWin95()) {
+        switch(oper) {
+        case LOCK_EX:
+	    while(i == -1) {
+	        LK_ERR(LockFile(fh, 0, 0, LK_LEN, 0), i);
+		if(errno != EDOM && i == -1) break;
+	    }
+	    break;
+	case LOCK_EX | LOCK_NB:
+	    LK_ERR(LockFile(fh, 0, 0, LK_LEN, 0), i);
+	    if(errno == EDOM) errno = EWOULDBLOCK;
+            break;
+        case LOCK_UN:
+            LK_ERR(UnlockFile(fh, 0, 0, LK_LEN, 0), i);
+	    if(errno == EDOM) errno = EWOULDBLOCK;
+            break;
+        default:
+            errno = EINVAL;
+            break;
+        }
+    }
+    return i;
+}
+
+#undef LK_ERR
+#undef LK_LEN
+
+
+//#undef const
+//FILE *fdopen(int, const char *);
+
+#if 0
+void
+sleep(unsigned int len)
+{
+	time_t end;
+
+	end = time((time_t *)0) + len;
+	while (time((time_t *)0) < end)
+		;
+}
+#endif
+
+//
+// Initialization stuff
+//
+void
+NtInitialize(int *argc, char ***argv) {
+
+    //
+    // subvert cmd.exe\'s feeble attempt at command line parsing
+    //
+    *argc = NtMakeCmdVector((char *)GetCommandLine(), argv, TRUE);
+
+    //
+    // Now set up the correct time stuff
+    //
+
+    tzset();
+
+    // Initialize Winsock
+    StartSockets();
+}
+
+
+char *getlogin()
+{
+    char buffer[200];
+    int len = 200;
+    extern char *NTLoginName;
+
+    if (NTLoginName == NULL) {
+	if (GetUserName(buffer, &len)) {
+	    NTLoginName = ALLOC_N(char, len+1);
+	    strncpy(NTLoginName, buffer, len);
+	    NTLoginName[len] = '\0';
+	}
+	else {
+	    NTLoginName = "<Unknown>";
+	}
+    }
+    return NTLoginName;
+}
+
+
+
+#if 1
+// popen stuff
+
+//
+// use these so I can remember which index is which
+//
+
+#define NtPipeRead  0	   // index of pipe read descriptor
+#define NtPipeWrite 1	   // index of pipe write descriptor
+
+#define NtPipeSize  1024   // size of pipe buffer
+
+#define MYPOPENSIZE 256	   // size of book keeping structure
+
+struct {
+    int inuse;
+    int pid;
+    HANDLE oshandle;
+    FILE *pipe;
+} MyPopenRecord[MYPOPENSIZE];
+
+int SafeFree(char **vec, int vecc)
+{
+    //   vec
+    //   |
+    //   V       ^---------------------V
+    //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+    //   |   |       | ....  |  NULL |   | ..... |\0 |   | ..... |\0 |...
+    //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+    //   |-  elements+1             -| ^ 1st element   ^ 2nd element
+
+	char *p;
+
+	p = (char *)vec;
+	free(p);
+
+	return 0;
+}
+
+
+static char *szInternalCmds[] = {
+  "append",
+  "break",
+  "call",
+  "cd",
+  "chdir",
+  "cls",
+  "copy",
+  "date",
+  "del",
+  "dir",
+  "echo",
+  "erase",
+  "label",
+  "md",
+  "mkdir",
+  "path",
+  "pause",
+  "rd",
+  "rem",
+  "ren",
+  "rename",
+  "rmdir",
+  "set",
+  "start",
+  "time",
+  "type",
+  "ver",
+  "vol",
+  NULL
+};
+
+int
+isInternalCmd(char *cmd)
+{
+#if 0
+        return 0;
+#else
+        int i, fRet=0;
+	char **vec;
+        int vecc = NtMakeCmdVector(cmd, &vec, FALSE);
+
+        for( i = 0; szInternalCmds[i] ; i++){
+	    if(!strcmp(szInternalCmds[i], vec[0])){
+		fRet = 1;
+		break;
+	    }
+        }
+ 
+	SafeFree (vec, vecc);
+
+	return fRet;
+#endif
+}
+
+
+FILE *
+mypopen (char *cmd, char *mode) 
+{
+    FILE *fp;
+    int reading;
+    int pipemode;
+    int slot;
+    static initialized = 0;
+
+    //
+    // if first time through, intialize our book keeping structure
+    //
+
+    if (!initialized++) {
+	for (slot = 0; slot < MYPOPENSIZE; slot++)
+	    MyPopenRecord[slot].inuse = FALSE;
+    }
+
+    //printf("mypopen %s\n", cmd);
+    
+    //
+    // find a free popen slot
+    //
+
+    for (slot = 0; slot < MYPOPENSIZE && MyPopenRecord[slot].inuse; slot++)
+	;
+
+    if (slot > MYPOPENSIZE) {
+	return NULL;
+    }
+
+    //
+    // Figure out what we\'re doing...
+    //
+
+    reading = (*mode == 'r') ? TRUE : FALSE;
+    pipemode = (*(mode+1) == 'b') ? O_BINARY : O_TEXT;
+
+    //
+    // Now get a pipe
+    //
+
+#if 0    
+    if (_pipe(pipes, NtPipeSize, pipemode) == -1) {
+	return NULL;
+    }
+
+    if (reading) {
+
+	//
+	// we\'re reading from the pipe, so we must hook up the
+	// write end of the pipe to the new processes stdout.
+	// To do this we must save our file handle from stdout
+	// by _dup\'ing it, then setting our stdout to be the pipe\'s 
+	// write descriptor. We must also make the write handle 
+	// inheritable so the new process can use it.
+
+	if ((saved = _dup(fileno(stdout))) == -1) {
+	    _close(pipes[NtPipeRead]);
+	    _close(pipes[NtPipeWrite]);
+	    return NULL;
+	}
+	if (_dup2 (pipes[NtPipeWrite], fileno(stdout)) == -1) {
+	    _close(pipes[NtPipeRead]);
+	    _close(pipes[NtPipeWrite]);
+	    return NULL;
+	}
+    }
+    else {
+	//
+	// must be writing to the new process. Do the opposite of
+	// the above, i.e. hook up the processes stdin to the read
+	// end of the pipe.
+	//
+
+	if ((saved = _dup(fileno(stdin))) == -1) {
+	    _close(pipes[NtPipeRead]);
+	    _close(pipes[NtPipeWrite]);
+	    return NULL;
+	}
+	if (_dup2(pipes[NtPipeRead], fileno(stdin)) == -1) {
+	    _close(pipes[NtPipeRead]);
+	    _close(pipes[NtPipeWrite]);
+	    return NULL;
+	}
+    }
+
+    //
+    // Start the new process. Must set _fileinfo to non-zero value
+    // for file descriptors to be inherited. Reset after the process
+    // is started.
+    //
+
+    if (NtHasRedirection(cmd)) {
+      docmd:
+	pid = spawnlpe(_P_NOWAIT, "cmd.exe", "/c", cmd, 0, environ);
+	if (pid == -1) {
+	    _close(pipes[NtPipeRead]);
+	    _close(pipes[NtPipeWrite]);
+	    return NULL;
+	}
+    }
+    else {
+	char **vec;
+	int vecc = NtMakeCmdVector(cmd, &vec, FALSE);
+
+	//pid = spawnvpe (_P_NOWAIT, vec[0], vec, environ);
+	pid = spawnvpe (_P_WAIT, vec[0], vec, environ);
+	if (pid == -1) {
+	    goto docmd;
+	}
+		Safefree (vec, vecc);
+    }
+
+    if (reading) {
+
+	//
+	// We need to close our instance of the inherited pipe write
+	// handle now that it's been inherited so that it will actually close
+	// when the child process ends.
+	//
+
+	if (_close(pipes[NtPipeWrite]) == -1) {
+	    _close(pipes[NtPipeRead]);
+	    return NULL;
+	}
+	if (_dup2 (saved, fileno(stdout)) == -1) {
+	    _close(pipes[NtPipeRead]);
+	    return NULL;
+	}
+	_close(saved);
+
+	// 
+	// Now get a stream pointer to return to the calling program.
+	//
+
+	if ((fp = (FILE *) fdopen(pipes[NtPipeRead], mode)) == NULL) {
+	    return NULL;
+	}
+    }
+    else {
+
+	//
+	// need to close our read end of the pipe so that it will go 
+	// away when the write end is closed.
+	//
+
+	if (_close(pipes[NtPipeRead]) == -1) {
+	    _close(pipes[NtPipeWrite]);
+	    return NULL;
+	}
+	if (_dup2 (saved, fileno(stdin)) == -1) {
+	    _close(pipes[NtPipeWrite]);
+	    return NULL;
+	}
+	_close(saved);
+
+	// 
+	// Now get a stream pointer to return to the calling program.
+	//
+
+	if ((fp = (FILE *) fdopen(pipes[NtPipeWrite], mode)) == NULL) {
+	    _close(pipes[NtPipeWrite]);
+	    return NULL;
+	}
+    }
+
+    //
+    // do the book keeping
+    //
+
+    MyPopenRecord[slot].inuse = TRUE;
+    MyPopenRecord[slot].pipe = fp;
+    MyPopenRecord[slot].pid = pid;
+
+    return fp;
+#else
+    {
+		BOOL fRet;
+		HANDLE hInFile, hOutFile, hStdin, hStdout;
+		LPCSTR lpApplicationName = NULL;
+		LPTSTR lpCommandLine;
+		LPTSTR lpCmd2 = NULL;
+		DWORD  dwCreationFlags;
+		STARTUPINFO aStartupInfo;
+		PROCESS_INFORMATION     aProcessInformation;
+		SECURITY_ATTRIBUTES sa;
+		int fd;
+
+		sa.nLength              = sizeof (SECURITY_ATTRIBUTES);
+		sa.lpSecurityDescriptor = NULL;
+		sa.bInheritHandle       = TRUE;
+
+		if (!reading) {
+        	FILE *fp;
+
+			fp = (_popen)(cmd, mode);
+
+			MyPopenRecord[slot].inuse = TRUE;
+			MyPopenRecord[slot].pipe = fp;
+			MyPopenRecord[slot].pid = -1;
+
+			if (!fp)
+                        rb_fatal("cannot open pipe \"%s\" (%s)", cmd, strerror(errno));
+				return fp;
+		}
+
+		fRet = CreatePipe(&hInFile, &hOutFile, &sa, 2048L);
+		if (!fRet)
+                        rb_fatal("cannot open pipe \"%s\" (%s)", cmd, strerror(errno));
+
+		memset(&aStartupInfo, 0, sizeof (STARTUPINFO));
+		memset(&aProcessInformation, 0, sizeof (PROCESS_INFORMATION));
+		aStartupInfo.cb = sizeof (STARTUPINFO);
+		aStartupInfo.dwFlags    = STARTF_USESTDHANDLES;
+
+		if (reading) {
+			aStartupInfo.hStdInput  = GetStdHandle(STD_OUTPUT_HANDLE);//hStdin;
+			aStartupInfo.hStdError  = INVALID_HANDLE_VALUE;
+			//for save
+			DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE),
+			  GetCurrentProcess(), &hStdout,
+			  0, FALSE, DUPLICATE_SAME_ACCESS
+			);
+			//for redirect
+			DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE),
+			  GetCurrentProcess(), &hStdin,
+			  0, TRUE, DUPLICATE_SAME_ACCESS
+			);
+			aStartupInfo.hStdOutput = hOutFile;
+		}
+		else {
+			aStartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); //hStdout;
+			aStartupInfo.hStdError  = INVALID_HANDLE_VALUE;
+			// for save
+			DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE),
+			  GetCurrentProcess(), &hStdin,
+			  0, FALSE, DUPLICATE_SAME_ACCESS
+			);
+			//for redirect
+			DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE),
+			  GetCurrentProcess(), &hStdout,
+			  0, TRUE, DUPLICATE_SAME_ACCESS
+			);
+			aStartupInfo.hStdInput = hInFile;
+		}
+
+		dwCreationFlags = (NORMAL_PRIORITY_CLASS);
+
+		lpCommandLine = cmd;
+		if (NtHasRedirection(cmd) || isInternalCmd(cmd)) {
+		  lpApplicationName = getenv("COMSPEC");
+		  lpCmd2 = malloc(strlen(lpApplicationName) + 1 + strlen(cmd) + sizeof (" /c "));
+		  if (lpCmd2 == NULL)
+                     rb_fatal("Mypopen: malloc failed");
+		  sprintf(lpCmd2, "%s %s%s", lpApplicationName, " /c ", cmd);
+		  lpCommandLine = lpCmd2;
+		}
+
+		fRet = CreateProcess(lpApplicationName, lpCommandLine, &sa, &sa,
+			sa.bInheritHandle, dwCreationFlags, NULL, NULL, &aStartupInfo, &aProcessInformation);
+
+		if (!fRet) {
+			CloseHandle(hInFile);
+			CloseHandle(hOutFile);
+                        rb_fatal("cannot fork for \"%s\" (%s)", cmd, strerror(errno));
+		}
+
+		CloseHandle(aProcessInformation.hThread);
+
+		if (reading) {
+			HANDLE hDummy;
+
+			fd = _open_osfhandle((long)hInFile,  (_O_RDONLY | pipemode));
+			CloseHandle(hOutFile);
+			DuplicateHandle(GetCurrentProcess(), hStdout,
+			  GetCurrentProcess(), &hDummy,
+			  0, TRUE, (DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)
+			);
+		}
+		else {
+			HANDLE hDummy;
+
+		    fd = _open_osfhandle((long)hOutFile, (_O_WRONLY | pipemode));
+			CloseHandle(hInFile);
+			DuplicateHandle(GetCurrentProcess(), hStdin,
+			  GetCurrentProcess(), &hDummy,
+			  0, TRUE, (DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)
+			);
+		}
+
+		if (fd == -1) 
+                  rb_fatal("cannot open pipe \"%s\" (%s)", cmd, strerror(errno));
+
+
+		if ((fp = (FILE *) fdopen(fd, mode)) == NULL)
+			return NULL;
+
+		if (lpCmd2)
+			free(lpCmd2);
+
+		MyPopenRecord[slot].inuse = TRUE;
+		MyPopenRecord[slot].pipe  = fp;
+		MyPopenRecord[slot].oshandle = (reading ? hInFile : hOutFile);
+		MyPopenRecord[slot].pid   = (int)aProcessInformation.hProcess;
+		return fp;
+    }
+#endif
+}
+
+int
+mypclose(FILE *fp)
+{
+    int i;
+    int exitcode;
+
+    Sleep(100);
+    for (i = 0; i < MYPOPENSIZE; i++) {
+	if (MyPopenRecord[i].inuse && MyPopenRecord[i].pipe == fp)
+	    break;
+    }
+    if (i >= MYPOPENSIZE) {
+                rb_fatal("Invalid file pointer passed to mypclose!\n");
+    }
+
+    //
+    // get the return status of the process
+    //
+
+#if 0
+    if (_cwait(&exitcode, MyPopenRecord[i].pid, WAIT_CHILD) == -1) {
+	if (errno == ECHILD) {
+	    fprintf(stderr, "mypclose: nosuch child as pid %x\n", 
+		    MyPopenRecord[i].pid);
+	}
+    }
+#else
+	for (;;) {
+		if (GetExitCodeProcess((HANDLE)MyPopenRecord[i].pid, &exitcode)) {
+			if (exitcode == STILL_ACTIVE) {
+				//printf("Process is Active.\n");
+				Sleep(100);
+				TerminateProcess((HANDLE)MyPopenRecord[i].pid, 0); // ugly...
+				continue;
+			}
+			else if (exitcode == 0) {
+				//printf("done.\n");
+				break;
+			}
+			else {
+				//printf("never.\n");
+				break;
+			}
+		}
+	}
+#endif
+
+
+    //
+    // close the pipe
+    //
+    CloseHandle(MyPopenRecord[i].oshandle);
+    fflush(fp);
+    fclose(fp);
+
+    //
+    // free this slot
+    //
+
+    MyPopenRecord[i].inuse = FALSE;
+    MyPopenRecord[i].pipe  = NULL;
+    MyPopenRecord[i].pid   = 0;
+
+    return exitcode;
+}
+#endif
+
+#if 1
+
+
+typedef char* CHARP;
+/*
+ * The following code is based on the do_exec and do_aexec functions
+ * in file doio.c
+ */
+
+int
+do_spawn(cmd)
+char *cmd;
+{
+    register char **a;
+    register char *s;
+    char **argv;
+    int status;
+    char *shell, *cmd2;
+    int mode = NtSyncProcess ? P_WAIT : P_NOWAIT;
+
+    /* save an extra exec if possible */
+    if ((shell = getenv("RUBYSHELL")) != 0) {
+	if (NtHasRedirection(cmd)) {
+	    char *p;
+	    char *argv[4];
+	    char *cmdline = ALLOC_N(char, (strlen(cmd) * 2 + 1));
+
+	    p=cmdline;           
+	    *p++ = '"';
+	    for (s=cmd; *s;) {
+		if (*s == '"') 
+		    *p++ = '\\'; /* Escape d-quote */
+		*p++ = *s++;
+	    }
+	    *p++ = '"';
+	    *p   = '\0';
+
+	    /* fprintf(stderr, "do_spawn: %s %s\n", shell, cmdline); */
+	    argv[0] = shell;
+	    argv[1] = "-c";
+	    argv[2] = cmdline;
+	    argv[4] = NULL;
+	    status = spawnvpe(mode, argv[0], argv, environ);
+	    /* return spawnle(mode, shell, shell, "-c", cmd, (char*)0, environ); */
+	    free(cmdline);
+	    return status;
+	} 
+    }
+    else if ((shell = getenv("COMSPEC")) != 0) {
+	if (NtHasRedirection(cmd) || isInternalCmd(cmd)) {
+	    return spawnle(mode, shell, shell, "/c", cmd, (char*)0, environ);
+	}
+    }
+
+    argv = ALLOC_N(CHARP, (strlen(cmd) / 2 + 2));
+    cmd2 = ALLOC_N(char, (strlen(cmd) + 1));
+    strcpy(cmd2, cmd);
+    a = argv;
+    for (s = cmd2; *s;) {
+	while (*s && isspace(*s)) s++;
+	if (*s)
+	    *(a++) = s;
+	while (*s && !isspace(*s)) s++;
+	if (*s)
+	    *s++ = '\0';
+    }
+    *a = NULL;
+    if (argv[0]) {
+	if ((status = spawnvpe(mode, argv[0], argv, environ)) == -1) {
+		rb_fatal("cannot execute \"%s\" (%s)", cmd, strerror(errno));
+	    free(argv);
+	    free(cmd2);
+	    return -1;
+	}
+    }
+    free(cmd2);
+    free(argv);
+    return status;
+}
+
+#endif
+
+typedef struct _NtCmdLineElement {
+    struct _NtCmdLineElement *next, *prev;
+    char *str;
+    int len;
+    int flags;
+} NtCmdLineElement;
+
+//
+// Possible values for flags
+//
+
+#define NTGLOB   0x1	// element contains a wildcard
+#define NTMALLOC 0x2	// string in element was malloc'ed
+#define NTSTRING 0x4	// element contains a quoted string
+
+NtCmdLineElement *NtCmdHead = NULL, *NtCmdTail = NULL;
+
+void
+NtFreeCmdLine(void)
+{
+    NtCmdLineElement *ptr;
+    
+    while(NtCmdHead) {
+	ptr = NtCmdHead;
+	NtCmdHead = NtCmdHead->next;
+	free(ptr);
+    }
+    NtCmdHead = NtCmdTail = NULL;
+}
+
+//
+// This function expands wild card characters that were spotted 
+// during the parse phase. The idea here is to call FindFirstFile and
+// FindNextFile with the wildcard pattern specified, and splice in the
+// resulting list of new names. If the wildcard pattern doesn\'t match 
+// any existing files, just leave it in the list.
+//
+
+void
+NtCmdGlob (NtCmdLineElement *patt)
+{
+    WIN32_FIND_DATA fd;
+    HANDLE fh;
+    char buffer[512];
+    NtCmdLineElement *tmphead, *tmptail, *tmpcurr;
+
+    strncpy(buffer, patt->str, patt->len);
+    buffer[patt->len] = '\0';
+    if ((fh = FindFirstFile (buffer, &fd)) == INVALID_HANDLE_VALUE) {
+	return;
+    }
+    tmphead = tmptail = NULL;
+    do {
+	tmpcurr = ALLOC(NtCmdLineElement);
+	if (tmpcurr == NULL) {
+	    fprintf(stderr, "Out of Memory in globbing!\n");
+	    while (tmphead) {
+		tmpcurr = tmphead;
+		tmphead = tmphead->next;
+		free(tmpcurr->str);
+		free(tmpcurr);
+	    }
+	    return;
+	}
+	memset (tmpcurr, 0, sizeof(*tmpcurr));
+	tmpcurr->len = strlen(fd.cFileName);
+	tmpcurr->str = ALLOC_N(char, tmpcurr->len+1);
+	if (tmpcurr->str == NULL) {
+	    fprintf(stderr, "Out of Memory in globbing!\n");
+	    while (tmphead) {
+		tmpcurr = tmphead;
+		tmphead = tmphead->next;
+		free(tmpcurr->str);
+		free(tmpcurr);
+	    }
+	    return;
+	}
+	strcpy(tmpcurr->str, fd.cFileName);
+	tmpcurr->flags |= NTMALLOC;
+	if (tmptail) {
+	    tmptail->next = tmpcurr;
+	    tmpcurr->prev = tmptail;
+	    tmptail = tmpcurr;
+	}
+	else {
+	    tmptail = tmphead = tmpcurr;
+	}
+    } while(FindNextFile(fh, &fd));
+
+    //
+    // ok, now we\'ve got a list of files that matched the wildcard
+    // specification. Put it in place of the pattern structure.
+    //
+    
+    tmphead->prev = patt->prev;
+    tmptail->next = patt->next;
+
+    if (tmphead->prev)
+	tmphead->prev->next = tmphead;
+
+    if (tmptail->next)
+	tmptail->next->prev = tmptail;
+
+    //
+    // Now get rid of the pattern structure
+    //
+
+    if (patt->flags & NTMALLOC)
+	free(patt->str);
+    // free(patt);  //TODO:  memory leak occures here. we have to fix it.
+}
+
+// 
+// Check a command string to determine if it has I/O redirection
+// characters that require it to be executed by a command interpreter
+//
+
+static bool
+NtHasRedirection (char *cmd)
+{
+    int inquote = 0;
+    char quote = '\0';
+    char *ptr ;
+    
+    //
+    // Scan the string, looking for redirection (< or >) or pipe 
+    // characters (|) that are not in a quoted string
+    //
+
+    for (ptr = cmd; *ptr; ptr++) {
+
+	switch (*ptr) {
+
+	  case '\'':
+	  case '\"':
+	    if (inquote) {
+		if (quote == *ptr) {
+		    inquote = 0;
+		    quote = '\0';
+		}
+	    }
+	    else {
+		quote = *ptr;
+		inquote++;
+	    }
+	    break;
+
+	  case '>':
+	  case '<':
+
+	    if (!inquote)
+		return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+
+int 
+NtMakeCmdVector (char *cmdline, char ***vec, int InputCmd)
+{
+    int cmdlen = strlen(cmdline);
+    int done, instring, globbing, quoted, len;
+    int newline, need_free = 0, i;
+    int elements, strsz;
+    int slashes = 0;
+    char *ptr, *base, *buffer;
+    char **vptr;
+    char quote;
+    NtCmdLineElement *curr;
+
+    //
+    // just return if we don\'t have a command line
+    //
+
+    if (cmdlen == 0) {
+	*vec = NULL;
+	return 0;
+    }
+
+    //
+    // strip trailing white space
+    //
+
+    ptr = cmdline+(cmdlen - 1);
+    while(ptr >= cmdline && isspace(*ptr))
+        --ptr;
+    *++ptr = '\0';
+
+    //
+    // check for newlines and formfeeds. If we find any, make a new
+    // command string that replaces them with escaped sequences (\n or \f)
+    //
+
+    for (ptr = cmdline, newline = 0; *ptr; ptr++) {
+	if (*ptr == '\n' || *ptr == '\f')
+	    newline++;
+    }
+
+    if (newline) {
+	base = ALLOC_N(char, strlen(cmdline) + 1 + newline + slashes);
+	if (base == NULL) {
+	    fprintf(stderr, "malloc failed!\n");
+	    return 0;
+	}
+	for (i = 0, ptr = base; (unsigned) i < strlen(cmdline); i++) {
+	    switch (cmdline[i]) {
+	      case '\n':
+		*ptr++ = '\\';
+		*ptr++ = 'n';
+		break;
+	      default:
+		*ptr++ = cmdline[i];
+	    }
+	}
+	*ptr = '\0';
+	cmdline = base;
+	need_free++;
+    }
+
+    //
+    // Ok, parse the command line, building a list of CmdLineElements.
+    // When we\'ve finished, and it\'s an input command (meaning that it\'s
+    // the processes argv), we\'ll do globing and then build the argument 
+    // vector.
+    // The outer loop does one interation for each element seen. 
+    // The inner loop does one interation for each character in the element.
+    //
+
+    for (done = 0, ptr = cmdline; *ptr;) {
+
+	//
+	// zap any leading whitespace
+	//
+
+	while(isspace(*ptr))
+	    ptr++;
+	base = ptr;
+
+	for (done = newline = globbing = instring = quoted = 0; 
+	     *ptr && !done; ptr++) {
+
+	    //
+	    // Switch on the current character. We only care about the
+	    // white-space characters, the  wild-card characters, and the
+	    // quote characters.
+	    //
+
+	    switch (*ptr) {
+	      case ' ':
+	      case '\t':
+#if 0
+	      case '/':  // have to do this for NT/DOS option strings
+
+		//
+		// check to see if we\'re parsing an option switch
+		//
+
+		if (*ptr == '/' && base == ptr)
+		    continue;
+#endif
+		//
+		// if we\'re not in a string, then we\'re finished with this
+		// element
+		//
+
+		if (!instring)
+		    done++;
+		break;
+
+	      case '*':
+	      case '?':
+
+		// 
+		// record the fact that this element has a wildcard character
+		// N.B. Don\'t glob if inside a single quoted string
+		//
+
+		if (!(instring && quote == '\''))
+		    globbing++;
+		break;
+
+	      case '\n':
+
+		//
+		// If this string contains a newline, mark it as such so
+		// we can replace it with the two character sequence "\n"
+		// (cmd.exe doesn\'t like raw newlines in strings...sigh).
+		//
+
+		newline++;
+		break;
+
+	      case '\'':
+	      case '\"':
+
+		//
+		// if we\'re already in a string, see if this is the
+		// terminating close-quote. If it is, we\'re finished with 
+		// the string, but not neccessarily with the element.
+		// If we\'re not already in a string, start one.
+		//
+
+		if (instring) {
+		    if (quote == *ptr) {
+			instring = 0;
+			quote = '\0';
+		    }
+		}
+		else {
+		    instring++;
+		    quote = *ptr;
+		    quoted++;
+		}
+		break;
+	    }
+	}
+
+	//
+	// need to back up ptr by one due to last increment of for loop
+	// (if we got out by seeing white space)
+	//
+
+	if (*ptr)
+	    ptr--;
+
+	//
+	// when we get here, we\'ve got a pair of pointers to the element,
+	// base and ptr. Base points to the start of the element while ptr
+	// points to the character following the element.
+	//
+
+	curr = ALLOC(NtCmdLineElement);
+	if (curr == NULL) {
+	    NtFreeCmdLine();
+	    fprintf(stderr, "Out of memory!!\n");
+	    *vec = NULL;
+	    return 0;
+	}
+	memset (curr, 0, sizeof(*curr));
+
+	len = ptr - base;
+
+	//
+	// if it\'s an input vector element and it\'s enclosed by quotes, 
+	// we can remove them.
+	//
+
+	if (InputCmd &&
+	    ((base[0] == '\"' && base[len-1] == '\"') ||
+	     (base[0] == '\'' && base[len-1] == '\''))) {
+	    base++;
+	    len -= 2;
+	}
+
+	curr->str = base;
+	curr->len = len;
+	curr->flags |= (globbing ? NTGLOB : 0);
+
+	//
+	// Now put it in the list of elements
+	//
+	if (NtCmdTail) {
+	    NtCmdTail->next = curr;
+	    curr->prev = NtCmdTail;
+	    NtCmdTail = curr;
+	}
+	else {
+	    NtCmdHead = NtCmdTail = curr;
+	}
+    }
+
+    if (InputCmd) {
+
+	//
+	// When we get here we\'ve finished parsing the command line. Now 
+	// we need to run the list, expanding any globbing patterns.
+	//
+	
+	for(curr = NtCmdHead; curr; curr = curr->next) {
+	    if (curr->flags & NTGLOB) {
+		NtCmdGlob(curr);
+	    }
+	}
+    }
+
+    //
+    // Almost done! 
+    // Count up the elements, then allocate space for a vector of pointers
+    // (argv) and a string table for the elements.
+    // 
+
+    for (elements = 0, strsz = 0, curr = NtCmdHead; curr; curr = curr->next) {
+	elements++;
+	strsz += (curr->len + 1);
+    }
+
+    len = (elements+1)*sizeof(char *) + strsz;
+    buffer = ALLOC_N(char, len);
+    if (buffer == NULL) {
+	fprintf(stderr, "Out of memory!!\n");
+	NtFreeCmdLine();
+	*vec = NULL;
+	return 0;
+    }
+    
+    memset (buffer, 0, len);
+
+    //
+    // make vptr point to the start of the buffer
+    // and ptr point to the area we\'ll consider the string table.
+    //
+    //   buffer (*vec)
+    //   |
+    //   V       ^---------------------V
+    //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+    //   |   |       | ....  | NULL  |   | ..... |\0 |   | ..... |\0 |...
+    //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+    //   |-  elements+1             -| ^ 1st element   ^ 2nd element
+
+    vptr = (char **) buffer;
+
+    ptr = buffer + (elements+1) * sizeof(char *);
+
+    for (curr =  NtCmdHead; curr;  curr = curr->next) {
+	strncpy (ptr, curr->str, curr->len);
+	ptr[curr->len] = '\0';
+	*vptr++ = ptr;
+	ptr += curr->len + 1;
+    }
+    NtFreeCmdLine();
+    *vec = (char **) buffer;
+    return elements;
+}
+
+
+#if 1
+//
+// UNIX compatible directory access functions for NT
+//
+
+//
+// File names are converted to lowercase if the
+// CONVERT_TO_LOWER_CASE variable is defined.
+//
+
+#define CONVERT_TO_LOWER_CASE
+#define PATHLEN 1024
+
+//
+// The idea here is to read all the directory names into a string table
+// (separated by nulls) and when one of the other dir functions is called
+// return the pointer to the current file name. 
+//
+
+DIR *
+opendir(char *filename)
+{
+    DIR            *p;
+    long            len;
+    long            idx;
+    char            scannamespc[PATHLEN];
+    char	   *scanname = scannamespc;
+    struct stat	    sbuf;
+    WIN32_FIND_DATA FindData;
+    HANDLE          fh;
+    char            root[PATHLEN];
+    char            volname[PATHLEN];
+    DWORD           serial, maxname, flags;
+    BOOL            downcase;
+    char           *dummy;
+
+    //
+    // check to see if we\'ve got a directory
+    //
+
+    if (stat (filename, &sbuf) < 0 ||
+	sbuf.st_mode & _S_IFDIR == 0) {
+	return NULL;
+    }
+
+    //
+    // check out the file system characteristics
+    //
+    if (GetFullPathName(filename, PATHLEN, root, &dummy)) {
+	if (dummy = strchr(root, '\\'))
+	    *++dummy = '\0';
+	if (GetVolumeInformation(root, volname, PATHLEN, 
+				 &serial, &maxname, &flags, 0, 0)) {
+	    downcase = !(flags & FS_CASE_SENSITIVE);
+	}
+    }
+    else {
+	downcase = TRUE;
+    }
+
+    //
+    // Get us a DIR structure
+    //
+
+    p = xcalloc(sizeof(DIR), 1);
+    if (p == NULL)
+	return NULL;
+    
+    //
+    // Create the search pattern
+    //
+
+    strcpy(scanname, filename);
+
+    if (index("/\\", *(scanname + strlen(scanname) - 1)) == NULL)
+	strcat(scanname, "/*");
+    else
+	strcat(scanname, "*");
+
+    //
+    // do the FindFirstFile call
+    //
+
+    fh = FindFirstFile (scanname, &FindData);
+    if (fh == INVALID_HANDLE_VALUE) {
+	return NULL;
+    }
+
+    //
+    // now allocate the first part of the string table for the
+    // filenames that we find.
+    //
+
+    idx = strlen(FindData.cFileName)+1;
+    p->start = ALLOC_N(char, idx);
+    strcpy (p->start, FindData.cFileName);
+    if (downcase)
+	strlwr(p->start);
+    p->nfiles++;
+    
+    //
+    // loop finding all the files that match the wildcard
+    // (which should be all of them in this directory!).
+    // the variable idx should point one past the null terminator
+    // of the previous string found.
+    //
+    while (FindNextFile(fh, &FindData)) {
+	len = strlen (FindData.cFileName);
+
+	//
+	// bump the string table size by enough for the
+	// new name and it's null terminator 
+	//
+
+	#define Renew(x, y, z) (x = (z *)realloc(x, y))
+
+	Renew (p->start, idx+len+1, char);
+	if (p->start == NULL) {
+            rb_fatal ("opendir: malloc failed!\n");
+	}
+	strcpy(&p->start[idx], FindData.cFileName);
+	if (downcase) 
+	    strlwr(&p->start[idx]);
+	p->nfiles++;
+	idx += len+1;
+    }
+    FindClose(fh);
+    p->size = idx;
+    p->curr = p->start;
+    return p;
+}
+
+
+//
+// Readdir just returns the current string pointer and bumps the
+// string pointer to the next entry.
+//
+
+struct direct  *
+readdir(DIR *dirp)
+{
+    int         len;
+    static int  dummy = 0;
+
+    if (dirp->curr) {
+
+	//
+	// first set up the structure to return
+	//
+
+	len = strlen(dirp->curr);
+	strcpy(dirp->dirstr.d_name, dirp->curr);
+	dirp->dirstr.d_namlen = len;
+
+	//
+	// Fake inode
+	//
+	dirp->dirstr.d_ino = dummy++;
+
+	//
+	// Now set up for the next call to readdir
+	//
+
+	dirp->curr += len + 1;
+	if (dirp->curr >= (dirp->start + dirp->size)) {
+	    dirp->curr = NULL;
+	}
+
+	return &(dirp->dirstr);
+
+    } else
+	return NULL;
+}
+
+//
+// Telldir returns the current string pointer position
+//
+
+long
+telldir(DIR *dirp)
+{
+	return (long) dirp->curr;	/* ouch! pointer to long cast */
+}
+
+//
+// Seekdir moves the string pointer to a previously saved position
+// (Saved by telldir).
+
+void
+seekdir(DIR *dirp, long loc)
+{
+	dirp->curr = (char *) loc;	/* ouch! long to pointer cast */
+}
+
+//
+// Rewinddir resets the string pointer to the start
+//
+
+void
+rewinddir(DIR *dirp)
+{
+	dirp->curr = dirp->start;
+}
+
+//
+// This just free\'s the memory allocated by opendir
+//
+
+void
+closedir(DIR *dirp)
+{
+	free(dirp->start);
+	free(dirp);
+}
+#endif
+
+
+//
+// 98.2% of this code was lifted from the OS2 port. (JCW)
+//
+
+#if 0
+// add_suffix is in util.c too.
+/*
+ * Suffix appending for in-place editing under MS-DOS and OS/2 (and now NT!).
+ *
+ * Here are the rules:
+ *
+ * Style 0:  Append the suffix exactly as standard perl would do it.
+ *           If the filesystem groks it, use it.  (HPFS will always
+ *           grok it.  So will NTFS. FAT will rarely accept it.)
+ *
+ * Style 1:  The suffix begins with a '.'.  The extension is replaced.
+ *           If the name matches the original name, use the fallback method.
+ *
+ * Style 2:  The suffix is a single character, not a '.'.  Try to add the 
+ *           suffix to the following places, using the first one that works.
+ *               [1] Append to extension.  
+ *               [2] Append to filename, 
+ *               [3] Replace end of extension, 
+ *               [4] Replace end of filename.
+ *           If the name matches the original name, use the fallback method.
+ *
+ * Style 3:  Any other case:  Ignore the suffix completely and use the
+ *           fallback method.
+ *
+ * Fallback method:  Change the extension to ".$$$".  If that matches the
+ *           original name, then change the extension to ".~~~".
+ *
+ * If filename is more than 1000 characters long, we die a horrible
+ * death.  Sorry.
+ *
+ * The filename restriction is a cheat so that we can use buf[] to store
+ * assorted temporary goo.
+ *
+ * Examples, assuming style 0 failed.
+ *
+ * suffix = ".bak" (style 1)
+ *                foo.bar => foo.bak
+ *                foo.bak => foo.$$$	(fallback)
+ *                foo.$$$ => foo.~~~	(fallback)
+ *                makefile => makefile.bak
+ *
+ * suffix = "~" (style 2)
+ *                foo.c => foo.c~
+ *                foo.c~ => foo.c~~
+ *                foo.c~~ => foo~.c~~
+ *                foo~.c~~ => foo~~.c~~
+ *                foo~~~~~.c~~ => foo~~~~~.$$$ (fallback)
+ *
+ *                foo.pas => foo~.pas
+ *                makefile => makefile.~
+ *                longname.fil => longname.fi~
+ *                longname.fi~ => longnam~.fi~
+ *                longnam~.fi~ => longnam~.$$$
+ *                
+ */
+
+
+static char suffix1[] = ".$$$";
+static char suffix2[] = ".~~~";
+
+#define ext (&buf[1000])
+
+#define strEQ(s1,s2) (strcmp(s1,s2) == 0)
+
+void
+add_suffix(struct RString *str, char *suffix)
+{
+    int baselen;
+    int extlen = strlen(suffix);
+    char *s, *t, *p;
+    int slen;
+    char buf[1024];
+
+    if (str->len > 1000)
+        rb_fatal("Cannot do inplace edit on long filename (%d characters)", str->len);
+
+    /* Style 0 */
+    slen = str->len;
+    str_cat(str, suffix, extlen);
+    if (valid_filename(str->ptr)) return;
+
+    /* Fooey, style 0 failed.  Fix str before continuing. */
+    str->ptr[str->len = slen] = '\0';
+
+    slen = extlen;
+    t = buf; baselen = 0; s = str->ptr;
+    while ( (*t = *s) && *s != '.') {
+	baselen++;
+	if (*s == '\\' || *s == '/') baselen = 0;
+ 	s++; t++;
+    }
+    p = t;
+
+    t = ext; extlen = 0;
+    while (*t++ = *s++) extlen++;
+    if (extlen == 0) { ext[0] = '.'; ext[1] = 0; extlen++; }
+
+    if (*suffix == '.') {        /* Style 1 */
+        if (strEQ(ext, suffix)) goto fallback;
+	strcpy(p, suffix);
+    } else if (suffix[1] == '\0') {  /* Style 2 */
+        if (extlen < 4) { 
+	    ext[extlen] = *suffix;
+	    ext[++extlen] = '\0';
+        } else if (baselen < 8) {
+   	    *p++ = *suffix;
+	} else if (ext[3] != *suffix) {
+	    ext[3] = *suffix;
+	} else if (buf[7] != *suffix) {
+	    buf[7] = *suffix;
+	} else goto fallback;
+	strcpy(p, ext);
+    } else { /* Style 3:  Panic */
+fallback:
+	(void)memcpy(p, strEQ(ext, suffix1) ? suffix2 : suffix1, 5);
+    }
+    str_grow(str, strlen(buf));
+    memcpy(str->ptr, buf, str->len);
+}
+#endif
+
+static int 
+valid_filename(char *s)
+{
+    int fd;
+
+    //
+    // if the file exists, then it\'s a valid filename!
+    //
+
+    if (_access(s, 0) == 0) {
+	return 1;
+    }
+
+    //
+    // It doesn\'t exist, so see if we can open it.
+    //
+    
+    if ((fd = _open(s, _O_CREAT, 0666)) >= 0) {
+	close(fd);
+	_unlink (s);	// don\'t leave it laying around
+	return 1;
+    }
+    return 0;
+}
+
+
+//
+// This is a clone of fdopen so that we can handle the 
+// brain damaged version of sockets that NT gets to use.
+//
+// The problem is that sockets are not real file handles and 
+// cannot be fdopen\'ed. This causes problems in the do_socket
+// routine in doio.c, since it tries to create two file pointers
+// for the socket just created. We\'ll fake out an fdopen and see
+// if we can prevent perl from trying to do stdio on sockets.
+//
+
+FILE *
+myfdopen (int fd, const char *mode)
+{
+    FILE *fp;
+    char sockbuf[80];
+    int optlen;
+    int retval;
+    extern int errno;
+
+    //fprintf(stderr, "myfdopen()\n");
+
+    retval = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
+    if (retval == SOCKET_ERROR) {
+	int iRet;
+
+	iRet = WSAGetLastError();
+	if (iRet == WSAENOTSOCK || iRet == WSANOTINITIALISED)
+	return (_fdopen(fd, mode));
+    }
+
+    //
+    // If we get here, then fd is actually a socket.
+    //
+    fp = xcalloc(sizeof(FILE), 1);
+#if _MSC_VER < 800
+    fileno(fp) = fd;
+#else
+    fp->_file = fd;
+#endif
+    if (*mode == 'r')
+	fp->_flag = _IOREAD;
+    else
+	fp->_flag = _IOWRT;
+    return fp;
+}
+
+
+//
+// Since the errors returned by the socket error function 
+// WSAGetLastError() are not known by the library routine strerror
+// we have to roll our own.
+//
+
+#undef strerror
+
+char * 
+mystrerror(int e) 
+{
+    static char buffer[512];
+    extern int sys_nerr;
+    DWORD source = 0;
+
+    if (e < 0 || e > sys_nerr) {
+	if (e < 0)
+	    e = GetLastError();
+	if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, &source, e, 0,
+			  buffer, 512, NULL) == 0) {
+	    strcpy (buffer, "Unknown Error");
+	}
+	return buffer;
+    }
+    return strerror(e);
+	
+}
+
+//
+// various stubs
+//
+
+
+// Ownership
+//
+// Just pretend that everyone is a superuser. NT will let us know if
+// we don\'t really have permission to do something.
+//
+
+#define ROOT_UID	0
+#define ROOT_GID	0
+
+UIDTYPE
+getuid(void)
+{
+	return ROOT_UID;
+}
+
+UIDTYPE
+geteuid(void)
+{
+	return ROOT_UID;
+}
+
+GIDTYPE
+getgid(void)
+{
+	return ROOT_GID;
+}
+
+GIDTYPE
+getegid(void)
+{
+    return ROOT_GID;
+}
+
+int
+setuid(int uid)
+{ 
+    return (uid == ROOT_UID ? 0 : -1);
+}
+
+int
+setgid(int gid)
+{
+    return (gid == ROOT_GID ? 0 : -1);
+}
+
+//
+// File system stuff
+//
+
+int
+/* ioctl(int i, unsigned int u, char *data) */
+ioctl(int i, unsigned int u, long data)
+{
+    return -1;
+}
+
+
+//
+// Networking trampolines
+// These are used to avoid socket startup/shutdown overhead in case 
+// the socket routines aren\'t used.
+//
+
+#undef select
+
+static int NtSocketsInitialized = 0;
+
+long 
+myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
+	       struct timeval *timeout)
+{
+    long r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+
+static void
+StartSockets () {
+    WORD version;
+    WSADATA retdata;
+    int ret;
+    
+    //
+    // initalize the winsock interface and insure that it\'s
+    // cleaned up at exit.
+    //
+    version = MAKEWORD(1, 1);
+    if (ret = WSAStartup(version, &retdata))
+        rb_fatal ("Unable to locate winsock library!\n");
+    if (LOBYTE(retdata.wVersion) != 1)
+        rb_fatal("could not find version 1 of winsock dll\n");
+
+    if (HIBYTE(retdata.wVersion) != 1)
+        rb_fatal("could not find version 1 of winsock dll\n");
+
+    atexit((void (*)(void)) WSACleanup);
+}
+
+#undef accept
+
+SOCKET 
+myaccept (SOCKET s, struct sockaddr *addr, int *addrlen)
+{
+    SOCKET r;
+
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = accept (s, addr, addrlen)) == INVALID_SOCKET)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef bind
+
+int 
+mybind (SOCKET s, struct sockaddr *addr, int addrlen)
+{
+    int r;
+
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = bind (s, addr, addrlen)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef connect
+
+int 
+myconnect (SOCKET s, struct sockaddr *addr, int addrlen)
+{
+    int r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = connect (s, addr, addrlen)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+
+
+#undef getpeername
+
+int 
+mygetpeername (SOCKET s, struct sockaddr *addr, int *addrlen)
+{
+    int r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = getpeername (s, addr, addrlen)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef getsockname
+
+int 
+mygetsockname (SOCKET s, struct sockaddr *addr, int *addrlen)
+{
+    int r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = getsockname (s, addr, addrlen)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef getsockopt
+
+int 
+mygetsockopt (SOCKET s, int level, int optname, char *optval, int *optlen)
+{
+    int r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = getsockopt (s, level, optname, optval, optlen)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef ioctlsocket
+
+int 
+myioctlsocket (SOCKET s, long cmd, u_long *argp)
+{
+    int r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = ioctlsocket (s, cmd, argp)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef listen
+
+int 
+mylisten (SOCKET s, int backlog)
+{
+    int r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = listen (s, backlog)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef recv
+
+int 
+myrecv (SOCKET s, char *buf, int len, int flags)
+{
+    int r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = recv (s, buf, len, flags)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef recvfrom
+
+int 
+myrecvfrom (SOCKET s, char *buf, int len, int flags, 
+		struct sockaddr *from, int *fromlen)
+{
+    int r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = recvfrom (s, buf, len, flags, from, fromlen)) == SOCKET_ERROR)
+	errno =  WSAGetLastError();
+    return r;
+}
+
+#undef send
+
+int 
+mysend (SOCKET s, char *buf, int len, int flags)
+{
+    int r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = send (s, buf, len, flags)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef sendto
+
+int 
+mysendto (SOCKET s, char *buf, int len, int flags, 
+		struct sockaddr *to, int tolen)
+{
+    int r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = sendto (s, buf, len, flags, to, tolen)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef setsockopt
+
+int 
+mysetsockopt (SOCKET s, int level, int optname, char *optval, int optlen)
+{
+    int r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = setsockopt (s, level, optname, optval, optlen)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+    
+#undef shutdown
+
+int 
+myshutdown (SOCKET s, int how)
+{
+    int r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = shutdown (s, how)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef socket
+
+SOCKET 
+mysocket (int af, int type, int protocol)
+{
+    SOCKET s;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((s = socket (af, type, protocol)) == INVALID_SOCKET) {
+	errno = WSAGetLastError();
+	//fprintf(stderr, "socket fail (%d)", WSAGetLastError());
+    }
+    return s;
+}
+
+#undef gethostbyaddr
+
+struct hostent *
+mygethostbyaddr (char *addr, int len, int type)
+{
+    struct hostent *r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = gethostbyaddr (addr, len, type)) == NULL)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef gethostbyname
+
+struct hostent *
+mygethostbyname (char *name)
+{
+    struct hostent *r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = gethostbyname (name)) == NULL)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef gethostname
+
+int
+mygethostname (char *name, int len)
+{
+    int r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = gethostname (name, len)) == SOCKET_ERROR)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef getprotobyname
+
+struct protoent *
+mygetprotobyname (char *name)
+{
+    struct protoent *r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = getprotobyname (name)) == NULL)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef getprotobynumber
+
+struct protoent *
+mygetprotobynumber (int num)
+{
+    struct protoent *r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = getprotobynumber (num)) == NULL)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef getservbyname
+
+struct servent *
+mygetservbyname (char *name, char *proto)
+{
+    struct servent *r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = getservbyname (name, proto)) == NULL)
+	errno = WSAGetLastError();
+    return r;
+}
+
+#undef getservbyport
+
+struct servent *
+mygetservbyport (int port, char *proto)
+{
+    struct servent *r;
+    if (!NtSocketsInitialized++) {
+	StartSockets();
+    }
+    if ((r = getservbyport (port, proto)) == NULL)
+	errno = WSAGetLastError();
+    return r;
+}
+
+//
+// Networking stubs
+//
+
+void endhostent() {}
+void endnetent() {}
+void endprotoent() {}
+void endservent() {}
+
+struct netent *getnetent (void) {return (struct netent *) NULL;}
+
+struct netent *getnetbyaddr(char *name) {return (struct netent *)NULL;}
+
+struct netent *getnetbyname(long net, int type) {return (struct netent *)NULL;}
+
+struct protoent *getprotoent (void) {return (struct protoent *) NULL;}
+
+struct servent *getservent (void) {return (struct servent *) NULL;}
+
+void sethostent (int stayopen) {}
+
+void setnetent (int stayopen) {}
+
+void setprotoent (int stayopen) {}
+
+void setservent (int stayopen) {}
+
+
+#ifndef WNOHANG
+#define WNOHANG -1
+#endif
+
+pid_t
+waitpid (pid_t pid, int *stat_loc, int options)
+{
+    DWORD timeout;
+
+    if (options == WNOHANG) {
+	timeout = 0;
+    } else {
+	timeout = INFINITE;
+    }
+    if (WaitForSingleObject((HANDLE) pid, timeout) == WAIT_OBJECT_0) {
+	pid = _cwait(stat_loc, pid, 0);
+	return pid;
+    }
+    return 0;
+}
+
+#include <sys/timeb.h>
+
+int _cdecl
+gettimeofday(struct timeval *tv, struct timezone *tz)
+{                                
+    struct timeb tb;
+
+    ftime(&tb);
+    tv->tv_sec = tb.time;
+    tv->tv_usec = tb.millitm * 1000;
+	return 0;
+}
+
+char *
+getcwd(buffer, size)
+    char *buffer;
+    int size;
+{
+    int length;
+    char *bp;
+
+    if (_getcwd(buffer, size) == NULL) {
+        return NULL;
+    }
+    length = strlen(buffer);
+    if (length >= size) {
+        return NULL;
+    }
+
+    for (bp = buffer; *bp != '\0'; bp++) {
+	if (*bp == '\\') {
+	    *bp = '/';
+	}
+    }
+    return buffer;
+}
+
+static char *
+str_grow(struct RString *str, size_t new_size)
+{
+	char *p;
+
+	p = realloc(str->ptr, new_size);
+	if (p == NULL)
+                rb_fatal("cannot grow string\n");
+
+	str->len = new_size;
+	str->ptr = p;
+
+	return p;
+}
+
+int
+chown(char *path, int owner, int group)
+{
+	return 0;
+}
+
+int
+kill(int pid, int sig)
+{
+#if 1
+	if ((UINT)pid == GetCurrentProcessId())
+		return raise(sig);
+
+	if (sig == 2 && pid > 0)
+		if (GenerateConsoleCtrlEvent(CTRL_C_EVENT, (DWORD)pid))
+			return 0;
+
+	return -1;
+#else
+	return 0;
+#endif
+}
+
+int
+link(char *from, char *to)
+{
+	return -1;
+}
+
+int
+wait()
+{
+	return 0;
+}
+
diff -iNu ruby-1.3_org/missing/nt.h ruby-1.3/missing/nt.h
--- ruby-1.3_org/missing/nt.h	Wed Nov 25 12:31:19 1998
+++ ruby-1.3/missing/nt.h	Mon Jan 11 15:31:08 1999
@@ -22,47 +22,47 @@
 //
 // GRRRR!!!!  Windows Nonsense.
 // Define the following so we don't get tons of extra stuff
-// when we include windows.h 
+// when we include windows.h
 //
 #if 0
-#define NOGDICAPMASKS     
-#define NOVIRTUALKEYCODES 
-#define NOWINMESSAGES     
-#define NOWINSTYLES       
-#define NOSYSMETRICS      
-#define NOMENUS           
-#define NOICONS           
-#define NOKEYSTATES       
-#define NOSYSCOMMANDS     
-#define NORASTEROPS       
-#define NOSHOWWINDOW      
-#define OEMRESOURCE       
-#define NOATOM            
-#define NOCLIPBOARD       
-#define NOCOLOR           
-#define NOCTLMGR          
-#define NODRAWTEXT        
-#define NOGDI             
-//#define NOKERNEL        
-//#define NOUSER          
-#define NONLS             
-#define NOMB              
-#define NOMEMMGR          
-#define NOMETAFILE        
-#define NOMINMAX          
-#define NOMSG             
-#define NOOPENFILE        
-#define NOSCROLL          
-#define NOSERVICE         
-#define NOSOUND           
-#define NOTEXTMETRIC      
-#define NOWH              
-#define NOWINOFFSETS      
-#define NOCOMM            
-#define NOKANJI           
-#define NOHELP            
-#define NOPROFILER        
-#define NODEFERWINDOWPOS  
+#define NOGDICAPMASKS
+#define NOVIRTUALKEYCODES
+#define NOWINMESSAGES
+#define NOWINSTYLES
+#define NOSYSMETRICS
+#define NOMENUS
+#define NOICONS
+#define NOKEYSTATES
+#define NOSYSCOMMANDS
+#define NORASTEROPS
+#define NOSHOWWINDOW
+#define OEMRESOURCE
+#define NOATOM
+#define NOCLIPBOARD
+#define NOCOLOR
+#define NOCTLMGR
+#define NODRAWTEXT
+#define NOGDI
+//#define NOKERNEL
+//#define NOUSER
+#define NONLS
+#define NOMB
+#define NOMEMMGR
+#define NOMETAFILE
+#define NOMINMAX
+#define NOMSG
+#define NOOPENFILE
+#define NOSCROLL
+#define NOSERVICE
+#define NOSOUND
+#define NOTEXTMETRIC
+#define NOWH
+#define NOWINOFFSETS
+#define NOCOMM
+#define NOKANJI
+#define NOHELP
+#define NOPROFILER
+#define NODEFERWINDOWPOS
 #endif
 
 //
@@ -94,6 +94,8 @@
 #include <math.h>
 #include <sys/types.h>
 #include <sys/utime.h>
+#include <io.h>
+#include <malloc.h>
 
 //
 // Grrr...
@@ -148,10 +150,11 @@
 /* these are defined in nt.c */
 
 extern int NtMakeCmdVector(char *, char ***, int);
-/* extern void NtInitialize(int *, char ***); */
+EXTERN void NtInitialize(int *, char ***);
 extern char *NtGetLib(void);
 extern char *NtGetBin(void);
 extern FILE *mypopen(char *, char *);
+extern int   mypclose(FILE *);
 extern int  flock(int fd, int oper);
 extern FILE *  myfdopen(int, char*);
 extern SOCKET  myaccept(SOCKET, struct sockaddr *, int *);
@@ -177,6 +180,15 @@
 extern struct servent *  mygetservbyname(char *, char *);
 extern struct servent * mygetservbyport(int, char *);
 
+extern int vsnprintf(char *, size_t, const char *, va_list);
+extern int snprintf(char *, size_t, const char *, ...);
+extern int chown(char *, int, int);
+extern int link(char *, char *);
+extern int  gettimeofday(struct timeval *, struct timezone *);
+extern pid_t waitpid (pid_t, int *, int);
+extern int do_spawn(char *);
+extern int kill(int, int);
+
 //
 // define this so we can do inplace editing
 //
@@ -201,7 +213,7 @@
 extern int       setuid (int);
 extern int       setgid (int);
 
-
+
 #undef IN  /* confict in parse.c */
 
 #if 0
@@ -227,7 +239,9 @@
 #define EWOULDBLOCK 10035 /* EBASEERR + 35 (winsock.h) */
 #endif
 
+#ifndef O_BINARY
 #define O_BINARY 0x8000
+#endif
 
 #ifdef popen
 #undef popen
diff -iNu ruby-1.3_org/missing/strtol.c ruby-1.3/missing/strtol.c
--- ruby-1.3_org/missing/strtol.c	Fri Jan 16 21:13:08 1998
+++ ruby-1.3/missing/strtol.c	Fri Jan 15 21:47:42 1999
@@ -15,7 +15,7 @@
 
 #include <ctype.h>
 
-
+
 /*
  *----------------------------------------------------------------------
  *
diff -iNu ruby-1.3_org/missing/strtoul.c ruby-1.3/missing/strtoul.c
--- ruby-1.3_org/missing/strtoul.c	Fri Jan 16 21:13:08 1998
+++ ruby-1.3/missing/strtoul.c	Fri Jan 15 21:47:58 1999
@@ -31,7 +31,7 @@
     10, 11, 12, 13, 14, 15, 16, 17, 18, 19,	/* 'a' - 'z' */
     20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
     30, 31, 32, 33, 34, 35};
-
+
 /*
  *----------------------------------------------------------------------
  *
diff -iNu ruby-1.3_org/missing/vsnprintf.c ruby-1.3/missing/vsnprintf.c
--- ruby-1.3_org/missing/vsnprintf.c	Wed Nov 25 12:31:19 1998
+++ ruby-1.3/missing/vsnprintf.c	Mon Jan 04 22:43:10 1999
@@ -58,6 +58,13 @@
 */
 
 #include <sys/types.h>
+
+#ifdef NT
+//#include <string.h>
+//#include <stdlib.h>
+typedef unsigned int size_t ;
+#endif
+
 #define u_long unsigned long
 #define u_short unsigned short
 #define u_int unsigned int
---------8<-----ここまで---------8<-----

In This Thread

Prev Next