a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | |
3e9a46 | 2002-01-16 | Martin Nilsson | | ||| This file is part of Pike. For copyright information see COPYRIGHT.
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | ||| Pike is distributed as GPL (General Public License)
||| See the files COPYING and DISCLAIMER for more information.
\*/
#include "global.h"
|
6ad237 | 2002-05-11 | Martin Nilsson | | RCSID("$Id: gdbmmod.c,v 1.17 2002/05/11 00:27:02 nilsson Exp $");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | #include "gdbm_machine.h"
#include "threads.h"
#include "interpret.h"
#include "svalue.h"
#include "stralloc.h"
#include "array.h"
#include "object.h"
|
bb55f8 | 1997-03-16 | Fredrik Hübinette (Hubbe) | | #include "pike_macros.h"
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
6dc277 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | #if defined(HAVE_GDBM_H) && defined(HAVE_LIBGDBM)
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | #include <gdbm.h>
#ifdef _REENTRANT
|
d3015d | 2000-04-18 | Jonas Wallden | | static MUTEX_T gdbm_lock STATIC_MUTEX_INIT;
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | #endif
|
6ad237 | 2002-05-11 | Martin Nilsson | |
#include "module_magic.h"
#define sp Pike_sp
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | struct gdbm_glue
{
GDBM_FILE dbf;
};
|
39221e | 2000-07-07 | Henrik Grubbström (Grubba) | | #define THIS ((struct gdbm_glue *)(Pike_fp->current_storage))
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | static void do_free(void)
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | {
if(THIS->dbf)
{
GDBM_FILE dbf;
dbf=THIS->dbf;
THIS->dbf=0;
THREADS_ALLOW();
mt_lock(& gdbm_lock);
gdbm_close(dbf);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
}
}
static int fixmods(char *mods)
{
int mode;
mode=0;
while(1)
{
switch(*(mods++))
{
case 0:
switch(mode & 15)
{
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | default: Pike_error("No mode given for gdbm->open()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | case 1|16:
case 1: mode=GDBM_READER; break;
case 3: mode=GDBM_WRITER; break;
case 3|16: mode=GDBM_WRITER | GDBM_FAST; break;
case 7: mode=GDBM_WRCREAT; break;
case 7|16: mode=GDBM_WRCREAT | GDBM_FAST; break;
case 15: mode=GDBM_NEWDB; break;
case 15|16: mode=GDBM_NEWDB | GDBM_FAST; break;
}
return mode;
case 'r': case 'R': mode|=1; break;
case 'w': case 'W': mode|=3; break;
case 'c': case 'C': mode|=7; break;
case 't': case 'T': mode|=15; break;
case 'f': case 'F': mode|=16; break;
default:
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad mode flag in gdbm->open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
}
}
void gdbmmod_fatal(char *err)
{
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("GDBM: %s\n",err);
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
|
fc293f | 2001-10-26 | Martin Nilsson | |
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_create(INT32 args)
{
struct gdbm_glue *this=THIS;
do_free();
if(args)
{
GDBM_FILE tmp;
struct pike_string *tmp2;
int rwmode = GDBM_WRCREAT;
if(sp[-args].type != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 1 to gdbm->create()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if(args>1)
{
if(sp[1-args].type != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 2 to gdbm->create()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
rwmode=fixmods(sp[1-args].u.string->str);
}
tmp2=sp[-args].u.string;
THREADS_ALLOW();
mt_lock(& gdbm_lock);
tmp=gdbm_open(tmp2->str, 512, rwmode, 00666, gdbmmod_fatal);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
|
39221e | 2000-07-07 | Henrik Grubbström (Grubba) | | if(!Pike_fp->current_object->prog)
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | {
if(tmp) gdbm_close(tmp);
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Object destructed in gdbm->open()n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
THIS->dbf=tmp;
pop_n_elems(args);
if(!THIS->dbf)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Failed to open GDBM database.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
}
#define STRING_TO_DATUM(dat, st) dat.dptr=st->str,dat.dsize=st->len;
#define DATUM_TO_STRING(dat) make_shared_binary_string(dat.dptr, dat.dsize)
|
fc293f | 2001-10-26 | Martin Nilsson | |
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_fetch(INT32 args)
{
struct gdbm_glue *this=THIS;
datum key,ret;
if(!args)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Too few arguments to gdbm->fetch()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if(sp[-args].type != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 1 to gdbm->fetch()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if(!THIS->dbf)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
STRING_TO_DATUM(key, sp[-args].u.string);
THREADS_ALLOW();
mt_lock(& gdbm_lock);
ret=gdbm_fetch(this->dbf, key);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
pop_n_elems(args);
if(ret.dptr)
{
push_string(DATUM_TO_STRING(ret));
free(ret.dptr);
}else{
push_int(0);
}
}
|
fc293f | 2001-10-26 | Martin Nilsson | |
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_delete(INT32 args)
{
struct gdbm_glue *this=THIS;
datum key;
int ret;
if(!args)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Too few arguments to gdbm->delete()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if(sp[-args].type != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 1 to gdbm->delete()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if(!this->dbf)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
STRING_TO_DATUM(key, sp[-args].u.string);
THREADS_ALLOW();
mt_lock(& gdbm_lock);
ret=gdbm_delete(this->dbf, key);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
pop_n_elems(args);
push_int(0);
}
|
fc293f | 2001-10-26 | Martin Nilsson | |
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_firstkey(INT32 args)
{
struct gdbm_glue *this=THIS;
datum ret;
pop_n_elems(args);
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | if(!this->dbf) Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
THREADS_ALLOW();
mt_lock(& gdbm_lock);
ret=gdbm_firstkey(this->dbf);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
if(ret.dptr)
{
push_string(DATUM_TO_STRING(ret));
free(ret.dptr);
}else{
push_int(0);
}
}
|
fc293f | 2001-10-26 | Martin Nilsson | |
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_nextkey(INT32 args)
{
struct gdbm_glue *this=THIS;
datum key,ret;
if(!args)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Too few arguments to gdbm->nextkey()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if(sp[-args].type != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 1 to gdbm->nextkey()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if(!THIS->dbf)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
STRING_TO_DATUM(key, sp[-args].u.string);
THREADS_ALLOW();
mt_lock(& gdbm_lock);
ret=gdbm_nextkey(this->dbf, key);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
pop_n_elems(args);
if(ret.dptr)
{
push_string(DATUM_TO_STRING(ret));
free(ret.dptr);
}else{
push_int(0);
}
}
|
fc293f | 2001-10-26 | Martin Nilsson | |
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_store(INT32 args)
{
struct gdbm_glue *this=THIS;
datum key,data;
|
04878b | 2001-01-23 | John W. Pierce | | int method = GDBM_REPLACE;
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | int ret;
if(args<2)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Too few arguments to gdbm->store()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if(sp[-args].type != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 1 to gdbm->store()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if(sp[1-args].type != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 2 to gdbm->store()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
04878b | 2001-01-23 | John W. Pierce | | if (args > 2) {
if (sp[2-args].type != T_INT) {
Pike_error("Bad argument 3 to gdbm->store()\n");
}
if (sp[2-args].u.integer) {
method = GDBM_INSERT;
}
}
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | if(!THIS->dbf)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
STRING_TO_DATUM(key, sp[-args].u.string);
STRING_TO_DATUM(data, sp[1-args].u.string);
THREADS_ALLOW();
mt_lock(& gdbm_lock);
|
04878b | 2001-01-23 | John W. Pierce | | ret=gdbm_store(this->dbf, key, data, method);
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
|
04878b | 2001-01-23 | John W. Pierce | | if(ret == -1) {
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("GDBM database not open for writing.\n");
|
04878b | 2001-01-23 | John W. Pierce | | } else if (ret == 1) {
Pike_error("Duplicate key.\n");
}
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
push_int(ret == 0);
}
|
fc293f | 2001-10-26 | Martin Nilsson | |
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_reorganize(INT32 args)
{
struct gdbm_glue *this=THIS;
int ret;
pop_n_elems(args);
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | if(!THIS->dbf) Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | THREADS_ALLOW();
mt_lock(& gdbm_lock);
ret=gdbm_reorganize(this->dbf);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
pop_n_elems(args);
push_int(ret);
}
|
fc293f | 2001-10-26 | Martin Nilsson | |
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_sync(INT32 args)
{
struct gdbm_glue *this=THIS;
pop_n_elems(args);
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | if(!THIS->dbf) Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | THREADS_ALLOW();
mt_lock(& gdbm_lock);
gdbm_sync(this->dbf);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
push_int(0);
}
|
fc293f | 2001-10-26 | Martin Nilsson | |
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_close(INT32 args)
{
pop_n_elems(args);
|
1458b9 | 1997-08-31 | Henrik Grubbström (Grubba) | | do_free();
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | push_int(0);
}
static void init_gdbm_glue(struct object *o)
{
THIS->dbf=0;
}
static void exit_gdbm_glue(struct object *o)
{
do_free();
}
|
fc293f | 2001-10-26 | Martin Nilsson | |
#endif /* defined(HAVE_GDBM_H) && defined(HAVE_LIBGDBM) */
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
void pike_module_exit(void) {}
void pike_module_init(void)
{
#if defined(HAVE_GDBM_H) && defined(HAVE_LIBGDBM)
start_new_program();
|
90e978 | 1999-01-31 | Fredrik Hübinette (Hubbe) | | ADD_STORAGE(struct gdbm_glue);
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
04878b | 2001-01-23 | John W. Pierce | | ADD_FUNCTION("create", gdbmmod_create,
|
4aa1e7 | 2001-01-23 | Henrik Grubbström (Grubba) | | tFunc(tOr(tVoid,tStr) tOr(tVoid,tStr), tVoid), 0 );
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
e64f5a | 1999-06-19 | Fredrik Hübinette (Hubbe) | | ADD_FUNCTION("close",gdbmmod_close,tFunc(tNone,tVoid),0);
|
04878b | 2001-01-23 | John W. Pierce | |
ADD_FUNCTION("store", gdbmmod_store,
tFunc(tStr tStr tOr(tInt01, tVoid), tInt), 0);
ADD_FUNCTION("`[]=", gdbmmod_store,
tFunc(tStr tStr tOr(tInt01, tVoid), tInt), 0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
ADD_FUNCTION("fetch",gdbmmod_fetch,tFunc(tStr,tStr),0);
ADD_FUNCTION("`[]",gdbmmod_fetch,tFunc(tStr,tStr),0);
ADD_FUNCTION("delete",gdbmmod_delete,tFunc(tStr,tInt),0);
|
e64f5a | 1999-06-19 | Fredrik Hübinette (Hubbe) | | ADD_FUNCTION("firstkey",gdbmmod_firstkey,tFunc(tNone,tStr),0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
ADD_FUNCTION("nextkey",gdbmmod_nextkey,tFunc(tStr,tStr),0);
|
e64f5a | 1999-06-19 | Fredrik Hübinette (Hubbe) | | ADD_FUNCTION("reorganize",gdbmmod_reorganize,tFunc(tNone,tInt),0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
e64f5a | 1999-06-19 | Fredrik Hübinette (Hubbe) | | ADD_FUNCTION("sync",gdbmmod_sync,tFunc(tNone,tVoid),0);
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
set_init_callback(init_gdbm_glue);
set_exit_callback(exit_gdbm_glue);
end_class("gdbm",0);
#endif
}
|