This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Skip tests for dl_unload_file() when built with -DPERL_GLOBAL_STRUCT_PRIVATE
[perl5.git] / ext / GDBM_File / GDBM_File.xs
CommitLineData
c5e332f0
NC
1#define PERL_NO_GET_CONTEXT
2
a0d0e21e
LW
3#include "EXTERN.h"
4#include "perl.h"
5#include "XSUB.h"
6
7#include <gdbm.h>
8#include <fcntl.h>
9
a4051d29
NC
10#define fetch_key 0
11#define store_key 1
12#define fetch_value 2
13#define store_value 3
14
9fe6733a
PM
15typedef struct {
16 GDBM_FILE dbp ;
a4051d29 17 SV * filter[4];
9fe6733a
PM
18 int filtering ;
19 } GDBM_File_type;
20
21typedef GDBM_File_type * GDBM_File ;
22typedef datum datum_key ;
23typedef datum datum_value ;
0bf2e707 24typedef datum datum_key_copy;
9fe6733a 25
9fe6733a 26#define GDBM_BLOCKSIZE 0 /* gdbm defaults to stat blocksize */
a0d0e21e 27
93b74b47
NC
28#if defined(GDBM_VERSION_MAJOR) && defined(GDBM_VERSION_MINOR) \
29 && GDBM_VERSION_MAJOR > 1 || \
30 (GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 9)
31typedef void (*FATALFUNC)(const char *);
32#else
33typedef void (*FATALFUNC)();
34#endif
35
8063af02 36#ifndef GDBM_FAST
a0d0e21e 37static int
f0f333f4 38not_here(char *s)
a0d0e21e
LW
39{
40 croak("GDBM_File::%s not implemented on this architecture", s);
41 return -1;
42}
8063af02 43#endif
a0d0e21e 44
097d66a9
GS
45/* GDBM allocates the datum with system malloc() and expects the user
46 * to free() it. So we either have to free() it immediately, or have
47 * perl free() it when it deallocates the SV, depending on whether
48 * perl uses malloc()/free() or not. */
49static void
caa0600b 50output_datum(pTHX_ SV *arg, char *str, int size)
097d66a9 51{
097d66a9 52 sv_setpvn(arg, str, size);
e46b65ad 53# undef free
77b7876f 54 free(str);
097d66a9
GS
55}
56
e50aee73
AD
57/* Versions of gdbm prior to 1.7x might not have the gdbm_sync,
58 gdbm_exists, and gdbm_setopt functions. Apparently Slackware
59 (Linux) 2.1 contains gdbm-1.5 (which dates back to 1991).
60*/
61#ifndef GDBM_FAST
62#define gdbm_exists(db,key) not_here("gdbm_exists")
63#define gdbm_sync(db) (void) not_here("gdbm_sync")
64#define gdbm_setopt(db,optflag,optval,optlen) not_here("gdbm_setopt")
65#endif
66
ceab7011
NC
67static void
68croak_string(const char *message) {
69 Perl_croak_nocontext("%s", message);
70}
71
1cb0fb50 72#include "const-c.inc"
a0d0e21e
LW
73
74MODULE = GDBM_File PACKAGE = GDBM_File PREFIX = gdbm_
75
1cb0fb50 76INCLUDE: const-xs.inc
a0d0e21e
LW
77
78GDBM_File
708cce4f 79gdbm_TIEHASH(dbtype, name, read_write, mode)
a0d0e21e
LW
80 char * dbtype
81 char * name
82 int read_write
83 int mode
9fe6733a
PM
84 CODE:
85 {
86 GDBM_FILE dbp ;
a0d0e21e 87
9fe6733a 88 RETVAL = NULL ;
93b74b47
NC
89 if ((dbp = gdbm_open(name, GDBM_BLOCKSIZE, read_write, mode,
90 (FATALFUNC) croak_string))) {
a5c6857c 91 RETVAL = (GDBM_File)safecalloc(1, sizeof(GDBM_File_type)) ;
9fe6733a
PM
92 RETVAL->dbp = dbp ;
93 }
94
95 }
96 OUTPUT:
97 RETVAL
98
99
100#define gdbm_close(db) gdbm_close(db->dbp)
a0d0e21e
LW
101void
102gdbm_close(db)
103 GDBM_File db
104 CLEANUP:
105
106void
107gdbm_DESTROY(db)
108 GDBM_File db
a4051d29
NC
109 PREINIT:
110 int i = store_value;
a0d0e21e
LW
111 CODE:
112 gdbm_close(db);
a4051d29
NC
113 do {
114 if (db->filter[i])
115 SvREFCNT_dec(db->filter[i]);
116 } while (i-- > 0);
eb99164f 117 safefree(db);
a0d0e21e 118
9fe6733a
PM
119#define gdbm_FETCH(db,key) gdbm_fetch(db->dbp,key)
120datum_value
a0d0e21e
LW
121gdbm_FETCH(db, key)
122 GDBM_File db
0bf2e707 123 datum_key_copy key
a0d0e21e 124
9fe6733a 125#define gdbm_STORE(db,key,value,flags) gdbm_store(db->dbp,key,value,flags)
a0d0e21e
LW
126int
127gdbm_STORE(db, key, value, flags = GDBM_REPLACE)
128 GDBM_File db
9fe6733a
PM
129 datum_key key
130 datum_value value
a0d0e21e
LW
131 int flags
132 CLEANUP:
133 if (RETVAL) {
134 if (RETVAL < 0 && errno == EPERM)
135 croak("No write permission to gdbm file");
748a9306 136 croak("gdbm store returned %d, errno %d, key \"%.*s\"",
a0d0e21e 137 RETVAL,errno,key.dsize,key.dptr);
a0d0e21e
LW
138 }
139
9fe6733a 140#define gdbm_DELETE(db,key) gdbm_delete(db->dbp,key)
a0d0e21e
LW
141int
142gdbm_DELETE(db, key)
143 GDBM_File db
9fe6733a 144 datum_key key
a0d0e21e 145
9fe6733a
PM
146#define gdbm_FIRSTKEY(db) gdbm_firstkey(db->dbp)
147datum_key
a0d0e21e
LW
148gdbm_FIRSTKEY(db)
149 GDBM_File db
150
9fe6733a
PM
151#define gdbm_NEXTKEY(db,key) gdbm_nextkey(db->dbp,key)
152datum_key
a0d0e21e
LW
153gdbm_NEXTKEY(db, key)
154 GDBM_File db
0bf2e707 155 datum_key key
a0d0e21e 156
9fe6733a 157#define gdbm_reorganize(db) gdbm_reorganize(db->dbp)
a0d0e21e
LW
158int
159gdbm_reorganize(db)
160 GDBM_File db
161
3b35bae3 162
9fe6733a 163#define gdbm_sync(db) gdbm_sync(db->dbp)
3b35bae3
AD
164void
165gdbm_sync(db)
166 GDBM_File db
167
9fe6733a 168#define gdbm_EXISTS(db,key) gdbm_exists(db->dbp,key)
3b35bae3 169int
c07a80fd 170gdbm_EXISTS(db, key)
3b35bae3 171 GDBM_File db
9fe6733a 172 datum_key key
3b35bae3 173
9fe6733a 174#define gdbm_setopt(db,optflag, optval, optlen) gdbm_setopt(db->dbp,optflag, optval, optlen)
3b35bae3
AD
175int
176gdbm_setopt (db, optflag, optval, optlen)
177 GDBM_File db
178 int optflag
179 int &optval
180 int optlen
181
9fe6733a 182
9fe6733a
PM
183SV *
184filter_fetch_key(db, code)
185 GDBM_File db
186 SV * code
187 SV * RETVAL = &PL_sv_undef ;
a4051d29
NC
188 ALIAS:
189 GDBM_File::filter_fetch_key = fetch_key
190 GDBM_File::filter_store_key = store_key
191 GDBM_File::filter_fetch_value = fetch_value
192 GDBM_File::filter_store_value = store_value
9fe6733a 193 CODE:
a4051d29 194 DBM_setFilter(db->filter[ix], code);