diff --git a/ChangeLog b/ChangeLog
index f44ab15eb7..df948679a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Mon Jun 19 10:48:28 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>
+
+	* variable.c (rb_cvar_set): forgot to add security check for class
+	  variable assignment.
+
 Sun Jun 18 22:49:13 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>
 
 	* configure.in: single quoted sitedir.
@@ -9,6 +14,33 @@ Sun Jun 18 22:49:13 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>
 	* ruby.c (load_file): force binmode if fname includes ".exe"
 	  on DOSISH.
 
+Sat Jun 17 23:22:17 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>
+
+	* sprintf.c (rb_f_sprintf): should ignore negative precision given
+	  by <%.*>.
+
+	* sprintf.c (rb_f_sprintf): should allow zero precision.
+
+Sat Jun 17 03:13:29 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>
+
+	* time.c (time_localtime): avoid unnecessary call of localtime.
+
+	* time.c (time_gmtime): avoid unnecessary call of gmtime.
+
+	* process.c (proc_wait2): new method.
+
+	* process.c (proc_waitpid): second argument made optional.
+
+	* process.c (proc_waitpid2): new method.
+
+Sat Jun 17 00:05:00 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>
+
+	* re.c (rb_reg_clone): should initialize member fields.
+
+Fri Jun 16 22:49:34 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>
+
+	* io.c (rb_io_rewind): set lineno to zero.
+
 Fri Jun 16 22:47:47 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>
 
 	* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.23.
@@ -21,6 +53,16 @@ Fri Jun 16 21:23:59 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>
 
 	* eval.c: define pause() if missing.
 
+Fri Jun 16 18:41:58 2000  Koji Arai  <JCA02266@nifty.ne.jp>
+
+	* process.c (proc_setsid): BSD-style setpgrp() don't return 
+	  process group ID, but 0 or -1.
+
+Fri Jun 16 16:23:35 2000  Koji Arai  <JCA02266@nifty.ne.jp>
+
+	* file.c (rb_stat_inspect): gives detailed information;
+	  compatibility with ruby-1.4.x.
+
 Fri Jun 16 05:18:45 2000  Yasuhiro Fukuma  <yasuf@bsdclub.org>
 
 	* configure.in: FreeBSD: do not link dummy libxpg4 which was
diff --git a/ToDo b/ToDo
index 27d436df24..c4654d9250 100644
--- a/ToDo
+++ b/ToDo
@@ -46,6 +46,7 @@ Hacking Interpreter
 * performance tune for in-block (dynamic) local variables.
 * generational GC ?
 * give warnings to assign magic variables.
+* export rb_io_{addstr,printf,puts,print}
 
 Standard Libraries
 
diff --git a/configure.in b/configure.in
index 98ebba57a7..d0d31cd724 100644
--- a/configure.in
+++ b/configure.in
@@ -219,10 +219,10 @@ AC_REPLACE_FUNCS(dup2 memmove mkdir strcasecmp strncasecmp strerror strftime\
 		 strchr strstr strtoul strdup crypt flock vsnprintf\
 		 isinf isnan finite)
 AC_CHECK_FUNCS(fmod killpg drand48 random wait4 waitpid syscall getcwd\
-	      truncate chsize times utimes fcntl lockf setitimer\
+	      truncate chsize times utimes fcntl lockf setitimer pause\
 	      setruid seteuid setreuid setrgid setegid setregid\
 	      getpgrp setpgrp getpgid setpgid getgroups getpriority\
-	      dlopen sigprocmask sigaction _setjmp setsid getrlimit pause)
+	      dlopen sigprocmask sigaction _setjmp setsid getrlimit)
 AC_STRUCT_TIMEZONE
 AC_CACHE_CHECK(for external int daylight, rb_cv_have_daylight,
   [AC_TRY_LINK([#include <time.h>
diff --git a/eval.c b/eval.c
index 0282bbda02..5afb4aa48c 100644
--- a/eval.c
+++ b/eval.c
@@ -4558,9 +4558,9 @@ eval(self, src, scope, file, line)
 	    VALUE err;
 	    VALUE errat;
 
-	    errat = get_backtrace(ruby_errinfo);
 	    if (strcmp(file, "(eval)") == 0) {
 		if (ruby_sourceline > 1) {
+		    errat = get_backtrace(ruby_errinfo);
 		    err = RARRAY(errat)->ptr[0];
 		    rb_str_cat2(err, ": ");
 		    rb_str_append(err, ruby_errinfo);
@@ -6289,7 +6289,7 @@ enum thread_status {
 /* +infty, for this purpose */
 #define DELAY_INFTY 1E30
 
-typedef struct thread * thread_t;
+typedef struct thread * rb_thread_t;
 
 struct thread {
     struct thread *next, *prev;
@@ -6332,7 +6332,7 @@ struct thread {
     fd_set exceptfds;
     int select_value;
     double delay;
-    thread_t join;
+    rb_thread_t join;
 
     int abort;
     int priority;
@@ -6345,8 +6345,8 @@ struct thread {
 
 #define THREAD_RAISED 0x200
 
-static thread_t main_thread;
-static thread_t curr_thread = 0;
+static rb_thread_t main_thread;
+static rb_thread_t curr_thread = 0;
 
 #define FOREACH_THREAD_FROM(f,x) x = f; do { x = x->next;
 #define END_FOREACH_FROM(f,x) } while (x != f)
@@ -6368,7 +6368,7 @@ timeofday()
 
 static void
 thread_mark(th)
-    thread_t th;
+    rb_thread_t th;
 {
     struct FRAME *frame;
     struct BLOCK *block;
@@ -6423,7 +6423,7 @@ thread_mark(th)
 void
 rb_gc_mark_threads()
 {
-    thread_t th;
+    rb_thread_t th;
 
     if (!curr_thread) return;
     FOREACH_THREAD(th) {
@@ -6433,7 +6433,7 @@ rb_gc_mark_threads()
 
 static void
 thread_free(th)
-    thread_t th;
+    rb_thread_t th;
 {
     if (th->stk_ptr) free(th->stk_ptr);
     th->stk_ptr = 0;
@@ -6445,7 +6445,7 @@ thread_free(th)
     if (th != main_thread) free(th);
 }
 
-static thread_t
+static rb_thread_t
 rb_thread_check(data)
     VALUE data;
 {
@@ -6453,7 +6453,7 @@ rb_thread_check(data)
 	rb_raise(rb_eTypeError, "wrong argument type %s (expected Thread)",
 		 rb_class2name(CLASS_OF(data)));
     }
-    return (thread_t)RDATA(data)->data;
+    return (rb_thread_t)RDATA(data)->data;
 }
 
 static int   th_raise_argc;
@@ -6473,7 +6473,7 @@ static char *th_signm;
 
 static void
 rb_thread_save_context(th)
-    thread_t th;
+    rb_thread_t th;
 {
     VALUE v;
 
@@ -6547,11 +6547,11 @@ thread_switch(n)
 #define THREAD_SAVE_CONTEXT(th) \
     (rb_thread_save_context(th),thread_switch(setjmp((th)->context)))
 
-static void rb_thread_restore_context _((thread_t,int));
+static void rb_thread_restore_context _((rb_thread_t,int));
 
 static void
 stack_extend(th, exit)
-    thread_t th;
+    rb_thread_t th;
     int exit;
 {
     VALUE space[1024];
@@ -6562,11 +6562,11 @@ stack_extend(th, exit)
 
 static void
 rb_thread_restore_context(th, exit)
-    thread_t th;
+    rb_thread_t th;
     int exit;
 {
     VALUE v;
-    static thread_t tmp;
+    static rb_thread_t tmp;
     static int ex;
 
     if (!th->stk_ptr) rb_bug("unsaved context");
@@ -6611,7 +6611,7 @@ rb_thread_restore_context(th, exit)
 
 static void
 rb_thread_ready(th)
-    thread_t th;
+    rb_thread_t th;
 {
     th->wait_for = 0;
     th->status = THREAD_RUNNABLE;
@@ -6628,7 +6628,7 @@ rb_thread_remove()
 
 static int
 rb_thread_dead(th)
-    thread_t th;
+    rb_thread_t th;
 {
     return th->status == THREAD_KILLED;
 }
@@ -6637,7 +6637,7 @@ void
 rb_thread_fd_close(fd)
     int fd;
 {
-    thread_t th;
+    rb_thread_t th;
 
     FOREACH_THREAD(th) {
 	if ((th->wait_for & WAIT_FD) && fd == th->fd) {
@@ -6740,9 +6740,9 @@ find_bad_fds(dst, src, max)
 void
 rb_thread_schedule()
 {
-    thread_t next;		/* OK */
-    thread_t th;
-    thread_t curr;
+    rb_thread_t next;		/* OK */
+    rb_thread_t th;
+    rb_thread_t curr;
     int found = 0;
 
     fd_set readfds;
@@ -7093,7 +7093,7 @@ static VALUE
 rb_thread_join(thread)
     VALUE thread;
 {
-    thread_t th = rb_thread_check(thread);
+    rb_thread_t th = rb_thread_check(thread);
 
     if (!rb_thread_dead(th)) {
 	if (th == curr_thread)
@@ -7135,7 +7135,7 @@ rb_thread_main()
 VALUE
 rb_thread_list()
 {
-    thread_t th;
+    rb_thread_t th;
     VALUE ary = rb_ary_new();
 
     FOREACH_THREAD(th) {
@@ -7156,7 +7156,7 @@ VALUE
 rb_thread_wakeup(thread)
     VALUE thread;
 {
-    thread_t th = rb_thread_check(thread);
+    rb_thread_t th = rb_thread_check(thread);
 
     if (th->status == THREAD_KILLED)
 	rb_raise(rb_eThreadError, "killed thread");
@@ -7179,7 +7179,7 @@ static VALUE
 rb_thread_kill(thread)
     VALUE thread;
 {
-    thread_t th = rb_thread_check(thread);
+    rb_thread_t th = rb_thread_check(thread);
 
     if (th != curr_thread && th->safe < 4) {
 	rb_secure(4);
@@ -7259,7 +7259,11 @@ rb_thread_sleep_forever()
 {
     if (curr_thread == curr_thread->next) {
 	TRAP_BEG;
+#ifdef HAVE_PAUSE
 	pause();
+#else
+	sleep((32767<<16)+32767);
+#endif
 	TRAP_END;
 	return;
     }
@@ -7274,7 +7278,7 @@ static VALUE
 rb_thread_priority(thread)
     VALUE thread;
 {
-    thread_t th = rb_thread_check(thread);;
+    rb_thread_t th = rb_thread_check(thread);;
 
     if (rb_safe_level() >= 4 && th != curr_thread) {
 	rb_raise(rb_eSecurityError, "Insecure: can't get priority");
@@ -7286,7 +7290,7 @@ static VALUE
 rb_thread_priority_set(thread, prio)
     VALUE thread, prio;
 {
-    thread_t th;
+    rb_thread_t th;
 
     rb_secure(4);
     th = rb_thread_check(thread);
@@ -7300,7 +7304,7 @@ static VALUE
 rb_thread_safe_level(thread)
     VALUE thread;
 {
-    thread_t th;
+    rb_thread_t th;
 
     th = rb_thread_check(thread);
     if (th == curr_thread) {
@@ -7330,7 +7334,7 @@ static VALUE
 rb_thread_abort_exc(thread)
     VALUE thread;
 {
-    thread_t th = rb_thread_check(thread);
+    rb_thread_t th = rb_thread_check(thread);
 
     return th->abort?Qtrue:Qfalse;
 }
@@ -7339,7 +7343,7 @@ static VALUE
 rb_thread_abort_exc_set(thread, val)
     VALUE thread, val;
 {
-    thread_t th = rb_thread_check(thread);
+    rb_thread_t th = rb_thread_check(thread);
 
     rb_secure(4);
     th->abort = RTEST(val);
@@ -7382,11 +7386,11 @@ rb_thread_abort_exc_set(thread, val)
     th->locals = 0;\
 } while(0)
 
-static thread_t
+static rb_thread_t
 rb_thread_alloc(klass)
     VALUE klass;
 {
-    thread_t th;
+    rb_thread_t th;
 
     THREAD_ALLOC(th);
     th->thread = Data_Wrap_Struct(klass, thread_mark, thread_free, th);
@@ -7462,7 +7466,7 @@ static VALUE
 rb_thread_start_0(fn, arg, th)
     VALUE (*fn)();
     void *arg;
-    thread_t th;
+    rb_thread_t th;
 {
     volatile VALUE thread = th->thread;
     enum thread_status status;
@@ -7539,7 +7543,7 @@ rb_thread_scope_shared_p()
 static VALUE
 rb_thread_yield(arg, th) 
     VALUE arg;
-    thread_t th;
+    rb_thread_t th;
 {
     scope_dup(ruby_block->scope);
     return rb_yield_0(callargs(arg), 0, 0, Qfalse);
@@ -7551,7 +7555,7 @@ rb_thread_s_new(argc, argv, klass)
     VALUE *argv;
     VALUE klass;
 {
-    thread_t th = rb_thread_alloc(klass);
+    rb_thread_t th = rb_thread_alloc(klass);
     volatile VALUE *pos;
 
     THREAD_SAVE_CONTEXT(th);
@@ -7589,7 +7593,7 @@ static VALUE
 rb_thread_value(thread)
     VALUE thread;
 {
-    thread_t th = rb_thread_check(thread);
+    rb_thread_t th = rb_thread_check(thread);
 
     rb_thread_join(thread);
 
@@ -7600,7 +7604,7 @@ static VALUE
 rb_thread_status(thread)
     VALUE thread;
 {
-    thread_t th = rb_thread_check(thread);
+    rb_thread_t th = rb_thread_check(thread);
 
     if (rb_thread_dead(th)) {
 	if (NIL_P(th->errinfo) && (th->flags & THREAD_RAISED))
@@ -7617,7 +7621,7 @@ static VALUE
 rb_thread_alive_p(thread)
     VALUE thread;
 {
-    thread_t th = rb_thread_check(thread);
+    rb_thread_t th = rb_thread_check(thread);
 
     if (rb_thread_dead(th)) return Qfalse;
     return Qtrue;
@@ -7627,7 +7631,7 @@ static VALUE
 rb_thread_stop_p(thread)
     VALUE thread;
 {
-    thread_t th = rb_thread_check(thread);
+    rb_thread_t th = rb_thread_check(thread);
 
     if (rb_thread_dead(th)) return Qtrue;
     if (th->status == THREAD_STOPPED) return Qtrue;
@@ -7646,7 +7650,7 @@ rb_thread_wait_other_threads()
 static void
 rb_thread_cleanup()
 {
-    thread_t th;
+    rb_thread_t th;
 
     if (curr_thread != curr_thread->next->prev) {
 	curr_thread = curr_thread->prev;
@@ -7754,7 +7758,7 @@ rb_thread_raise(argc, argv, thread)
     VALUE *argv;
     VALUE thread;
 {
-    thread_t th = rb_thread_check(thread);
+    rb_thread_t th = rb_thread_check(thread);
 
     if (rb_thread_dead(th)) return Qnil;
     if (curr_thread == th) {
@@ -7813,7 +7817,7 @@ rb_thread_local_aref(thread, id)
     VALUE thread;
     ID id;
 {
-    thread_t th;
+    rb_thread_t th;
     VALUE val;
 
     th = rb_thread_check(thread);
@@ -7840,7 +7844,7 @@ rb_thread_local_aset(thread, id, val)
     ID id;
     VALUE val;
 {
-    thread_t th = rb_thread_check(thread);
+    rb_thread_t th = rb_thread_check(thread);
 
     if (rb_safe_level() >= 4 && th != curr_thread) {
 	rb_raise(rb_eSecurityError, "Insecure: can't modify thread locals");
@@ -7870,7 +7874,7 @@ static VALUE
 rb_thread_key_p(thread, id)
     VALUE thread, id;
 {
-    thread_t th = rb_thread_check(thread);
+    rb_thread_t th = rb_thread_check(thread);
 
     if (!th->locals) return Qfalse;
     if (st_lookup(th->locals, rb_to_id(id), 0))
@@ -7883,7 +7887,7 @@ rb_thread_inspect(thread)
     VALUE thread;
 {
     char *cname = rb_class2name(CLASS_OF(thread));
-    thread_t th = rb_thread_check(thread);
+    rb_thread_t th = rb_thread_check(thread);
     char *s, *status;
     VALUE str;
 
@@ -7914,7 +7918,7 @@ rb_callcc(self)
     VALUE self;
 {
     volatile VALUE cont;
-    thread_t th;
+    rb_thread_t th;
     struct tag *tag;
 
     THREAD_ALLOC(th);
@@ -7940,7 +7944,7 @@ rb_cont_call(argc, argv, cont)
     VALUE *argv;
     VALUE cont;
 {
-    thread_t th = rb_thread_check(cont);
+    rb_thread_t th = rb_thread_check(cont);
 
     switch (argc) {
     case 0:
@@ -7984,7 +7988,7 @@ thgroup_list(group)
     VALUE group;
 {
     struct thgroup *data;
-    thread_t th;
+    rb_thread_t th;
     VALUE ary;
 
     Data_Get_Struct(group, struct thgroup, data);
@@ -8004,7 +8008,7 @@ static VALUE
 thgroup_add(group, thread)
     VALUE group, thread;
 {
-    thread_t th;
+    rb_thread_t th;
     struct thgroup *data;
 
     rb_secure(4);
diff --git a/file.c b/file.c
index 29cea5471d..a5db21ddcc 100644
--- a/file.c
+++ b/file.c
@@ -251,6 +251,53 @@ rb_stat_ctime(self)
     return rb_time_new(get_stat(self)->st_ctime, 0);
 }
 
+static VALUE
+rb_stat_inspect(self)
+    VALUE self;
+{
+    VALUE str;
+    int i;
+    struct {
+        char *name;
+        VALUE (*func)();
+    } member[] = {
+        {"dev",     rb_stat_dev},
+        {"ino",     rb_stat_ino},
+        {"mode",    rb_stat_mode},
+        {"nlink",   rb_stat_nlink},
+        {"uid",     rb_stat_uid},
+        {"gid",     rb_stat_gid},
+        {"rdev",    rb_stat_rdev},
+        {"size",    rb_stat_size},
+        {"blksize", rb_stat_blksize},
+        {"blocks",  rb_stat_blocks},
+        {"atime",   rb_stat_atime},
+        {"mtime",   rb_stat_mtime},
+        {"ctime",   rb_stat_ctime},
+    };
+
+    str = rb_str_new2("#<");
+    rb_str_cat2(str, rb_class2name(CLASS_OF(self)));
+    rb_str_cat2(str, " ");
+
+    for (i = 0; i < sizeof(member)/sizeof(member[0]); i++) {
+	VALUE str2;
+	char *p;
+
+	if (i > 0) {
+	    rb_str_cat2(str, ", ");
+	}
+	rb_str_cat2(str, member[i].name);
+	rb_str_cat2(str, "=");
+	str2 = rb_inspect((*member[i].func)(self));
+	rb_str_append(str, str2);
+    }
+    rb_str_cat2(str, ">");
+    OBJ_INFECT(str, self);
+
+    return str;
+}
+
 static int
 rb_stat(file, st)
     VALUE file;
@@ -2216,6 +2263,8 @@ Init_File()
     rb_define_method(rb_cStat, "mtime", rb_stat_mtime, 0);
     rb_define_method(rb_cStat, "ctime", rb_stat_ctime, 0);
 
+    rb_define_method(rb_cStat, "inspect", rb_stat_inspect, 0);
+
     rb_define_method(rb_cStat, "ftype", rb_stat_ftype, 0);
 
     rb_define_method(rb_cStat, "directory?",  rb_stat_d, 0);
diff --git a/io.c b/io.c
index 9f6631dfbf..cbc4719094 100644
--- a/io.c
+++ b/io.c
@@ -334,6 +334,10 @@ rb_io_rewind(io)
     GetOpenFile(io, fptr);
     if (fseek(fptr->f, 0L, 0) != 0) rb_sys_fail(fptr->path);
     clearerr(fptr->f);
+    if (io == current_file) {
+	gets_lineno -= fptr->lineno;
+    }
+    fptr->lineno = 0;
 
     return INT2FIX(0);
 }
diff --git a/process.c b/process.c
index 8077de5495..9a19d0145e 100644
--- a/process.c
+++ b/process.c
@@ -186,13 +186,26 @@ proc_wait()
 }
 
 static VALUE
-proc_waitpid(obj, vpid, vflags)
-    VALUE obj, vpid, vflags;
+proc_wait2()
 {
+    VALUE pid = proc_wait();
+
+    return rb_assoc_new(pid, rb_last_status);
+}
+
+static VALUE
+proc_waitpid(argc, argv)
+    int argc;
+    VALUE *argv;
+{
+    VALUE vpid, vflags;
     int pid, flags, status;
 
-    if (NIL_P(vflags)) flags = 0;
-    else flags = NUM2UINT(vflags);
+    flags = 0;
+    rb_scan_args(argc, argv, "11", &vpid, &vflags);
+    if (argc == 2 && !NIL_P(vflags)) {
+	flags = NUM2UINT(vflags);
+    }
 
     if ((pid = rb_waitpid(NUM2INT(vpid), flags, &status)) < 0)
 	rb_sys_fail(0);
@@ -200,6 +213,15 @@ proc_waitpid(obj, vpid, vflags)
     return INT2FIX(pid);
 }
 
+static VALUE
+proc_waitpid2(argc, argv)
+    int argc;
+    VALUE *argv;
+{
+    VALUE pid = proc_waitpid2(argc, argv);
+    return rb_assoc_new(pid, rb_last_status);
+}
+
 char *strtok();
 
 #ifdef HAVE_SETITIMER
@@ -834,21 +856,26 @@ proc_setsid()
     if (pid < 0) rb_sys_fail(0);
     return INT2FIX(pid);
 #elif defined(HAVE_SETPGRP) && defined(TIOCNOTTY)
-  pid_t sid;
+  pid_t pid;
+  int ret;
 
+  rb_secure(2);
+  pid = getpid();
 #if defined(SETPGRP_VOID)
-  sid = setpgrp();
+  ret = setpgrp();
+  /* If `pid_t setpgrp(void)' is equivalent to setsid(),
+     `ret' will be the same value as `pid', and following open() will fail.
+     In Linux, `int setpgrp(void)' is equivalent to setpgid(0, 0). */
 #else
-  sid = setpgrp(0, getpid());
+  ret = setpgrp(0, pid);
 #endif
-  if (sid == -1) return -1;
+  if (ret == -1) rb_sys_fail(0);
 
   if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
     ioctl(fd, TIOCNOTTY, NULL);
     close(fd);
   }
-  return sid;
-}
+  return INT2FIX(pid);
 #else
     rb_notimplement();
 #endif
@@ -1046,7 +1073,9 @@ Init_process()
     rb_define_module_function(rb_mProcess, "kill", rb_f_kill, -1);
 #ifndef NT
     rb_define_module_function(rb_mProcess, "wait", proc_wait, 0);
-    rb_define_module_function(rb_mProcess, "waitpid", proc_waitpid, 2);
+    rb_define_module_function(rb_mProcess, "wait2", proc_wait2, 0);
+    rb_define_module_function(rb_mProcess, "waitpid", proc_waitpid, -1);
+    rb_define_module_function(rb_mProcess, "waitpid2", proc_waitpid2, -1);
 
     rb_define_module_function(rb_mProcess, "pid", get_pid, 0);
     rb_define_module_function(rb_mProcess, "ppid", get_ppid, 0);
diff --git a/re.c b/re.c
index 6f4dcc2ff2..a28ac4a235 100644
--- a/re.c
+++ b/re.c
@@ -1145,6 +1145,7 @@ rb_reg_clone(re)
     NEWOBJ(clone, struct RRegexp);
     CLONESETUP(clone, re);
     rb_reg_check(re);
+    clone->ptr = 0; clone->len = 0;
     rb_reg_initialize(clone, RREGEXP(re)->str, RREGEXP(re)->len,
 		      rb_reg_options(re));
     return (VALUE)re;
diff --git a/sprintf.c b/sprintf.c
index 204ea145d2..a3350b4578 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -264,13 +264,15 @@ rb_f_sprintf(argc, argv)
 	    if (flags & FPREC) {
 		rb_raise(rb_eArgError, "precision given twice");
 	    }
+	    flags |= FPREC;
 
 	    prec = 0;
 	    p++;
 	    if (*p == '*') {
 		GETASTER(prec);
-		if (prec > 0)
-		    flags |= FPREC;
+		if (prec < 0) {	/* ignore negative precision */
+		    flags &= ~FPREC;
+		}
 		p++;
 		goto retry;
 	    }
@@ -281,8 +283,6 @@ rb_f_sprintf(argc, argv)
 	    if (p >= end) {
 		rb_raise(rb_eArgError, "malformed format string - %%.[0-9]");
 	    }
-	    if (prec > 0)
-		flags |= FPREC;
 	    goto retry;
 
 	  case '\n':
diff --git a/time.c b/time.c
index 5c3dcaebf5..9028b7337d 100644
--- a/time.c
+++ b/time.c
@@ -490,7 +490,7 @@ time_eql(time1, time2)
 }
 
 static VALUE
-time_gmt_p(time)
+time_utc_p(time)
     VALUE time;
 {
     struct time_object *tobj;
@@ -536,6 +536,9 @@ time_localtime(time)
     time_t t;
 
     GetTimeval(time, tobj);
+    if (tobj->tm_got && !tobj->gmt) {
+	return time;
+    }
     t = tobj->tv.tv_sec;
     tm_tmp = localtime(&t);
     tobj->tm = *tm_tmp;
@@ -553,6 +556,9 @@ time_gmtime(time)
     time_t t;
 
     GetTimeval(time, tobj);
+    if (tobj->tm_got && tobj->gmt) {
+	return time;
+    }
     t = tobj->tv.tv_sec;
     tm_tmp = gmtime(&t);
     tobj->tm = *tm_tmp;
@@ -1077,7 +1083,8 @@ Init_Time()
     rb_define_method(rb_cTime, "isdst", time_isdst, 0);
     rb_define_method(rb_cTime, "zone", time_zone, 0);
 
-    rb_define_method(rb_cTime, "gmt?", time_gmt_p, 0);
+    rb_define_method(rb_cTime, "utc?", time_utc_p, 0);
+    rb_define_method(rb_cTime, "gmt?", time_utc_p, 0);
 
     rb_define_method(rb_cTime, "tv_sec", time_to_i, 0);
     rb_define_method(rb_cTime, "tv_usec", time_usec, 0);
diff --git a/variable.c b/variable.c
index e3da3615f0..177f61c76d 100644
--- a/variable.c
+++ b/variable.c
@@ -1337,6 +1337,8 @@ rb_cvar_set(klass, id, val)
 {
     VALUE tmp;
 
+    if (!OBJ_TAINTED(klass) && rb_safe_level() >= 4)
+	rb_raise(rb_eSecurityError, "Insecure: can't modify class variable");
     if (FL_TEST(klass, FL_SINGLETON)) {
 	klass = rb_iv_get(klass, "__attached__");
     }
diff --git a/version.h b/version.h
index c60e74ae9c..e5cbb64667 100644
--- a/version.h
+++ b/version.h
@@ -1,4 +1,4 @@
 #define RUBY_VERSION "1.5.4"
-#define RUBY_RELEASE_DATE "2000-06-16"
+#define RUBY_RELEASE_DATE "2000-06-19"
 #define RUBY_VERSION_CODE 154
-#define RUBY_RELEASE_CODE 20000616
+#define RUBY_RELEASE_CODE 20000619