minix/lib/libelf/compat/mmap.c
2011-05-21 19:15:26 +02:00

73 lines
1.3 KiB
C

#include <sys/cdefs.h>
#include <sys/types.h>
#include <err.h>
#include <errno.h>
#include <libelf.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "_libelf.h"
#include "../libelf_compat.h"
void *
libelf_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
{
void *p; /* malloc'ed pointer */
size_t bufsize;
if ((addr != NULL) || (flags != MAP_PRIVATE) || (prot != PROT_READ)) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (MAP_FAILED);
}
/*
* Fall back to malloc+read.
*/
p = NULL;
bufsize = 1024 * 1024;
while (/*CONSTCOND*/true) {
void *newp = realloc(p, bufsize);
ssize_t rsz;
if (newp == NULL) {
free(p);
LIBELF_SET_ERROR(RESOURCE, 0);
return (MAP_FAILED);
}
p = newp;
rsz = pread(fd, p, bufsize, 0);
if (rsz == -1) {
free(p);
LIBELF_SET_ERROR(IO, errno);
return (MAP_FAILED);
} else if ((size_t) rsz > bufsize) {
free(p);
LIBELF_SET_ERROR(IO, EIO); /* XXX */
return (MAP_FAILED);
} else if ((size_t) rsz < bufsize) {
/*
* try to shrink the buffer.
*/
newp = realloc(p, (size_t) rsz);
if (newp != NULL) {
p = newp;
}
break;
}
bufsize *= 2;
}
return p;
}
int
libelf_munmap(void *addr, size_t len)
{
free(addr);
return 0;
}