82 lines
1.9 KiB
C
82 lines
1.9 KiB
C
#define _FILE_OFFSET_BITS 64
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <sys/mman.h>
|
|
#include "mstorage.h"
|
|
|
|
#ifdef UNITTEST
|
|
#include <errno.h>
|
|
int failafter=0;
|
|
void* my_mmap(void* addr, size_t len, int prot, int flags, int fd, off_t ofs) {
|
|
if (--failafter == 0) {
|
|
errno=EINVAL;
|
|
return MAP_FAILED;
|
|
}
|
|
return mmap(addr,len,prot,flags,fd,ofs);
|
|
}
|
|
#define mmap my_mmap
|
|
#endif
|
|
|
|
int mstorage_init_persistent(mstorage_t* p,int fd) {
|
|
off_t o;
|
|
p->fd=fd;
|
|
p->mapped=p->used=0;
|
|
p->root=NULL;
|
|
o=lseek(fd,0,SEEK_END);
|
|
if (o==-1)
|
|
return -1;
|
|
if (o==0) {
|
|
if (ftruncate(fd,4096)==-1)
|
|
return -1;
|
|
o=4096;
|
|
}
|
|
p->root=mmap(0,o,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
|
|
if (p->root==MAP_FAILED) {
|
|
p->root=NULL;
|
|
return -1;
|
|
}
|
|
p->mapped=p->used=o;
|
|
return 0;
|
|
}
|
|
|
|
#ifdef UNITTEST
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <fcntl.h>
|
|
#include <sys/resource.h>
|
|
|
|
int main() {
|
|
mstorage_t m;
|
|
char filename[]="/tmp/fooXXXXXX";
|
|
int fd;
|
|
assert((fd=mkstemp(filename)) != -1);
|
|
assert(unlink(filename) == 0);
|
|
// success case
|
|
assert(mstorage_init_persistent(&m, fd) == 0);
|
|
assert(munmap(m.root, m.mapped) == 0);
|
|
assert(close(fd) == 0);
|
|
// make lseek fail
|
|
int pipes[2];
|
|
assert(pipe(pipes) == 0);
|
|
assert(mstorage_init_persistent(&m, pipes[0]) == -1);
|
|
close(pipes[0]); close(pipes[1]);
|
|
// make ftruncate fail
|
|
assert((fd=open(filename, O_RDWR|O_CREAT|O_EXCL, 0600)) != -1);
|
|
assert(close(fd) == 0);
|
|
assert((fd=open(filename, O_RDONLY)) != -1);
|
|
assert(unlink(filename) == 0);
|
|
// fd is now a read-only handle to a 0 byte file
|
|
assert(mstorage_init_persistent(&m, fd) == -1);
|
|
assert(m.root == NULL && m.mapped == 0);
|
|
assert(close(fd) == 0);
|
|
// make mmap fail
|
|
failafter=1;
|
|
assert((fd=open(filename, O_RDWR|O_CREAT|O_EXCL, 0600)) != -1);
|
|
assert(unlink(filename) == 0);
|
|
assert(mstorage_init_persistent(&m, fd) == -1);
|
|
assert(m.root == NULL && m.mapped == 0);
|
|
assert(close(fd) == 0);
|
|
return 0;
|
|
}
|
|
#endif
|