Undo io_linenum.t part of #34148. It was io_multihomed.t that I meant
[p5sagit/p5-mst-13.2.git] / ext / SDBM_File / sdbm / sdbm.c
index a62334c..cc6d0e9 100644 (file)
@@ -7,11 +7,11 @@
  * core routines
  */
 
-#ifndef lint
-static char rcsid[] = "$Id: sdbm.c,v 1.16 90/12/13 13:01:31 oz Exp $";
-#endif
-
+#include "INTERN.h"
 #include "config.h"
+#ifdef WIN32
+#include "io.h"
+#endif
 #include "sdbm.h"
 #include "tune.h"
 #include "pair.h"
@@ -24,7 +24,9 @@ static char rcsid[] = "$Id: sdbm.c,v 1.16 90/12/13 13:01:31 oz Exp $";
 #endif
 
 #ifdef I_STRING
-# include <string.h>
+# ifndef __ultrix__
+#  include <string.h>
+# endif
 #else
 # include <strings.h>
 #endif
@@ -32,13 +34,12 @@ static char rcsid[] = "$Id: sdbm.c,v 1.16 90/12/13 13:01:31 oz Exp $";
 /*
  * externals
  */
-#ifndef sun
-extern int errno;
-#endif
+
+#include <errno.h> /* See notes in perl.h about avoiding
+                       extern int errno; */
 
 extern Malloc_t malloc proto((MEM_SIZE));
 extern Free_t free proto((Malloc_t));
-extern Off_t lseek();
 
 /*
  * forward
@@ -59,7 +60,7 @@ static int makroom proto((DBM *, long, int));
 #define OFF_PAG(off)   (long) (off) * PBLKSIZ
 #define OFF_DIR(off)   (long) (off) * DBLKSIZ
 
-static long masks[] = {
+static const long masks[] = {
        000000000000, 000000000001, 000000000003, 000000000007,
        000000000017, 000000000037, 000000000077, 000000000177,
        000000000377, 000000000777, 000000001777, 000000003777,
@@ -70,13 +71,8 @@ static long masks[] = {
        001777777777, 003777777777, 007777777777, 017777777777
 };
 
-datum nullitem = {NULL, 0};
-
 DBM *
-sdbm_open(file, flags, mode)
-register char *file;
-register int flags;
-register int mode;
+sdbm_open(register char *file, register int flags, register int mode)
 {
        register DBM *db;
        register char *dirname;
@@ -90,7 +86,7 @@ register int mode;
  */
        n = strlen(file) * 2 + strlen(DIRFEXT) + strlen(PAGFEXT) + 2;
 
-       if ((dirname = malloc((unsigned) n)) == NULL)
+       if ((dirname = (char *) malloc((unsigned) n)) == NULL)
                return errno = ENOMEM, (DBM *) NULL;
 /*
  * build the file names
@@ -105,11 +101,7 @@ register int mode;
 }
 
 DBM *
-sdbm_prep(dirname, pagname, flags, mode)
-char *dirname;
-char *pagname;
-int flags;
-int mode;
+sdbm_prep(char *dirname, char *pagname, int flags, int mode)
 {
        register DBM *db;
        struct stat dstat;
@@ -135,7 +127,7 @@ int mode;
  * open the files in sequence, and stat the dirfile.
  * If we fail anywhere, undo everything, return NULL.
  */
-#if defined(OS2) || defined(MSDOS)
+#if defined(OS2) || defined(MSDOS) || defined(WIN32) || defined(__CYGWIN__)
        flags |= O_BINARY;
 #      endif
        if ((db->pagf = open(pagname, flags, mode)) > -1) {
@@ -168,8 +160,7 @@ int mode;
 }
 
 void
-sdbm_close(db)
-register DBM *db;
+sdbm_close(register DBM *db)
 {
        if (db == NULL)
                errno = EINVAL;
@@ -181,9 +172,7 @@ register DBM *db;
 }
 
 datum
-sdbm_fetch(db, key)
-register DBM *db;
-datum key;
+sdbm_fetch(register DBM *db, datum key)
 {
        if (db == NULL || bad(key))
                return errno = EINVAL, nullitem;
@@ -195,9 +184,19 @@ datum key;
 }
 
 int
-sdbm_delete(db, key)
-register DBM *db;
-datum key;
+sdbm_exists(register DBM *db, datum key)
+{
+       if (db == NULL || bad(key))
+               return errno = EINVAL, -1;
+
+       if (getpage(db, exhash(key)))
+               return exipair(db->pagbuf, key);
+
+       return ioerr(db), -1;
+}
+
+int
+sdbm_delete(register DBM *db, datum key)
 {
        if (db == NULL || bad(key))
                return errno = EINVAL, -1;
@@ -221,11 +220,7 @@ datum key;
 }
 
 int
-sdbm_store(db, key, val, flags)
-register DBM *db;
-datum key;
-datum val;
-int flags;
+sdbm_store(register DBM *db, datum key, datum val, int flags)
 {
        int need;
        register long hash;
@@ -283,22 +278,23 @@ int flags;
  * giving up.
  */
 static int
-makroom(db, hash, need)
-register DBM *db;
-long hash;
-int need;
+makroom(register DBM *db, long int hash, int need)
 {
        long newp;
        char twin[PBLKSIZ];
+#if defined(DOSISH) || defined(WIN32)
+       char zer[PBLKSIZ];
+       long oldtail;
+#endif
        char *pag = db->pagbuf;
-       char *new = twin;
+       char *New = twin;
        register int smax = SPLTMAX;
 
        do {
 /*
  * split the current page
  */
-               (void) splpage(pag, new, db->hmask + 1);
+               (void) splpage(pag, New, db->hmask + 1);
 /*
  * address of the new page
  */
@@ -312,15 +308,32 @@ int need;
  * still looking at the page of interest. current page is not updated
  * here, as sdbm_store will do so, after it inserts the incoming pair.
  */
+
+#if defined(DOSISH) || defined(WIN32)
+               /*
+                * Fill hole with 0 if made it.
+                * (hole is NOT read as 0)
+                */
+               oldtail = lseek(db->pagf, 0L, SEEK_END);
+               memset(zer, 0, PBLKSIZ);
+               while (OFF_PAG(newp) > oldtail) {
+                       if (lseek(db->pagf, 0L, SEEK_END) < 0 ||
+                           write(db->pagf, zer, PBLKSIZ) < 0) {
+
+                               return 0;
+                       }
+                       oldtail += PBLKSIZ;
+               }
+#endif
                if (hash & (db->hmask + 1)) {
                        if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0
                            || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)
                                return 0;
                        db->pagbno = newp;
-                       (void) memcpy(pag, new, PBLKSIZ);
+                       (void) memcpy(pag, New, PBLKSIZ);
                }
                else if (lseek(db->pagf, OFF_PAG(newp), SEEK_SET) < 0
-                        || write(db->pagf, new, PBLKSIZ) < 0)
+                        || write(db->pagf, New, PBLKSIZ) < 0)
                        return 0;
 
                if (!setdbit(db, db->curbit))
@@ -361,8 +374,7 @@ int need;
  * deletions aren't taken into account. (ndbm bug)
  */
 datum
-sdbm_firstkey(db)
-register DBM *db;
+sdbm_firstkey(register DBM *db)
 {
        if (db == NULL)
                return errno = EINVAL, nullitem;
@@ -380,8 +392,7 @@ register DBM *db;
 }
 
 datum
-sdbm_nextkey(db)
-register DBM *db;
+sdbm_nextkey(register DBM *db)
 {
        if (db == NULL)
                return errno = EINVAL, nullitem;
@@ -392,9 +403,7 @@ register DBM *db;
  * all important binary trie traversal
  */
 static int
-getpage(db, hash)
-register DBM *db;
-register long hash;
+getpage(register DBM *db, register long int hash)
 {
        register int hbit;
        register long dbit;
@@ -433,9 +442,7 @@ register long hash;
 }
 
 static int
-getdbit(db, dbit)
-register DBM *db;
-register long dbit;
+getdbit(register DBM *db, register long int dbit)
 {
        register long c;
        register long dirb;
@@ -444,9 +451,12 @@ register long dbit;
        dirb = c / DBLKSIZ;
 
        if (dirb != db->dirbno) {
+               int got;
                if (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0
-                   || read(db->dirf, db->dirbuf, DBLKSIZ) < 0)
+                   || (got=read(db->dirf, db->dirbuf, DBLKSIZ)) < 0)
                        return 0;
+               if (got==0) 
+                       memset(db->dirbuf,0,DBLKSIZ);
                db->dirbno = dirb;
 
                debug(("dir read: %d\n", dirb));
@@ -456,9 +466,7 @@ register long dbit;
 }
 
 static int
-setdbit(db, dbit)
-register DBM *db;
-register long dbit;
+setdbit(register DBM *db, register long int dbit)
 {
        register long c;
        register long dirb;
@@ -467,9 +475,12 @@ register long dbit;
        dirb = c / DBLKSIZ;
 
        if (dirb != db->dirbno) {
+               int got;
                if (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0
-                   || read(db->dirf, db->dirbuf, DBLKSIZ) < 0)
+                   || (got=read(db->dirf, db->dirbuf, DBLKSIZ)) < 0)
                        return 0;
+               if (got==0) 
+                       memset(db->dirbuf,0,DBLKSIZ);
                db->dirbno = dirb;
 
                debug(("dir read: %d\n", dirb));
@@ -477,8 +488,13 @@ register long dbit;
 
        db->dirbuf[c % DBLKSIZ] |= (1 << dbit % BYTESIZ);
 
+#if 0
        if (dbit >= db->maxbno)
                db->maxbno += DBLKSIZ * BYTESIZ;
+#else
+       if (OFF_DIR((dirb+1))*BYTESIZ > db->maxbno) 
+               db->maxbno=OFF_DIR((dirb+1))*BYTESIZ;
+#endif
 
        if (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0
            || write(db->dirf, db->dirbuf, DBLKSIZ) < 0)
@@ -492,8 +508,7 @@ register long dbit;
  * the page, try the next page in sequence
  */
 static datum
-getnext(db)
-register DBM *db;
+getnext(register DBM *db)
 {
        datum key;