Files
mars-tinyldap/mstorage_add.c
leitner 5b980e3f93 ldapclient can now also query for no attributes
mstorage_add can now allocate larger chunks (and parse uses 1 MiB)
fix small oversight in addindex putting wrong index size in header
more integer overflow checks in asn1 code (not security relevant)
fix missing initialization in asn1 routines (not security relevant, code
section not triggered by ldap)
2005-04-01 21:53:33 +00:00

86 lines
2.2 KiB
C

#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/fcntl.h>
#include <sys/shm.h>
#include <stdio.h>
#include "byte.h"
#include "mstorage.h"
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
#define PAGEMASK ((PAGE_SIZE)-1)
unsigned long mstorage_increment=4*PAGE_SIZE;
/* Sadly, mremap is only available on Linux */
/* Please petition your congressman^Woperating system vendor to include it! */
long mstorage_add(mstorage_t* p,const char* s,unsigned long n) {
if (p->mapped-p->used<n) {
if (!p->root) {
/* nothing allocated. mmap /dev/zero */
char* tmp;
long need=(n|PAGEMASK)+1;
#ifdef MREMAP_MAYMOVE
#ifdef MAP_ANONYMOUS
if ((tmp=mmap(0,need,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0))==MAP_FAILED)
return -1;
#else
int fd=open("/dev/zero",O_RDWR);
if (fd<0) return -1;
tmp=mmap(0,need,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0);
close(fd);
if (tmp==MAP_FAILED)
return -1;
#endif
#else
if (!(tmp=malloc(need)))
return -1;
#endif
p->root=tmp;
p->mapped=need;
p->used=0;
} else {
long need=((p->used+n)|PAGEMASK)+1+mstorage_increment;
char* tmp;
#ifdef MREMAP_MAYMOVE
tmp=mremap(p->root,p->mapped,need,MREMAP_MAYMOVE);
if (tmp==MAP_FAILED) return -1;
#else
if (p->fd==-1) {
tmp=realloc(p->root,need);
if (!tmp) return -1;
} else {
munmap(p->root,p->used);
tmp=mmap(0,need,PROT_READ|PROT_WRITE,MAP_SHARED,p->fd,0);
if (tmp==-1) {
tmp=mmap(0,p->used,PROT_READ|PROT_WRITE,MAP_SHARED,p->fd,0);
/* this can never fail, because we mmap exactly as much as we
* had mmapped previously. We need to munmap before doing the
* new mmap, though, because we may run into the address space
* limit too early on 32-bit systems with lots of RAM */
return -1;
}
}
#endif
if (p->fd!=-1) {
/* slight complication if the storage is file based: we need to
* make sure the file size is extended, or the byte_copy will
* yield a bus error. */
if (ftruncate(p->fd,need)==-1) return -1;
}
p->mapped=need; p->root=tmp;
}
}
byte_copy(p->root+p->used,n,s);
{
unsigned long l=p->used;
p->used+=n;
return l;
}
}