Forcing DBM.open to be read-only?

I'd like to use the DBM routines in ruby, and I want to force DBM.open
to be performed in read-only mode. However, looking at the source code
(in ext/dbm/dbm.c), it looks like ruby always tries to open the database
in read-write mode before trying it in read-only mode [see the
fdbm_initialize() routine, below].

Am I misinterpreting something?

In any case, how can I do a DBM.open with the guarantee that it will
never even try to open the file in read-write mode?

Thanks in advance.

Here's the code I that mentioned:

  static VALUE
  fdbm_initialize(argc, argv, obj)
      int argc;
      VALUE *argv;
      VALUE obj;
  {
      VALUE file, vmode, vflags;
      DBM *dbm;
      struct dbmdata *dbmp;
      int mode, flags = 0;
  
      if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
          mode = 0666; /* default value */
      }
      else if (NIL_P(vmode)) {
          mode = -1; /* return nil if DB not exist */
      }
      else {
          mode = NUM2INT(vmode);
      }
  
      if (!NIL_P(vflags))
          flags = NUM2INT(vflags);
  
      SafeStringValue(file);
  
      if (flags & RUBY_DBM_RW_BIT) {
          flags &= ~RUBY_DBM_RW_BIT;
          dbm = dbm_open(RSTRING(file)->ptr, flags, mode);
      }
      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) {
          if (mode == -1) return Qnil;
          rb_sys_fail(RSTRING(file)->ptr);
      }
  
      dbmp = ALLOC(struct dbmdata);
      DATA_PTR(obj) = dbmp;
      dbmp->di_dbm = dbm;
      dbmp->di_size = -1;
  
      return obj;
  }

···

--
Lloyd Zusman
ljz@asfast.com
God bless you.

I'd like to use the DBM routines in ruby, and I want to force DBM.open
to be performed in read-only mode. However, looking at the source code
(in ext/dbm/dbm.c), it looks like ruby always tries to open the database
in read-write mode before trying it in read-only mode [see the
fdbm_initialize() routine, below].

Am I misinterpreting something?

In any case, how can I do a DBM.open with the guarantee that it will
never even try to open the file in read-write mode?

maybe DBM.open(filename, 0666, DBM::READER) ?
(that sets the RUBY_DBM_RW_BIT... )

      if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
          mode = 0666; /* default value */
      }

[...]

···

On Tue, Oct 12, 2004 at 02:26:10AM +0900, Lloyd Zusman wrote:

      if (flags & RUBY_DBM_RW_BIT) {
          flags &= ~RUBY_DBM_RW_BIT;
          dbm = dbm_open(RSTRING(file)->ptr, flags, mode);
      }

--
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Mauricio Fernández <batsman.geo@yahoo.com> writes:

I'd like to use the DBM routines in ruby, and I want to force DBM.open
to be performed in read-only mode. However, looking at the source code
(in ext/dbm/dbm.c), it looks like ruby always tries to open the database
in read-write mode before trying it in read-only mode [see the
fdbm_initialize() routine, below].

Am I misinterpreting something?

In any case, how can I do a DBM.open with the guarantee that it will
never even try to open the file in read-write mode?

maybe DBM.open(filename, 0666, DBM::READER) ?
(that sets the RUBY_DBM_RW_BIT... )

That logic is a little confusing to me: by _setting_ RUBY_DBM_RW_BIT in
the flags that are passed to DBM.open, that causes the bit to get
_cleared_ before the dbm_open call gets made. That seems
counter-intuitive, but as long as it works, I'm not going to
complain. :slight_smile:

Thanks.

···

On Tue, Oct 12, 2004 at 02:26:10AM +0900, Lloyd Zusman wrote:

      if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
          mode = 0666; /* default value */
      }

[...]

      if (flags & RUBY_DBM_RW_BIT) {
          flags &= ~RUBY_DBM_RW_BIT;
          dbm = dbm_open(RSTRING(file)->ptr, flags, mode);
      }

--
Lloyd Zusman
ljz@asfast.com
God bless you.