Method: DBM#initialize

Defined in:
dbm.c

- (Object) new(filename[, mode[, flags]])

Open a dbm database with the specified name, which can include a directory path. Any file extensions needed will be supplied automatically by the dbm library. For example, Berkeley DB appends '.db', and GNU gdbm uses two physical files with extensions '.dir' and '.pag'.

The mode should be an integer, as for Unix chmod.

Flags should be one of READER, WRITER, WRCREAT or NEWDB.



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'dbm.c', line 125

static VALUE
fdbm_initialize(int argc, VALUE *argv, VALUE obj)
{
    volatile VALUE file;
    VALUE 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);

    FilePathValue(file);

    /*
     * Note:
     * gdbm 1.10 works with O_CLOEXEC.  gdbm 1.9.1 silently ignore it.
     */
#ifndef O_CLOEXEC
#   define O_CLOEXEC 0
#endif

    if (flags & RUBY_DBM_RW_BIT) {
        flags &= ~RUBY_DBM_RW_BIT;
        dbm = dbm_open(RSTRING_PTR(file), flags|O_CLOEXEC, mode);
    }
    else {
        dbm = 0;
        if (mode >= 0) {
            dbm = dbm_open(RSTRING_PTR(file), O_RDWR|O_CREAT|O_CLOEXEC, mode);
        }
        if (!dbm) {
            dbm = dbm_open(RSTRING_PTR(file), O_RDWR|O_CLOEXEC, 0);
        }
        if (!dbm) {
            dbm = dbm_open(RSTRING_PTR(file), O_RDONLY|O_CLOEXEC, 0);
        }
    }

    if (dbm) {
    /*
     * History of dbm_pagfno() and dbm_dirfno() in ndbm and its compatibles.
     * (dbm_pagfno() and dbm_dirfno() is not standardized.)
     *
     * 1986: 4.3BSD provides ndbm.
     *       It provides dbm_pagfno() and dbm_dirfno() as macros.
     * 1991: gdbm-1.5 provides them as functions.
     *       They returns a same descriptor.
     *       (Earlier releases may have the functions too.)
     * 1991: Net/2 provides Berkeley DB.
     *       It doesn't provide dbm_pagfno() and dbm_dirfno().
     * 1992: 4.4BSD Alpha provides Berkeley DB with dbm_dirfno() as a function.
     *       dbm_pagfno() is a macro as DBM_PAGFNO_NOT_AVAILABLE.
     * 1997: Berkeley DB 2.0 is released by Sleepycat Software, Inc.
     *       It defines dbm_pagfno() and dbm_dirfno() as macros.
     * 2011: gdbm-1.9 creates a separate dir file.
     *       dbm_pagfno() and dbm_dirfno() returns different descriptors.
     */
#if defined(HAVE_DBM_PAGFNO)
        rb_fd_fix_cloexec(dbm_pagfno(dbm));
#endif
#if defined(HAVE_DBM_DIRFNO)
        rb_fd_fix_cloexec(dbm_dirfno(dbm));
#endif

#if defined(RUBYDBM_DB_HEADER) && defined(HAVE_TYPE_DBC)
    /* Disable Berkeley DB error messages such as:
     * DB->put: attempt to modify a read-only database */
        ((DBC*)dbm)->dbp->set_errfile(((DBC*)dbm)->dbp, NULL);
#endif
    }

    if (!dbm) {
	if (mode == -1) return Qnil;
	rb_sys_fail_str(file);
    }

    dbmp = ALLOC(struct dbmdata);
    DATA_PTR(obj) = dbmp;
    dbmp->di_dbm = dbm;
    dbmp->di_size = -1;

    return obj;
}

Comments