2000-06-19

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@767 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2000-06-19 08:38:11 +00:00
parent c613f625b7
commit b8148f4594
12 changed files with 209 additions and 70 deletions

View File

@ -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> Sun Jun 18 22:49:13 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
* configure.in: single quoted sitedir. * 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" * ruby.c (load_file): force binmode if fname includes ".exe"
on DOSISH. 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> 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. * 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. * 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> Fri Jun 16 05:18:45 2000 Yasuhiro Fukuma <yasuf@bsdclub.org>
* configure.in: FreeBSD: do not link dummy libxpg4 which was * configure.in: FreeBSD: do not link dummy libxpg4 which was

1
ToDo
View File

@ -46,6 +46,7 @@ Hacking Interpreter
* performance tune for in-block (dynamic) local variables. * performance tune for in-block (dynamic) local variables.
* generational GC ? * generational GC ?
* give warnings to assign magic variables. * give warnings to assign magic variables.
* export rb_io_{addstr,printf,puts,print}
Standard Libraries Standard Libraries

View File

@ -219,10 +219,10 @@ AC_REPLACE_FUNCS(dup2 memmove mkdir strcasecmp strncasecmp strerror strftime\
strchr strstr strtoul strdup crypt flock vsnprintf\ strchr strstr strtoul strdup crypt flock vsnprintf\
isinf isnan finite) isinf isnan finite)
AC_CHECK_FUNCS(fmod killpg drand48 random wait4 waitpid syscall getcwd\ 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\ setruid seteuid setreuid setrgid setegid setregid\
getpgrp setpgrp getpgid setpgid getgroups getpriority\ getpgrp setpgrp getpgid setpgid getgroups getpriority\
dlopen sigprocmask sigaction _setjmp setsid getrlimit pause) dlopen sigprocmask sigaction _setjmp setsid getrlimit)
AC_STRUCT_TIMEZONE AC_STRUCT_TIMEZONE
AC_CACHE_CHECK(for external int daylight, rb_cv_have_daylight, AC_CACHE_CHECK(for external int daylight, rb_cv_have_daylight,
[AC_TRY_LINK([#include <time.h> [AC_TRY_LINK([#include <time.h>

102
eval.c
View File

@ -4558,9 +4558,9 @@ eval(self, src, scope, file, line)
VALUE err; VALUE err;
VALUE errat; VALUE errat;
errat = get_backtrace(ruby_errinfo);
if (strcmp(file, "(eval)") == 0) { if (strcmp(file, "(eval)") == 0) {
if (ruby_sourceline > 1) { if (ruby_sourceline > 1) {
errat = get_backtrace(ruby_errinfo);
err = RARRAY(errat)->ptr[0]; err = RARRAY(errat)->ptr[0];
rb_str_cat2(err, ": "); rb_str_cat2(err, ": ");
rb_str_append(err, ruby_errinfo); rb_str_append(err, ruby_errinfo);
@ -6289,7 +6289,7 @@ enum thread_status {
/* +infty, for this purpose */ /* +infty, for this purpose */
#define DELAY_INFTY 1E30 #define DELAY_INFTY 1E30
typedef struct thread * thread_t; typedef struct thread * rb_thread_t;
struct thread { struct thread {
struct thread *next, *prev; struct thread *next, *prev;
@ -6332,7 +6332,7 @@ struct thread {
fd_set exceptfds; fd_set exceptfds;
int select_value; int select_value;
double delay; double delay;
thread_t join; rb_thread_t join;
int abort; int abort;
int priority; int priority;
@ -6345,8 +6345,8 @@ struct thread {
#define THREAD_RAISED 0x200 #define THREAD_RAISED 0x200
static thread_t main_thread; static rb_thread_t main_thread;
static thread_t curr_thread = 0; static rb_thread_t curr_thread = 0;
#define FOREACH_THREAD_FROM(f,x) x = f; do { x = x->next; #define FOREACH_THREAD_FROM(f,x) x = f; do { x = x->next;
#define END_FOREACH_FROM(f,x) } while (x != f) #define END_FOREACH_FROM(f,x) } while (x != f)
@ -6368,7 +6368,7 @@ timeofday()
static void static void
thread_mark(th) thread_mark(th)
thread_t th; rb_thread_t th;
{ {
struct FRAME *frame; struct FRAME *frame;
struct BLOCK *block; struct BLOCK *block;
@ -6423,7 +6423,7 @@ thread_mark(th)
void void
rb_gc_mark_threads() rb_gc_mark_threads()
{ {
thread_t th; rb_thread_t th;
if (!curr_thread) return; if (!curr_thread) return;
FOREACH_THREAD(th) { FOREACH_THREAD(th) {
@ -6433,7 +6433,7 @@ rb_gc_mark_threads()
static void static void
thread_free(th) thread_free(th)
thread_t th; rb_thread_t th;
{ {
if (th->stk_ptr) free(th->stk_ptr); if (th->stk_ptr) free(th->stk_ptr);
th->stk_ptr = 0; th->stk_ptr = 0;
@ -6445,7 +6445,7 @@ thread_free(th)
if (th != main_thread) free(th); if (th != main_thread) free(th);
} }
static thread_t static rb_thread_t
rb_thread_check(data) rb_thread_check(data)
VALUE data; VALUE data;
{ {
@ -6453,7 +6453,7 @@ rb_thread_check(data)
rb_raise(rb_eTypeError, "wrong argument type %s (expected Thread)", rb_raise(rb_eTypeError, "wrong argument type %s (expected Thread)",
rb_class2name(CLASS_OF(data))); rb_class2name(CLASS_OF(data)));
} }
return (thread_t)RDATA(data)->data; return (rb_thread_t)RDATA(data)->data;
} }
static int th_raise_argc; static int th_raise_argc;
@ -6473,7 +6473,7 @@ static char *th_signm;
static void static void
rb_thread_save_context(th) rb_thread_save_context(th)
thread_t th; rb_thread_t th;
{ {
VALUE v; VALUE v;
@ -6547,11 +6547,11 @@ thread_switch(n)
#define THREAD_SAVE_CONTEXT(th) \ #define THREAD_SAVE_CONTEXT(th) \
(rb_thread_save_context(th),thread_switch(setjmp((th)->context))) (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 static void
stack_extend(th, exit) stack_extend(th, exit)
thread_t th; rb_thread_t th;
int exit; int exit;
{ {
VALUE space[1024]; VALUE space[1024];
@ -6562,11 +6562,11 @@ stack_extend(th, exit)
static void static void
rb_thread_restore_context(th, exit) rb_thread_restore_context(th, exit)
thread_t th; rb_thread_t th;
int exit; int exit;
{ {
VALUE v; VALUE v;
static thread_t tmp; static rb_thread_t tmp;
static int ex; static int ex;
if (!th->stk_ptr) rb_bug("unsaved context"); if (!th->stk_ptr) rb_bug("unsaved context");
@ -6611,7 +6611,7 @@ rb_thread_restore_context(th, exit)
static void static void
rb_thread_ready(th) rb_thread_ready(th)
thread_t th; rb_thread_t th;
{ {
th->wait_for = 0; th->wait_for = 0;
th->status = THREAD_RUNNABLE; th->status = THREAD_RUNNABLE;
@ -6628,7 +6628,7 @@ rb_thread_remove()
static int static int
rb_thread_dead(th) rb_thread_dead(th)
thread_t th; rb_thread_t th;
{ {
return th->status == THREAD_KILLED; return th->status == THREAD_KILLED;
} }
@ -6637,7 +6637,7 @@ void
rb_thread_fd_close(fd) rb_thread_fd_close(fd)
int fd; int fd;
{ {
thread_t th; rb_thread_t th;
FOREACH_THREAD(th) { FOREACH_THREAD(th) {
if ((th->wait_for & WAIT_FD) && fd == th->fd) { if ((th->wait_for & WAIT_FD) && fd == th->fd) {
@ -6740,9 +6740,9 @@ find_bad_fds(dst, src, max)
void void
rb_thread_schedule() rb_thread_schedule()
{ {
thread_t next; /* OK */ rb_thread_t next; /* OK */
thread_t th; rb_thread_t th;
thread_t curr; rb_thread_t curr;
int found = 0; int found = 0;
fd_set readfds; fd_set readfds;
@ -7093,7 +7093,7 @@ static VALUE
rb_thread_join(thread) rb_thread_join(thread)
VALUE thread; VALUE thread;
{ {
thread_t th = rb_thread_check(thread); rb_thread_t th = rb_thread_check(thread);
if (!rb_thread_dead(th)) { if (!rb_thread_dead(th)) {
if (th == curr_thread) if (th == curr_thread)
@ -7135,7 +7135,7 @@ rb_thread_main()
VALUE VALUE
rb_thread_list() rb_thread_list()
{ {
thread_t th; rb_thread_t th;
VALUE ary = rb_ary_new(); VALUE ary = rb_ary_new();
FOREACH_THREAD(th) { FOREACH_THREAD(th) {
@ -7156,7 +7156,7 @@ VALUE
rb_thread_wakeup(thread) rb_thread_wakeup(thread)
VALUE thread; VALUE thread;
{ {
thread_t th = rb_thread_check(thread); rb_thread_t th = rb_thread_check(thread);
if (th->status == THREAD_KILLED) if (th->status == THREAD_KILLED)
rb_raise(rb_eThreadError, "killed thread"); rb_raise(rb_eThreadError, "killed thread");
@ -7179,7 +7179,7 @@ static VALUE
rb_thread_kill(thread) rb_thread_kill(thread)
VALUE 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) { if (th != curr_thread && th->safe < 4) {
rb_secure(4); rb_secure(4);
@ -7259,7 +7259,11 @@ rb_thread_sleep_forever()
{ {
if (curr_thread == curr_thread->next) { if (curr_thread == curr_thread->next) {
TRAP_BEG; TRAP_BEG;
#ifdef HAVE_PAUSE
pause(); pause();
#else
sleep((32767<<16)+32767);
#endif
TRAP_END; TRAP_END;
return; return;
} }
@ -7274,7 +7278,7 @@ static VALUE
rb_thread_priority(thread) rb_thread_priority(thread)
VALUE 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) { if (rb_safe_level() >= 4 && th != curr_thread) {
rb_raise(rb_eSecurityError, "Insecure: can't get priority"); rb_raise(rb_eSecurityError, "Insecure: can't get priority");
@ -7286,7 +7290,7 @@ static VALUE
rb_thread_priority_set(thread, prio) rb_thread_priority_set(thread, prio)
VALUE thread, prio; VALUE thread, prio;
{ {
thread_t th; rb_thread_t th;
rb_secure(4); rb_secure(4);
th = rb_thread_check(thread); th = rb_thread_check(thread);
@ -7300,7 +7304,7 @@ static VALUE
rb_thread_safe_level(thread) rb_thread_safe_level(thread)
VALUE thread; VALUE thread;
{ {
thread_t th; rb_thread_t th;
th = rb_thread_check(thread); th = rb_thread_check(thread);
if (th == curr_thread) { if (th == curr_thread) {
@ -7330,7 +7334,7 @@ static VALUE
rb_thread_abort_exc(thread) rb_thread_abort_exc(thread)
VALUE thread; VALUE thread;
{ {
thread_t th = rb_thread_check(thread); rb_thread_t th = rb_thread_check(thread);
return th->abort?Qtrue:Qfalse; return th->abort?Qtrue:Qfalse;
} }
@ -7339,7 +7343,7 @@ static VALUE
rb_thread_abort_exc_set(thread, val) rb_thread_abort_exc_set(thread, val)
VALUE thread, val; VALUE thread, val;
{ {
thread_t th = rb_thread_check(thread); rb_thread_t th = rb_thread_check(thread);
rb_secure(4); rb_secure(4);
th->abort = RTEST(val); th->abort = RTEST(val);
@ -7382,11 +7386,11 @@ rb_thread_abort_exc_set(thread, val)
th->locals = 0;\ th->locals = 0;\
} while(0) } while(0)
static thread_t static rb_thread_t
rb_thread_alloc(klass) rb_thread_alloc(klass)
VALUE klass; VALUE klass;
{ {
thread_t th; rb_thread_t th;
THREAD_ALLOC(th); THREAD_ALLOC(th);
th->thread = Data_Wrap_Struct(klass, thread_mark, thread_free, 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) rb_thread_start_0(fn, arg, th)
VALUE (*fn)(); VALUE (*fn)();
void *arg; void *arg;
thread_t th; rb_thread_t th;
{ {
volatile VALUE thread = th->thread; volatile VALUE thread = th->thread;
enum thread_status status; enum thread_status status;
@ -7539,7 +7543,7 @@ rb_thread_scope_shared_p()
static VALUE static VALUE
rb_thread_yield(arg, th) rb_thread_yield(arg, th)
VALUE arg; VALUE arg;
thread_t th; rb_thread_t th;
{ {
scope_dup(ruby_block->scope); scope_dup(ruby_block->scope);
return rb_yield_0(callargs(arg), 0, 0, Qfalse); return rb_yield_0(callargs(arg), 0, 0, Qfalse);
@ -7551,7 +7555,7 @@ rb_thread_s_new(argc, argv, klass)
VALUE *argv; VALUE *argv;
VALUE klass; VALUE klass;
{ {
thread_t th = rb_thread_alloc(klass); rb_thread_t th = rb_thread_alloc(klass);
volatile VALUE *pos; volatile VALUE *pos;
THREAD_SAVE_CONTEXT(th); THREAD_SAVE_CONTEXT(th);
@ -7589,7 +7593,7 @@ static VALUE
rb_thread_value(thread) rb_thread_value(thread)
VALUE thread; VALUE thread;
{ {
thread_t th = rb_thread_check(thread); rb_thread_t th = rb_thread_check(thread);
rb_thread_join(thread); rb_thread_join(thread);
@ -7600,7 +7604,7 @@ static VALUE
rb_thread_status(thread) rb_thread_status(thread)
VALUE thread; VALUE thread;
{ {
thread_t th = rb_thread_check(thread); rb_thread_t th = rb_thread_check(thread);
if (rb_thread_dead(th)) { if (rb_thread_dead(th)) {
if (NIL_P(th->errinfo) && (th->flags & THREAD_RAISED)) if (NIL_P(th->errinfo) && (th->flags & THREAD_RAISED))
@ -7617,7 +7621,7 @@ static VALUE
rb_thread_alive_p(thread) rb_thread_alive_p(thread)
VALUE 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; if (rb_thread_dead(th)) return Qfalse;
return Qtrue; return Qtrue;
@ -7627,7 +7631,7 @@ static VALUE
rb_thread_stop_p(thread) rb_thread_stop_p(thread)
VALUE 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 (rb_thread_dead(th)) return Qtrue;
if (th->status == THREAD_STOPPED) return Qtrue; if (th->status == THREAD_STOPPED) return Qtrue;
@ -7646,7 +7650,7 @@ rb_thread_wait_other_threads()
static void static void
rb_thread_cleanup() rb_thread_cleanup()
{ {
thread_t th; rb_thread_t th;
if (curr_thread != curr_thread->next->prev) { if (curr_thread != curr_thread->next->prev) {
curr_thread = curr_thread->prev; curr_thread = curr_thread->prev;
@ -7754,7 +7758,7 @@ rb_thread_raise(argc, argv, thread)
VALUE *argv; VALUE *argv;
VALUE thread; 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 (rb_thread_dead(th)) return Qnil;
if (curr_thread == th) { if (curr_thread == th) {
@ -7813,7 +7817,7 @@ rb_thread_local_aref(thread, id)
VALUE thread; VALUE thread;
ID id; ID id;
{ {
thread_t th; rb_thread_t th;
VALUE val; VALUE val;
th = rb_thread_check(thread); th = rb_thread_check(thread);
@ -7840,7 +7844,7 @@ rb_thread_local_aset(thread, id, val)
ID id; ID id;
VALUE val; 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) { if (rb_safe_level() >= 4 && th != curr_thread) {
rb_raise(rb_eSecurityError, "Insecure: can't modify thread locals"); rb_raise(rb_eSecurityError, "Insecure: can't modify thread locals");
@ -7870,7 +7874,7 @@ static VALUE
rb_thread_key_p(thread, id) rb_thread_key_p(thread, id)
VALUE 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 (!th->locals) return Qfalse;
if (st_lookup(th->locals, rb_to_id(id), 0)) if (st_lookup(th->locals, rb_to_id(id), 0))
@ -7883,7 +7887,7 @@ rb_thread_inspect(thread)
VALUE thread; VALUE thread;
{ {
char *cname = rb_class2name(CLASS_OF(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; char *s, *status;
VALUE str; VALUE str;
@ -7914,7 +7918,7 @@ rb_callcc(self)
VALUE self; VALUE self;
{ {
volatile VALUE cont; volatile VALUE cont;
thread_t th; rb_thread_t th;
struct tag *tag; struct tag *tag;
THREAD_ALLOC(th); THREAD_ALLOC(th);
@ -7940,7 +7944,7 @@ rb_cont_call(argc, argv, cont)
VALUE *argv; VALUE *argv;
VALUE cont; VALUE cont;
{ {
thread_t th = rb_thread_check(cont); rb_thread_t th = rb_thread_check(cont);
switch (argc) { switch (argc) {
case 0: case 0:
@ -7984,7 +7988,7 @@ thgroup_list(group)
VALUE group; VALUE group;
{ {
struct thgroup *data; struct thgroup *data;
thread_t th; rb_thread_t th;
VALUE ary; VALUE ary;
Data_Get_Struct(group, struct thgroup, data); Data_Get_Struct(group, struct thgroup, data);
@ -8004,7 +8008,7 @@ static VALUE
thgroup_add(group, thread) thgroup_add(group, thread)
VALUE group, thread; VALUE group, thread;
{ {
thread_t th; rb_thread_t th;
struct thgroup *data; struct thgroup *data;
rb_secure(4); rb_secure(4);

49
file.c
View File

@ -251,6 +251,53 @@ rb_stat_ctime(self)
return rb_time_new(get_stat(self)->st_ctime, 0); 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 static int
rb_stat(file, st) rb_stat(file, st)
VALUE file; VALUE file;
@ -2216,6 +2263,8 @@ Init_File()
rb_define_method(rb_cStat, "mtime", rb_stat_mtime, 0); 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, "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, "ftype", rb_stat_ftype, 0);
rb_define_method(rb_cStat, "directory?", rb_stat_d, 0); rb_define_method(rb_cStat, "directory?", rb_stat_d, 0);

4
io.c
View File

@ -334,6 +334,10 @@ rb_io_rewind(io)
GetOpenFile(io, fptr); GetOpenFile(io, fptr);
if (fseek(fptr->f, 0L, 0) != 0) rb_sys_fail(fptr->path); if (fseek(fptr->f, 0L, 0) != 0) rb_sys_fail(fptr->path);
clearerr(fptr->f); clearerr(fptr->f);
if (io == current_file) {
gets_lineno -= fptr->lineno;
}
fptr->lineno = 0;
return INT2FIX(0); return INT2FIX(0);
} }

View File

@ -186,13 +186,26 @@ proc_wait()
} }
static VALUE static VALUE
proc_waitpid(obj, vpid, vflags) proc_wait2()
VALUE obj, vpid, vflags;
{ {
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; int pid, flags, status;
if (NIL_P(vflags)) flags = 0; flags = 0;
else flags = NUM2UINT(vflags); 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) if ((pid = rb_waitpid(NUM2INT(vpid), flags, &status)) < 0)
rb_sys_fail(0); rb_sys_fail(0);
@ -200,6 +213,15 @@ proc_waitpid(obj, vpid, vflags)
return INT2FIX(pid); 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(); char *strtok();
#ifdef HAVE_SETITIMER #ifdef HAVE_SETITIMER
@ -834,21 +856,26 @@ proc_setsid()
if (pid < 0) rb_sys_fail(0); if (pid < 0) rb_sys_fail(0);
return INT2FIX(pid); return INT2FIX(pid);
#elif defined(HAVE_SETPGRP) && defined(TIOCNOTTY) #elif defined(HAVE_SETPGRP) && defined(TIOCNOTTY)
pid_t sid; pid_t pid;
int ret;
rb_secure(2);
pid = getpid();
#if defined(SETPGRP_VOID) #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 #else
sid = setpgrp(0, getpid()); ret = setpgrp(0, pid);
#endif #endif
if (sid == -1) return -1; if (ret == -1) rb_sys_fail(0);
if ((fd = open("/dev/tty", O_RDWR)) >= 0) { if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
ioctl(fd, TIOCNOTTY, NULL); ioctl(fd, TIOCNOTTY, NULL);
close(fd); close(fd);
} }
return sid; return INT2FIX(pid);
}
#else #else
rb_notimplement(); rb_notimplement();
#endif #endif
@ -1046,7 +1073,9 @@ Init_process()
rb_define_module_function(rb_mProcess, "kill", rb_f_kill, -1); rb_define_module_function(rb_mProcess, "kill", rb_f_kill, -1);
#ifndef NT #ifndef NT
rb_define_module_function(rb_mProcess, "wait", proc_wait, 0); 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, "pid", get_pid, 0);
rb_define_module_function(rb_mProcess, "ppid", get_ppid, 0); rb_define_module_function(rb_mProcess, "ppid", get_ppid, 0);

1
re.c
View File

@ -1145,6 +1145,7 @@ rb_reg_clone(re)
NEWOBJ(clone, struct RRegexp); NEWOBJ(clone, struct RRegexp);
CLONESETUP(clone, re); CLONESETUP(clone, re);
rb_reg_check(re); rb_reg_check(re);
clone->ptr = 0; clone->len = 0;
rb_reg_initialize(clone, RREGEXP(re)->str, RREGEXP(re)->len, rb_reg_initialize(clone, RREGEXP(re)->str, RREGEXP(re)->len,
rb_reg_options(re)); rb_reg_options(re));
return (VALUE)re; return (VALUE)re;

View File

@ -264,13 +264,15 @@ rb_f_sprintf(argc, argv)
if (flags & FPREC) { if (flags & FPREC) {
rb_raise(rb_eArgError, "precision given twice"); rb_raise(rb_eArgError, "precision given twice");
} }
flags |= FPREC;
prec = 0; prec = 0;
p++; p++;
if (*p == '*') { if (*p == '*') {
GETASTER(prec); GETASTER(prec);
if (prec > 0) if (prec < 0) { /* ignore negative precision */
flags |= FPREC; flags &= ~FPREC;
}
p++; p++;
goto retry; goto retry;
} }
@ -281,8 +283,6 @@ rb_f_sprintf(argc, argv)
if (p >= end) { if (p >= end) {
rb_raise(rb_eArgError, "malformed format string - %%.[0-9]"); rb_raise(rb_eArgError, "malformed format string - %%.[0-9]");
} }
if (prec > 0)
flags |= FPREC;
goto retry; goto retry;
case '\n': case '\n':

11
time.c
View File

@ -490,7 +490,7 @@ time_eql(time1, time2)
} }
static VALUE static VALUE
time_gmt_p(time) time_utc_p(time)
VALUE time; VALUE time;
{ {
struct time_object *tobj; struct time_object *tobj;
@ -536,6 +536,9 @@ time_localtime(time)
time_t t; time_t t;
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got && !tobj->gmt) {
return time;
}
t = tobj->tv.tv_sec; t = tobj->tv.tv_sec;
tm_tmp = localtime(&t); tm_tmp = localtime(&t);
tobj->tm = *tm_tmp; tobj->tm = *tm_tmp;
@ -553,6 +556,9 @@ time_gmtime(time)
time_t t; time_t t;
GetTimeval(time, tobj); GetTimeval(time, tobj);
if (tobj->tm_got && tobj->gmt) {
return time;
}
t = tobj->tv.tv_sec; t = tobj->tv.tv_sec;
tm_tmp = gmtime(&t); tm_tmp = gmtime(&t);
tobj->tm = *tm_tmp; tobj->tm = *tm_tmp;
@ -1077,7 +1083,8 @@ Init_Time()
rb_define_method(rb_cTime, "isdst", time_isdst, 0); rb_define_method(rb_cTime, "isdst", time_isdst, 0);
rb_define_method(rb_cTime, "zone", time_zone, 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_sec", time_to_i, 0);
rb_define_method(rb_cTime, "tv_usec", time_usec, 0); rb_define_method(rb_cTime, "tv_usec", time_usec, 0);

View File

@ -1337,6 +1337,8 @@ rb_cvar_set(klass, id, val)
{ {
VALUE tmp; 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)) { if (FL_TEST(klass, FL_SINGLETON)) {
klass = rb_iv_get(klass, "__attached__"); klass = rb_iv_get(klass, "__attached__");
} }

View File

@ -1,4 +1,4 @@
#define RUBY_VERSION "1.5.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_VERSION_CODE 154
#define RUBY_RELEASE_CODE 20000616 #define RUBY_RELEASE_CODE 20000619