From eeb5c7e18e91e43502cf30d6f395364543fbf109 Mon Sep 17 00:00:00 2001 From: akr Date: Sun, 16 May 2004 12:03:23 +0000 Subject: [PATCH] * ext/dbm/dbm.c (fdbm_initialize): accept optional 3rd argument to specify an open flag. (Init_dbm): define open flags: DBM::READER, DBM::WRITER, DBM::WRCREAT and DBM::NEWDB. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6326 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 7 +++++++ ext/dbm/dbm.c | 40 +++++++++++++++++++++++++++++----------- test/dbm/test_dbm.rb | 27 +++++++++++++++++++++++++-- test/gdbm/test_gdbm.rb | 14 +++++++++++++- 4 files changed, 74 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index a1526f246f..f6ded75be2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Sun May 16 20:55:49 2004 Tanaka Akira + + * ext/dbm/dbm.c (fdbm_initialize): accept optional 3rd argument to + specify an open flag. + (Init_dbm): define open flags: DBM::READER, DBM::WRITER, DBM::WRCREAT + and DBM::NEWDB. + Sat May 15 17:52:24 Hirokazu Yamamoto * test/ruby/test_float.rb(test_strtod): Add test for signed 0.000...1 diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c index e9e2a6e1e9..c76d667989 100644 --- a/ext/dbm/dbm.c +++ b/ext/dbm/dbm.c @@ -24,6 +24,8 @@ static VALUE rb_cDBM, rb_eDBMError; +#define RUBY_DBM_RW_BIT 0x20000000 + struct dbmdata { int di_size; DBM *di_dbm; @@ -78,12 +80,12 @@ fdbm_initialize(argc, argv, obj) VALUE *argv; VALUE obj; { - VALUE file, vmode; + VALUE file, vmode, vflags; DBM *dbm; struct dbmdata *dbmp; - int mode; + int mode, flags = 0; - if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) { + if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) { mode = 0666; /* default value */ } else if (NIL_P(vmode)) { @@ -92,17 +94,27 @@ fdbm_initialize(argc, argv, obj) else { mode = NUM2INT(vmode); } + + if (!NIL_P(vflags)) + flags = NUM2INT(vflags); + SafeStringValue(file); - dbm = 0; - if (mode >= 0) { - dbm = dbm_open(RSTRING(file)->ptr, O_RDWR|O_CREAT, mode); + if (flags & RUBY_DBM_RW_BIT) { + flags &= ~RUBY_DBM_RW_BIT; + dbm = dbm_open(RSTRING(file)->ptr, flags, mode); } - if (!dbm) { - dbm = dbm_open(RSTRING(file)->ptr, O_RDWR, 0); - } - if (!dbm) { - dbm = dbm_open(RSTRING(file)->ptr, O_RDONLY, 0); + else { + dbm = 0; + if (mode >= 0) { + dbm = dbm_open(RSTRING(file)->ptr, O_RDWR|O_CREAT, mode); + } + if (!dbm) { + dbm = dbm_open(RSTRING(file)->ptr, O_RDWR, 0); + } + if (!dbm) { + dbm = dbm_open(RSTRING(file)->ptr, O_RDONLY, 0); + } } if (!dbm) { @@ -787,6 +799,12 @@ Init_dbm() rb_define_method(rb_cDBM, "to_a", fdbm_to_a, 0); rb_define_method(rb_cDBM, "to_hash", fdbm_to_hash, 0); + /* flags for dbm_open() */ + rb_define_const(rb_cDBM, "READER", INT2FIX(O_RDONLY|RUBY_DBM_RW_BIT)); + rb_define_const(rb_cDBM, "WRITER", INT2FIX(O_RDWR|RUBY_DBM_RW_BIT)); + rb_define_const(rb_cDBM, "WRCREAT", INT2FIX(O_RDWR|O_CREAT|RUBY_DBM_RW_BIT)); + rb_define_const(rb_cDBM, "NEWDB", INT2FIX(O_RDWR|O_CREAT|O_TRUNC|RUBY_DBM_RW_BIT)); + #ifdef DB_VERSION_STRING rb_define_const(rb_cDBM, "VERSION", rb_str_new2(DB_VERSION_STRING)); #endif diff --git a/test/dbm/test_dbm.rb b/test/dbm/test_dbm.rb index f9198903a3..2de73d1d5e 100644 --- a/test/dbm/test_dbm.rb +++ b/test/dbm/test_dbm.rb @@ -11,7 +11,7 @@ if defined? DBM require 'fileutils' class TestDBM < Test::Unit::TestCase - TMPROOT = "#{Dir.tmpdir}/ruby-gdbm.#{$$}" + TMPROOT = "#{Dir.tmpdir}/ruby-dbm.#{$$}" def setup Dir.mkdir TMPROOT @@ -21,8 +21,31 @@ if defined? DBM FileUtils.rm_rf TMPROOT if File.directory?(TMPROOT) end + def test_reader_open + DBM.open("#{TMPROOT}/a") {} + v = DBM.open("#{TMPROOT}/a", nil, DBM::READER) {|d| + # Errno::EPERM is raised on Solaris which use ndbm. + # DBMError is raised on Debian which use gdbm. + assert_raises(Errno::EPERM, DBMError) { d["k"] = "v" } + true + } + assert(v) + end + + def test_newdb_open + DBM.open("#{TMPROOT}/a") {|dbm| + dbm["k"] = "v" + } + v = DBM.open("#{TMPROOT}/a", nil, DBM::NEWDB) {|d| + assert_equal(0, d.length) + assert_nil(d["k"]) + true + } + assert(v) + end + def test_freeze - DBM.open("#{TMPROOT}/a.dbm") {|d| + DBM.open("#{TMPROOT}/a") {|d| d.freeze assert_raises(TypeError) { d["k"] = "v" } } diff --git a/test/gdbm/test_gdbm.rb b/test/gdbm/test_gdbm.rb index ca0110cd91..c90f4a6074 100644 --- a/test/gdbm/test_gdbm.rb +++ b/test/gdbm/test_gdbm.rb @@ -21,7 +21,7 @@ if defined? GDBM FileUtils.rm_rf TMPROOT if File.directory?(TMPROOT) end - def test_open + def test_reader_open GDBM.open("#{TMPROOT}/a.dbm") {} v = GDBM.open("#{TMPROOT}/a.dbm", nil, GDBM::READER) {|d| assert_raises(GDBMError) { d["k"] = "v" } @@ -30,6 +30,18 @@ if defined? GDBM assert(v) end + def test_newdb_open + GDBM.open("#{TMPROOT}/a.dbm") {|dbm| + dbm["k"] = "v" + } + v = GDBM.open("#{TMPROOT}/a.dbm", nil, GDBM::NEWDB) {|d| + assert_equal(0, d.length) + assert_nil(d["k"]) + true + } + assert(v) + end + def test_freeze GDBM.open("#{TMPROOT}/a.dbm") {|d| d.freeze