summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-11-25 09:03:08 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-11-25 09:03:08 +0000
commitebab487fcd7633038b9272ddbe31c268cda15723 (patch)
treee7880ae217a2a58dbe35bcf0f94744bc03805e08
parent8e48dc16e97a783a69f0972b4882ad2faae561ea (diff)
19991125
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@570 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog33
-rw-r--r--MANIFEST2
-rw-r--r--ToDo5
-rw-r--r--dir.c32
-rw-r--r--enum.c2
-rw-r--r--file.c356
-rw-r--r--hash.c26
-rw-r--r--io.c22
-rw-r--r--lib/cgi/session.rb157
-rw-r--r--lib/pstore.rb42
-rw-r--r--lib/singleton.rb7
-rw-r--r--process.c14
-rw-r--r--ruby.c3
-rw-r--r--variable.c4
14 files changed, 617 insertions, 88 deletions
diff --git a/ChangeLog b/ChangeLog
index 0f309166763..7f62c45fdb5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+Mon Nov 22 14:07:24 1999 Koji Arai <JCA02266@nifty.ne.jp>
+
+ * ruby.c (proc_options): variable e_script should be visited by
+ garbage collector.
+
+Sat Nov 20 10:10:41 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * hash.c (inspect_i): value may be nil, check revised.
+
+Fri Nov 19 18:06:21 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * dir.c (glob): recurseve wildcard match by `**' ala zsh.
+
+Fri Nov 19 11:44:26 1999 EGUCHI Osamu <eguchi@shizuokanet.ne.jp>
+
+ * variable.c: was returning void value.
+
+Fri Nov 19 03:57:22 1999 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
+
+ * file.c: add methods Stat struct class to reduce stat(2).
+
+Thu Nov 18 16:18:27 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * lib/pstore.rb: mutual lock by flock(2).
+
+Thu Nov 18 11:44:13 1999 Masahiro Tomita <tommy@tmtm.org>
+
+ * io.c (read_all): should check bytes too.
+
Wed Nov 17 02:40:40 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* io.c (Init_IO): $defout (alias of $>) added.
@@ -37,6 +66,10 @@ Sat Nov 13 07:34:18 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* parse.y (assignable): allow constant assignment in methods;
constants should be called `shared variable'.
+Fri Nov 12 23:52:19 1999 Katsuyuki Komatsu <komatsu@sarion.co.jp>
+
+ * process.c (rb_f_system): argument check for NT, __EMX__, DJGPP.
+
Wed Nov 10 21:54:11 1999 EGUCHI Osamu <eguchi@shizuokanet.ne.jp>
* hash.c (rb_any_cmp): Fixed return without value.
diff --git a/MANIFEST b/MANIFEST
index 99c65e2edd4..d67346f3ac5 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 f39a0183481..c762f3c9888 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 e9ca286b912..a0a5d3eddd9 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 008e0a4136d..ad171f6276e 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 b53c814211a..aec45c9106d 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
@@ -676,6 +665,25 @@ rb_file_s_ftype(obj, fname)
}
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 5b8b576b2fe..8fb2153f84f 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 d03277f04fa..1a9d99f5df6 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 00000000000..c584fdb49bc
--- /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 cc90207aa3e..566de8d8f96 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 4aea574e7a1..2785c77134b 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 57b4300ea46..211445b88de 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 5a1a58c89c4..a38a5f1f68a 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 d66fa9915b4..41f935dff8d 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