- Moved unused argc, temp variable into small scope.
[dragonfly.git] / contrib / perl5 / ext / ODBM_File / ODBM_File.xs
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #ifdef NULL
6 #undef NULL  /* XXX Why? */
7 #endif
8 #ifdef I_DBM
9 #  include <dbm.h>
10 #else
11 #  ifdef I_RPCSVC_DBM
12 #    include <rpcsvc/dbm.h>
13 #  endif
14 #endif
15
16 #ifdef DBM_BUG_DUPLICATE_FREE 
17 /*
18  * DBM on at least Ultrix and HPUX call dbmclose() from dbminit(),
19  * resulting in duplicate free() because dbmclose() does *not*
20  * check if it has already been called for this DBM.
21  * If some malloc/free calls have been done between dbmclose() and
22  * the next dbminit(), the memory might be used for something else when
23  * it is freed.
24  * Verified to work on ultrix4.3.  Probably will work on HP/UX.
25  * Set DBM_BUG_DUPLICATE_FREE in the extension hint file.
26  */
27 /* Close the previous dbm, and fail to open a new dbm */
28 #define dbmclose()      ((void) dbminit("/tmp/x/y/z/z/y"))
29 #endif
30
31 #include <fcntl.h>
32
33 typedef void* ODBM_File;
34
35 #define odbm_FETCH(db,key)                      fetch(key)
36 #define odbm_STORE(db,key,value,flags)          store(key,value)
37 #define odbm_DELETE(db,key)                     delete(key)
38 #define odbm_FIRSTKEY(db)                       firstkey()
39 #define odbm_NEXTKEY(db,key)                    nextkey(key)
40
41 static int dbmrefcnt;
42
43 #ifndef DBM_REPLACE
44 #define DBM_REPLACE 0
45 #endif
46
47 MODULE = ODBM_File      PACKAGE = ODBM_File     PREFIX = odbm_
48
49 #ifndef NULL
50 #  define NULL 0
51 #endif
52
53 ODBM_File
54 odbm_TIEHASH(dbtype, filename, flags, mode)
55         char *          dbtype
56         char *          filename
57         int             flags
58         int             mode
59         CODE:
60         {
61             char *tmpbuf;
62             if (dbmrefcnt++)
63                 croak("Old dbm can only open one database");
64             New(0, tmpbuf, strlen(filename) + 5, char);
65             SAVEFREEPV(tmpbuf);
66             sprintf(tmpbuf,"%s.dir",filename);
67             if (stat(tmpbuf, &PL_statbuf) < 0) {
68                 if (flags & O_CREAT) {
69                     if (mode < 0 || close(creat(tmpbuf,mode)) < 0)
70                         croak("ODBM_File: Can't create %s", filename);
71                     sprintf(tmpbuf,"%s.pag",filename);
72                     if (close(creat(tmpbuf,mode)) < 0)
73                         croak("ODBM_File: Can't create %s", filename);
74                 }
75                 else
76                     croak("ODBM_FILE: Can't open %s", filename);
77             }
78             RETVAL = (void*)(dbminit(filename) >= 0 ? &dbmrefcnt : 0);
79             ST(0) = sv_mortalcopy(&PL_sv_undef);
80             sv_setptrobj(ST(0), RETVAL, dbtype);
81         }
82
83 void
84 DESTROY(db)
85         ODBM_File       db
86         CODE:
87         dbmrefcnt--;
88         dbmclose();
89
90 datum
91 odbm_FETCH(db, key)
92         ODBM_File       db
93         datum           key
94
95 int
96 odbm_STORE(db, key, value, flags = DBM_REPLACE)
97         ODBM_File       db
98         datum           key
99         datum           value
100         int             flags
101     CLEANUP:
102         if (RETVAL) {
103             if (RETVAL < 0 && errno == EPERM)
104                 croak("No write permission to odbm file");
105             croak("odbm store returned %d, errno %d, key \"%s\"",
106                         RETVAL,errno,key.dptr);
107         }
108
109 int
110 odbm_DELETE(db, key)
111         ODBM_File       db
112         datum           key
113
114 datum
115 odbm_FIRSTKEY(db)
116         ODBM_File       db
117
118 datum
119 odbm_NEXTKEY(db, key)
120         ODBM_File       db
121         datum           key
122