From ebab487fcd7633038b9272ddbe31c268cda15723 Mon Sep 17 00:00:00 2001 From: matz Date: Thu, 25 Nov 1999 09:03:08 +0000 Subject: 19991125 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@570 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 33 +++++ MANIFEST | 2 - ToDo | 5 +- dir.c | 32 +++-- enum.c | 2 +- file.c | 356 ++++++++++++++++++++++++++++++++++++++++++++++++++--- hash.c | 26 ++-- io.c | 22 ++-- lib/cgi/session.rb | 157 +++++++++++++++++++++++ lib/pstore.rb | 42 +++---- lib/singleton.rb | 7 +- process.c | 14 ++- ruby.c | 3 +- variable.c | 4 +- 14 files changed, 617 insertions(+), 88 deletions(-) create mode 100644 lib/cgi/session.rb diff --git a/ChangeLog b/ChangeLog index 0f30916676..7f62c45fdb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +Mon Nov 22 14:07:24 1999 Koji Arai + + * ruby.c (proc_options): variable e_script should be visited by + garbage collector. + +Sat Nov 20 10:10:41 1999 Yukihiro Matsumoto + + * hash.c (inspect_i): value may be nil, check revised. + +Fri Nov 19 18:06:21 1999 Yukihiro Matsumoto + + * dir.c (glob): recurseve wildcard match by `**' ala zsh. + +Fri Nov 19 11:44:26 1999 EGUCHI Osamu + + * variable.c: was returning void value. + +Fri Nov 19 03:57:22 1999 Nobuyoshi Nakada + + * file.c: add methods Stat struct class to reduce stat(2). + +Thu Nov 18 16:18:27 1999 Yukihiro Matsumoto + + * lib/pstore.rb: mutual lock by flock(2). + +Thu Nov 18 11:44:13 1999 Masahiro Tomita + + * io.c (read_all): should check bytes too. + Wed Nov 17 02:40:40 1999 Yukihiro Matsumoto * io.c (Init_IO): $defout (alias of $>) added. @@ -37,6 +66,10 @@ Sat Nov 13 07:34:18 1999 Yukihiro Matsumoto * parse.y (assignable): allow constant assignment in methods; constants should be called `shared variable'. +Fri Nov 12 23:52:19 1999 Katsuyuki Komatsu + + * process.c (rb_f_system): argument check for NT, __EMX__, DJGPP. + Wed Nov 10 21:54:11 1999 EGUCHI Osamu * hash.c (rb_any_cmp): Fixed return without value. diff --git a/MANIFEST b/MANIFEST index 99c65e2edd..d67346f3ac 100644 --- a/MANIFEST +++ b/MANIFEST @@ -234,8 +234,6 @@ win32/config.h win32/config.status win32/ntsetup.bat win32/ruby.def -win32/sdbm.c -win32/sdbm.h win32/win32.c win32/win32.h x68/fconvert.c diff --git a/ToDo b/ToDo index f39a018348..c762f3c988 100644 --- a/ToDo +++ b/ToDo @@ -2,9 +2,10 @@ Language Spec. - def foo; .. rescue .. end - compile time string concatenation, "hello" "world" => "helloworld" -- rescue modifier; a rescue b => begin a rescue; b end - assignable constant, which now should be called shared variable. - class variable (prefix?) -- done by shared variable +- rescue modifier; a rescue b => begin a rescue; b end +* operator !! for rescue. * objectify symbols * objectify characters * ../... outside condition invokes operator method too. @@ -39,8 +40,8 @@ Standard Libraries - Array#{first,last,at} - Dir.glob(pat){|f|...} - sprintf/printf's $ to specify argument order +- Dir.glob("**/*.c") ala zsh * debugger for thread programming -* Dir.glob("**/*.c") ala zsh * Struct::new([name,]member,...) ?? * String#scanf(?) * Object#fmt(?) diff --git a/dir.c b/dir.c index e9ca286b91..a0a5d3eddd 100644 --- a/dir.c +++ b/dir.c @@ -557,9 +557,10 @@ glob(path, func, arg) if (*p == '/') p++; m = strchr(p, '/'); if (has_magic(p, m)) { - char *dir, *base, *magic; + char *dir, *base, *magic, *buf; DIR *dirp; struct dirent *dp; + int recursive = 0; struct d_link { char *path; @@ -570,24 +571,39 @@ glob(path, func, arg) if (path == p) dir = "."; else dir = base; + magic = extract_elem(p); + if (strcmp(magic, "**") == 0) { + recursive = 1; + buf = ALLOC_N(char, strlen(base)+strlen(m)+3); + sprintf(buf, "%s%s%s", base, (*base)?"":".", m); + glob(buf, func, arg); + free(buf); + } dirp = opendir(dir); if (dirp == NULL) { free(base); break; } - magic = extract_elem(p); for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { + if (recursive) { + if (strcmp(".", dp->d_name) == 0 || strcmp("..", dp->d_name) == 0) + continue; + buf = ALLOC_N(char, strlen(base)+NAMLEN(dp)+strlen(m)+6); + sprintf(buf, "%s%s%s/**%s", base, (*base)?"/":"", dp->d_name, m); + glob(buf, func, arg); + free(buf); + continue; + } if (fnmatch(magic, dp->d_name, FNM_PERIOD|FNM_PATHNAME) == 0) { - char *fix = ALLOC_N(char, strlen(base)+NAMLEN(dp)+2); - - sprintf(fix, "%s%s%s", base, (*base)?"/":"", dp->d_name); + buf = ALLOC_N(char, strlen(base)+NAMLEN(dp)+2); + sprintf(buf, "%s%s%s", base, (*base)?"/":"", dp->d_name); if (!m) { - (*func)(fix, arg); - free(fix); + (*func)(buf, arg); + free(buf); continue; } tmp = ALLOC(struct d_link); - tmp->path = fix; + tmp->path = buf; tmp->next = link; link = tmp; } diff --git a/enum.c b/enum.c index 008e0a4136..ad171f6276 100644 --- a/enum.c +++ b/enum.c @@ -50,7 +50,7 @@ enum_grep(obj, pat) arg[0] = pat; arg[1] = tmp = rb_ary_new(); if (rb_iterator_p()) { - rb_iterate(rb_each, obj, grep_iter_i, pat); + rb_iterate(rb_each, obj, grep_iter_i, (VALUE)arg); } else { rb_iterate(rb_each, obj, grep_i, (VALUE)arg); diff --git a/file.c b/file.c index b53c814211..aec45c9106 100644 --- a/file.c +++ b/file.c @@ -625,46 +625,35 @@ rb_file_s_size(obj, fname) } static VALUE -rb_file_s_ftype(obj, fname) - VALUE obj, fname; +rb_file_ftype(mode) + mode_t mode; { - struct stat st; char *t; -#if defined(MSDOS) || defined(NT) - if (rb_stat(fname, &st) < 0) - rb_sys_fail(RSTRING(fname)->ptr); -#else - Check_SafeStr(fname); - if (lstat(RSTRING(fname)->ptr, &st) == -1) { - rb_sys_fail(RSTRING(fname)->ptr); - } -#endif - - if (S_ISREG(st.st_mode)) { + if (S_ISREG(mode)) { t = "file"; - } else if (S_ISDIR(st.st_mode)) { + } else if (S_ISDIR(mode)) { t = "directory"; - } else if (S_ISCHR(st.st_mode)) { + } else if (S_ISCHR(mode)) { t = "characterSpecial"; } #ifdef S_ISBLK - else if (S_ISBLK(st.st_mode)) { + else if (S_ISBLK(mode)) { t = "blockSpecial"; } #endif #ifdef S_ISFIFO - else if (S_ISFIFO(st.st_mode)) { + else if (S_ISFIFO(mode)) { t = "fifo"; } #endif #ifdef S_ISLNK - else if (S_ISLNK(st.st_mode)) { + else if (S_ISLNK(mode)) { t = "link"; } #endif #ifdef S_ISSOCK - else if (S_ISSOCK(st.st_mode)) { + else if (S_ISSOCK(mode)) { t = "socket"; } #endif @@ -675,6 +664,25 @@ rb_file_s_ftype(obj, fname) return rb_str_new2(t); } +static VALUE +rb_file_s_ftype(obj, fname) + VALUE obj, fname; +{ + struct stat st; + +#if defined(MSDOS) || defined(NT) + if (rb_stat(fname, &st) < 0) + rb_sys_fail(RSTRING(fname)->ptr); +#else + Check_SafeStr(fname); + if (lstat(RSTRING(fname)->ptr, &st) == -1) { + rb_sys_fail(RSTRING(fname)->ptr); + } +#endif + + return rb_file_ftype(st.st_mode); +} + static VALUE rb_file_s_atime(obj, fname) VALUE obj, fname; @@ -1541,6 +1549,283 @@ rb_f_test(argc, argv) return Qnil; /* not reached */ } +static ID rb_st_mode; +static ID rb_st_size; +static ID rb_st_uid; +static ID rb_st_gid; + +#define ST_MODE(obj) FIX2INT(rb_funcall3((obj), rb_st_mode, 0, 0)) + +static VALUE +rb_stat_ftype(obj) + VALUE obj; +{ + return rb_file_ftype(ST_MODE(obj)); +} + +static VALUE +rb_stat_d(obj) + VALUE obj; +{ + if (S_ISDIR(ST_MODE(obj))) return Qtrue; + return Qfalse; +} + +static VALUE +rb_stat_p(obj) + VALUE obj; +{ +#ifdef S_IFIFO + if (S_ISFIFO(ST_MODE(obj))) return Qtrue; + +#endif + return Qfalse; +} + +static VALUE +rb_stat_l(obj) + VALUE obj; +{ +#ifdef S_ISLNK + if (S_ISLNK(ST_MODE(obj))) return Qtrue; + +#endif + return Qfalse; +} + +static VALUE +rb_stat_S(obj) + VALUE obj; +{ +#ifdef S_ISSOCK + if (S_ISSOCK(ST_MODE(obj))) return Qtrue; + +#endif + return Qfalse; +} + +static VALUE +rb_stat_b(obj) + VALUE obj; +{ +#ifdef S_ISBLK + if (S_ISBLK(ST_MODE(obj))) return Qtrue; + +#endif + return Qfalse; +} + +static VALUE +rb_stat_c(obj) + VALUE obj; +{ + if (S_ISBLK(ST_MODE(obj))) return Qtrue; + + return Qfalse; +} + +static VALUE +rb_stat_owned(obj) + VALUE obj; +{ + if (FIX2INT(rb_funcall3(obj, rb_st_uid, 0, 0)) == geteuid()) return Qtrue; + return Qfalse; +} + +static VALUE +rb_stat_rowned(obj) + VALUE obj; +{ + if (FIX2INT(rb_funcall3(obj, rb_st_uid, 0, 0)) == getuid()) return Qtrue; + return Qfalse; +} + +static VALUE +rb_stat_grpowned(obj) + VALUE obj; +{ +#ifndef NT + if (FIX2INT(rb_funcall3(obj, rb_st_gid, 0, 0)) == getegid()) return Qtrue; +#endif + return Qfalse; +} + +static VALUE +rb_stat_r(obj) + VALUE obj; +{ + mode_t mode = ST_MODE(obj); + +#ifdef S_IRUSR + if (rb_stat_owned(obj)) + return mode & S_IRUSR ? Qtrue : Qfalse; +#endif +#ifdef S_IRGRP + if (rb_stat_grpowned(obj)) + return mode & S_IRGRP ? Qtrue : Qfalse; +#endif +#ifdef S_IROTH + if (!(mode & S_IROTH)) return Qfalse; +#endif + return Qtrue; +} + +static VALUE +rb_stat_R(obj) + VALUE obj; +{ + mode_t mode = ST_MODE(obj); + +#ifdef S_IRUSR + if (rb_stat_rowned(obj)) + return mode & S_IRUSR ? Qtrue : Qfalse; +#endif +#ifdef S_IRGRP + if (group_member(FIX2INT(rb_funcall3(obj, rb_st_gid, 0, 0)))) + return mode & S_IRGRP ? Qtrue : Qfalse; +#endif +#ifdef S_IROTH + if (!(mode & S_IROTH)) return Qfalse; +#endif + return Qtrue; +} + +static VALUE +rb_stat_w(obj) + VALUE obj; +{ + mode_t mode = ST_MODE(obj); + +#ifdef S_IRUSR + if (rb_stat_owned(obj)) + return mode & S_IWUSR ? Qtrue : Qfalse; +#endif +#ifdef S_IRGRP + if (rb_stat_grpowned(obj)) + return mode & S_IWGRP ? Qtrue : Qfalse; +#endif +#ifdef S_IROTH + if (!(mode & S_IWOTH)) return Qfalse; +#endif + return Qtrue; +} + +static VALUE +rb_stat_W(obj) + VALUE obj; +{ + mode_t mode = ST_MODE(obj); + +#ifdef S_IRUSR + if (rb_stat_rowned(obj)) + return mode & S_IWUSR ? Qtrue : Qfalse; +#endif +#ifdef S_IRGRP + if (group_member(FIX2INT(rb_funcall3(obj, rb_st_gid, 0, 0)))) + return mode & S_IWGRP ? Qtrue : Qfalse; +#endif +#ifdef S_IROTH + if (!(mode & S_IWOTH)) return Qfalse; +#endif + return Qtrue; +} + +static VALUE +rb_stat_x(obj) + VALUE obj; +{ + mode_t mode = ST_MODE(obj); + +#ifdef S_IRUSR + if (rb_stat_owned(obj)) + return mode & S_IXUSR ? Qtrue : Qfalse; +#endif +#ifdef S_IRGRP + if (rb_stat_grpowned(obj)) + return mode & S_IXGRP ? Qtrue : Qfalse; +#endif +#ifdef S_IROTH + if (!(mode & S_IXOTH)) return Qfalse; +#endif + return Qtrue; +} + +static VALUE +rb_stat_X(obj) + VALUE obj; +{ + mode_t mode = ST_MODE(obj); + +#ifdef S_IRUSR + if (rb_stat_rowned(obj)) + return mode & S_IXUSR ? Qtrue : Qfalse; +#endif +#ifdef S_IRGRP + if (group_member(FIX2INT(rb_funcall3(obj, rb_st_gid, 0, 0)))) + return mode & S_IXGRP ? Qtrue : Qfalse; +#endif +#ifdef S_IROTH + if (!(mode & S_IXOTH)) return Qfalse; +#endif + return Qtrue; +} + +static VALUE +rb_stat_f(obj) + VALUE obj; +{ + if (S_ISREG(ST_MODE(obj))) return Qtrue; + return Qfalse; +} + +static VALUE +rb_stat_z(obj) + VALUE obj; +{ + if (rb_funcall3(obj, rb_st_size, 0, 0) == INT2FIX(0)) return Qtrue; + return Qfalse; +} + +static VALUE +rb_stat_s(obj) + VALUE obj; +{ + VALUE size = rb_funcall3(obj, rb_st_size, 0, 0); + + if (size == INT2FIX(0)) return Qnil; + return size; +} + +static VALUE +rb_stat_suid(obj) + VALUE obj; +{ +#ifdef S_ISUID + if (ST_MODE(obj) & S_ISUID) return Qtrue; +#endif + return Qfalse; +} + +static VALUE +rb_stat_sgid(obj) + VALUE obj; +{ +#ifndef NT + if (ST_MODE(obj) & S_ISGID) return Qtrue; +#endif + return Qfalse; +} + +static VALUE +rb_stat_sticky(obj) + VALUE obj; +{ +#ifdef S_ISVTX + if (ST_MODE(obj) & S_ISVTX) return Qtrue; +#endif + return Qnil; +} + static VALUE rb_mConst; void @@ -1653,4 +1938,35 @@ Init_File() "nlink", "uid", "gid", "rdev", "size", "blksize", "blocks", "atime", "mtime", "ctime", 0); + + rb_st_mode = rb_intern("mode"); + rb_st_size = rb_intern("size"); + rb_st_uid = rb_intern("uid"); + rb_st_gid = rb_intern("gid"); + + rb_define_method(sStat, "ftype", rb_stat_ftype, 0); + + rb_define_method(sStat, "directory?", rb_stat_d, 0); + rb_define_method(sStat, "readable?", rb_stat_r, 0); + rb_define_method(sStat, "readable_real?", rb_stat_R, 0); + rb_define_method(sStat, "writable?", rb_stat_w, 0); + rb_define_method(sStat, "writable_real?", rb_stat_W, 0); + rb_define_method(sStat, "executable?", rb_stat_x, 0); + rb_define_method(sStat, "executable_real?", rb_stat_X, 0); + rb_define_method(sStat, "file?", rb_stat_f, 0); + rb_define_method(sStat, "zero?", rb_stat_z, 0); + rb_define_method(sStat, "size?", rb_stat_s, 0); + rb_define_method(sStat, "owned?", rb_stat_owned, 0); + rb_define_method(sStat, "grpowned?", rb_stat_grpowned, 0); + + rb_define_method(sStat, "pipe?", rb_stat_p, 0); + rb_define_method(sStat, "symlink?", rb_stat_l, 0); + rb_define_method(sStat, "socket?", rb_stat_S, 0); + + rb_define_method(sStat, "blockdev?", rb_stat_b, 0); + rb_define_method(sStat, "chardev?", rb_stat_c, 0); + + rb_define_method(sStat, "setuid?", rb_stat_suid, 0); + rb_define_method(sStat, "setgid?", rb_stat_sgid, 0); + rb_define_method(sStat, "sticky?", rb_stat_sticky, 0); } diff --git a/hash.c b/hash.c index 5b8b576b2f..8fb2153f84 100644 --- a/hash.c +++ b/hash.c @@ -139,7 +139,7 @@ rb_hash_foreach_iter(key, value, arg) st_table *tbl = RHASH(arg->hash)->tbl; struct st_table_entry **bins = tbl->bins; - if (value == Qnil) return ST_CONTINUE; + if (key == Qnil) return ST_CONTINUE; status = (*arg->func)(key, value, arg->arg); if (RHASH(arg->hash)->tbl != tbl || RHASH(arg->hash)->tbl->bins != bins){ rb_raise(rb_eIndexError, "rehash occurred during iteration"); @@ -457,7 +457,7 @@ shift_i(key, value, var) VALUE key, value; struct shift_var *var; { - if (value == Qnil) return ST_CONTINUE; + if (key == Qnil) return ST_CONTINUE; if (var->stop) return ST_STOP; var->stop = 1; var->key = key; @@ -483,7 +483,7 @@ static int delete_if_i(key, value) VALUE key, value; { - if (value == Qnil) return ST_CONTINUE; + if (key == Qnil) return ST_CONTINUE; if (RTEST(rb_yield(rb_assoc_new(key, value)))) return ST_DELETE; return ST_CONTINUE; @@ -569,7 +569,7 @@ static int each_value_i(key, value) VALUE key, value; { - if (value == Qnil) return ST_CONTINUE; + if (key == Qnil) return ST_CONTINUE; rb_yield(value); return ST_CONTINUE; } @@ -586,7 +586,7 @@ static int each_key_i(key, value) VALUE key, value; { - if (value == Qnil) return ST_CONTINUE; + if (key == Qnil) return ST_CONTINUE; rb_yield(key); return ST_CONTINUE; } @@ -603,7 +603,7 @@ static int each_pair_i(key, value) VALUE key, value; { - if (value == Qnil) return ST_CONTINUE; + if (key == Qnil) return ST_CONTINUE; rb_yield(rb_assoc_new(key, value)); return ST_CONTINUE; } @@ -620,7 +620,7 @@ static int to_a_i(key, value, ary) VALUE key, value, ary; { - if (value == Qnil) return ST_CONTINUE; + if (key == Qnil) return ST_CONTINUE; rb_ary_push(ary, rb_assoc_new(key, value)); return ST_CONTINUE; } @@ -650,7 +650,7 @@ inspect_i(key, value, str) { VALUE str2; - if (value == Qnil) return ST_CONTINUE; + if (key == Qnil) return ST_CONTINUE; if (RSTRING(str)->len > 1) { rb_str_cat(str, ", ", 2); } @@ -712,7 +712,7 @@ static int keys_i(key, value, ary) VALUE key, value, ary; { - if (value == Qnil) return ST_CONTINUE; + if (key == Qnil) return ST_CONTINUE; rb_ary_push(ary, key); return ST_CONTINUE; } @@ -733,7 +733,7 @@ static int values_i(key, value, ary) VALUE key, value, ary; { - if (value == Qnil) return ST_CONTINUE; + if (key == Qnil) return ST_CONTINUE; rb_ary_push(ary, value); return ST_CONTINUE; } @@ -765,7 +765,7 @@ static int rb_hash_search_value(key, value, data) VALUE key, value, *data; { - if (value == Qnil) return ST_CONTINUE; + if (key == Qnil) return ST_CONTINUE; if (rb_equal(value, data[1])) { data[0] = Qtrue; return ST_STOP; @@ -832,7 +832,7 @@ rb_hash_invert_i(key, value, hash) VALUE key, value; VALUE hash; { - if (value == Qnil) return ST_CONTINUE; + if (key == Qnil) return ST_CONTINUE; rb_hash_aset(hash, value, key); return ST_CONTINUE; } @@ -852,7 +852,7 @@ rb_hash_update_i(key, value, hash) VALUE key, value; VALUE hash; { - if (value == Qnil) return ST_CONTINUE; + if (key == Qnil) return ST_CONTINUE; rb_hash_aset(hash, key, value); return ST_CONTINUE; } diff --git a/io.c b/io.c index d03277f04f..1a9d99f5df 100644 --- a/io.c +++ b/io.c @@ -426,7 +426,7 @@ read_all(port) TRAP_BEG; n = fread(RSTRING(str)->ptr+bytes, 1, siz-bytes, fptr->f); TRAP_END; - if (n == 0) { + if (n == 0 && bytes == 0) { if (feof(fptr->f)) return Qnil; rb_sys_fail(fptr->path); } @@ -1092,7 +1092,7 @@ VALUE rb_io_binmode(io) VALUE io; { -#if defined(NT) || defined(DJGPP) || defined(__CYGWIN32__)\ +#if defined(NT) || defined(DJGPP) || defined(__CYGWIN__)\ || defined(__human68k__) || defined(USE_CWGUSI) || defined(__EMX__) OpenFile *fptr; @@ -1338,7 +1338,7 @@ rb_file_sysopen(fname, flags, mode) return rb_file_sysopen_internal(rb_cFile, fname, flags, mode); } -#if defined (NT) || defined(DJGPP) || defined(__CYGWIN32__) || defined(__human68k__) +#if defined (NT) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__) static struct pipe_list { OpenFile *fptr; struct pipe_list *next; @@ -1397,7 +1397,7 @@ static void pipe_finalize(fptr) OpenFile *fptr; { -#if !defined (__CYGWIN32__) +#if !defined (__CYGWIN__) if (fptr->f != NULL) { pclose(fptr->f); } @@ -1528,7 +1528,7 @@ pipe_open(pname, mode) if (fptr->f) fptr->f2 = f; else fptr->f = f; } -#if defined (__CYGWIN32__) +#if defined (__CYGWIN__) fptr->finalize = pipe_finalize; pipe_add_fptr(fptr); #endif @@ -2287,13 +2287,13 @@ next_argv() fstat(fileno(fr), &st); if (*ruby_inplace_mode) { str = rb_str_new2(fn); -#if defined(MSDOS) || defined(__CYGWIN32__) || defined(NT) +#if defined(MSDOS) || defined(__CYGWIN__) || defined(NT) ruby_add_suffix(str, ruby_inplace_mode); #else rb_str_cat(str, ruby_inplace_mode, strlen(ruby_inplace_mode)); #endif -#if defined(MSDOS) || defined(__BOW__) || defined(__CYGWIN32__) || defined(NT) || defined(__human68k__) || defined(__EMX__) +#if defined(MSDOS) || defined(__BOW__) || defined(__CYGWIN__) || defined(NT) || defined(__human68k__) || defined(__EMX__) (void)fclose(fr); (void)unlink(RSTRING(str)->ptr); (void)rename(fn, RSTRING(str)->ptr); @@ -2308,7 +2308,7 @@ next_argv() #endif } else { -#if !defined(MSDOS) && !defined(__BOW__) && !defined(__CYGWIN32__) && !defined(NT) && !defined(__human68k__) +#if !defined(MSDOS) && !defined(__BOW__) && !defined(__CYGWIN__) && !defined(NT) && !defined(__human68k__) if (unlink(fn) < 0) { rb_warn("Can't remove %s: %s, skipping file", fn, strerror(errno)); @@ -2320,7 +2320,7 @@ next_argv() #endif } fw = rb_fopen(fn, "w"); -#if !defined(MSDOS) && !defined(__CYGWIN32__) && !(NT) && !defined(__human68k__) && !defined(USE_CWGUSI) && !defined(__BEOS__) && !defined(__EMX__) +#if !defined(MSDOS) && !defined(__CYGWIN__) && !(NT) && !defined(__human68k__) && !defined(USE_CWGUSI) && !defined(__BEOS__) && !defined(__EMX__) fstat(fileno(fw), &st2); fchmod(fileno(fw), st.st_mode); if (st.st_uid!=st2.st_uid || st.st_gid!=st2.st_gid) { @@ -2673,7 +2673,7 @@ rb_io_ctl(io, req, arg, io_p) fd = fileno(fptr->f); #ifdef HAVE_FCNTL TRAP_BEG; -# ifdef USE_CWGUSI +# if defined(USE_CWGUSI) || defined(__CYGWIN__) retval = io_p?ioctl(fd, cmd, (void*) narg):fcntl(fd, cmd, narg); # else retval = io_p?ioctl(fd, cmd, narg):fcntl(fd, cmd, narg); @@ -3335,7 +3335,7 @@ Init_IO() rb_define_virtual_variable("$-i", opt_i_get, opt_i_set); -#if defined (NT) || defined(DJGPP) || defined(__CYGWIN32__) || defined(__human68k__) +#if defined (NT) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__) atexit(pipe_atexit); #endif diff --git a/lib/cgi/session.rb b/lib/cgi/session.rb new file mode 100644 index 0000000000..c584fdb49b --- /dev/null +++ b/lib/cgi/session.rb @@ -0,0 +1,157 @@ + +require 'CGI' +require 'final' + +class CGI + class Session + + attr_reader :session_id + + def Session::callback(dbman) + lambda{ + dbman.close + } + end + + def create_new_id + require 'md5' + md5 = MD5::new + md5.update(String(Time::now)) + md5.update(String(rand(0))) + md5.update(String($$)) + md5.update('foobar') + @session_id = md5.hexdigest[0,16] + end + private :create_new_id + + def initialize(request, option={}) + session_key = option['session_key'] || '_session_id' + id, = option['session_id'] + unless id + if option['new_session'] + id = create_new_id + end + end + unless id + id, = request[session_key] + unless id + id, = request.cookies[session_key] + end + unless id + if option.key?('new_session') and not option['new_session'] + raise ArgumentError, "session_key `%s' should be supplied"%session_key + end + id = create_new_id + end + end + @session_id = id + dbman = option['database_manager'] || FileStore + @dbman = dbman::new(self, option) + request.instance_eval do + @output_hidden = {session_key => id} + @output_cookies = [Cookie::new(session_key,id)] + end + ObjectSpace::define_finalizer(self, Session::callback(@dbman)) + end + + def [](key) + unless @data + @data = @dbman.restore + end + @data[key] + end + + def []=(key, val) + unless @write_lock + @write_lock = true + end + unless @data + @data = @dbman.restore + end + @data[key] = String(val) + end + + def update + @dbman.update + end + + def delete + @dbman.delete + end + + class FileStore + def initialize(session, option={}) + dir = option['tmpdir'] || ENV['TMP'] || '/tmp' + prefix = option['prefix'] || '' + path = dir+"/"+prefix+session.session_id + path.untaint + unless File::exist? path + @hash = {} + end + begin + @f = open(path, "r+") + rescue Errno::ENOENT + @f = open(path, "w+") + end + end + + def restore + unless @hash + @hash = {} + @f.flock File::LOCK_EX + @f.rewind + for line in @f + line.chomp! + k, v = line.split('=',2) + @hash[CGI::unescape(k)] = CGI::unescape(v) + end + end + @hash + end + + def update + @f.rewind + for k,v in @hash + @f.printf "%s=%s\n", CGI::escape(k), CGI::escape(v) + end + @f.truncate @f.tell + end + + def close + update + @f.close + end + + def delete + path = @f.path + @f.close + File::unlink path + end + end + + class MemoryStore + GLOBAL_HASH_TABLE = {} + + def initialize(session, option={}) + @session_id = session.session_id + GLOBAL_HASH_TABLE[@session_id] = {} + end + + def restore + GLOBAL_HASH_TABLE[@session_id] + end + + def update + # don't need to update; hash is shared + end + + def close + # don't need to close + end + + def delete + GLOBAL_HASH_TABLE[@session_id] = nil + end + end + end +end diff --git a/lib/pstore.rb b/lib/pstore.rb index cc90207aa3..566de8d8f9 100644 --- a/lib/pstore.rb +++ b/lib/pstore.rb @@ -13,6 +13,7 @@ # end require "marshal" +require "ftools" class PStore class Error < StandardError @@ -77,22 +78,19 @@ class PStore raise PStore::Error, "nested transaction" if @transaction begin @transaction = true - value = file = nil - lock = @filename + ".lock" - loop do - begin - File::symlink("pstore::#$$", lock) - break - rescue Errno::EEXIST - rescue - sleep 1 - end + value = nil + backup = @filename+"~" + if File::exist?(@filename) + file = File::open(@filename, "r+") + orig = true + else + file = File::open(@filename, "w+") end - begin - File::open(@filename, "r") do |file| - @table = Marshal.load(file) - end - rescue Errno::ENOENT + file.flock(File::LOCK_EX) + if orig + File::copy @filename, backup + @table = Marshal::load(file) + else @table = {} end begin @@ -105,16 +103,10 @@ class PStore ensure unless @abort begin - File::rename @filename, @filename+"~" - rescue Errno::ENOENT - no_orig = true - end - begin - File::open(@filename, "w") do |file| - Marshal::dump(@table, file) - end + file.rewind + Marshal::dump(@table, file) rescue - File::rename @filename+"~", @filename unless no_orig + File::rename backup, @filename if File::exist?(backup) end end @abort = false @@ -122,7 +114,7 @@ class PStore ensure @table = nil @transaction = false - File::unlink(lock) + file.close end value end diff --git a/lib/singleton.rb b/lib/singleton.rb index 4aea574e7a..2785c77134 100644 --- a/lib/singleton.rb +++ b/lib/singleton.rb @@ -17,7 +17,12 @@ module Singleton @__instance__ = nil def instance unless @__instance__ - @__instance__ = new + Thread.critical = true + begin + @__instance__ = new + ensure + Thread.critical = false + end end return @__instance__ end diff --git a/process.c b/process.c index 57b4300ea4..211445b88d 100644 --- a/process.c +++ b/process.c @@ -600,6 +600,13 @@ rb_f_system(argc, argv) VALUE cmd; int state; + fflush(stdout); + fflush(stderr); + if (argc == 0) { + rb_last_status = INT2FIX(0); + rb_raise(rb_eArgError, "wrong # of arguments"); + } + if (TYPE(argv[0]) == T_ARRAY) { if (RARRAY(argv[0])->len != 2) { rb_raise(rb_eArgError, "wrong first argument"); @@ -619,6 +626,11 @@ rb_f_system(argc, argv) VALUE cmd; int state; + if (argc == 0) { + rb_last_status = INT2FIX(0); + rb_raise(rb_eArgError, "wrong # of arguments"); + } + if (TYPE(argv[0]) == T_ARRAY) { if (RARRAY(argv[0])->len != 2) { rb_raise(rb_eArgError, "wrong first argument"); @@ -667,7 +679,7 @@ rb_f_system(argc, argv) #if defined(USE_CWGUSI) rb_notimplement(); #else - volatile VALUE prog = 0; + volatile VALUE prog = 0; int pid; int i; diff --git a/ruby.c b/ruby.c index 5a1a58c89c..a38a5f1f68 100644 --- a/ruby.c +++ b/ruby.c @@ -117,8 +117,6 @@ NULL extern VALUE rb_load_path; -static VALUE e_script; - #define STATIC_FILE_LENGTH 255 #if defined(_WIN32) || defined(DJGPP) @@ -324,6 +322,7 @@ proc_options(argc, argv) int version = 0; int copyright = 0; int verbose = 0; + VALUE e_script = Qfalse; if (argc == 0) return; diff --git a/variable.c b/variable.c index d66fa9915b..41f935dff8 100644 --- a/variable.c +++ b/variable.c @@ -1263,7 +1263,7 @@ rb_const_set(klass, id, val) ID id; VALUE val; { - return rb_shvar_set(klass, id, val); + rb_shvar_set(klass, id, val); } void @@ -1331,7 +1331,7 @@ rb_define_shvar(klass, name, val) const char *name; VALUE val; { - return rb_define_const(klass, name, val); + rb_define_const(klass, name, val); } void -- cgit v1.2.3