summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/ODBM_File/ODBM_File.xs42
1 files changed, 31 insertions, 11 deletions
diff --git a/ext/ODBM_File/ODBM_File.xs b/ext/ODBM_File/ODBM_File.xs
index 57beaf9a93..bf5def38f8 100644
--- a/ext/ODBM_File/ODBM_File.xs
+++ b/ext/ODBM_File/ODBM_File.xs
@@ -92,7 +92,6 @@ odbm_TIEHASH(dbtype, filename, flags, mode)
{
char *tmpbuf;
void * dbp ;
- Stat_t statbuf;
dMY_CXT;
if (dbmrefcnt++)
@@ -100,16 +99,37 @@ odbm_TIEHASH(dbtype, filename, flags, mode)
Newx(tmpbuf, strlen(filename) + 5, char);
SAVEFREEPV(tmpbuf);
sprintf(tmpbuf,"%s.dir",filename);
- if (stat(tmpbuf, &statbuf) < 0) {
- if (flags & O_CREAT) {
- if (mode < 0 || close(creat(tmpbuf,mode)) < 0)
- croak("ODBM_File: Can't create %s", filename);
- sprintf(tmpbuf,"%s.pag",filename);
- if (close(creat(tmpbuf,mode)) < 0)
- croak("ODBM_File: Can't create %s", filename);
- }
- else
- croak("ODBM_FILE: Can't open %s", filename);
+ if ((flags & O_CREAT)) {
+ const int oflags = O_CREAT | O_TRUNC | O_WRONLY | O_EXCL;
+ int created = 0;
+ int fd;
+ if (mode < 0)
+ goto creat_done;
+ if ((fd = open(tmpbuf,oflags,mode)) < 0 && errno != EEXIST)
+ goto creat_done;
+ if (close(fd) < 0)
+ goto creat_done;
+ sprintf(tmpbuf,"%s.pag",filename);
+ if ((fd = open(tmpbuf,oflags,mode)) < 0 && errno != EEXIST)
+ goto creat_done;
+ if (close(fd) < 0)
+ goto creat_done;
+ created = 1;
+ creat_done:
+ if (!created)
+ croak("ODBM_File: Can't create %s", filename);
+ }
+ else {
+ int opened = 0;
+ int fd;
+ if ((fd = open(tmpbuf,O_RDONLY,mode)) < 0)
+ goto rdonly_done;
+ if (close(fd) < 0)
+ goto rdonly_done;
+ opened = 1;
+ rdonly_done:
+ if (!opened)
+ croak("ODBM_FILE: Can't open %s", filename);
}
dbp = (void*)(dbminit(filename) >= 0 ? &dbmrefcnt : 0);
RETVAL = (ODBM_File)safecalloc(1, sizeof(ODBM_File_type));