Blame src/internal/slibtool_mapfile_impl.c
|
|
0f9f97 |
#include <fcntl.h>
|
|
|
0f9f97 |
#include <errno.h>
|
|
|
0f9f97 |
#include <unistd.h>
|
|
|
0f9f97 |
#include <stdint.h>
|
|
|
0f9f97 |
#include <stdlib.h>
|
|
|
0f9f97 |
#include <sys/mman.h>
|
|
|
0f9f97 |
#include <sys/stat.h>
|
|
|
0f9f97 |
#include "slibtool_mapfile_impl.h"
|
|
|
0f9f97 |
|
|
|
0f9f97 |
static void slbt_munmap(void * addr, size_t size)
|
|
|
0f9f97 |
{
|
|
|
0f9f97 |
if (addr) {
|
|
|
0f9f97 |
munmap(addr,size);
|
|
|
0f9f97 |
}
|
|
|
0f9f97 |
}
|
|
|
0f9f97 |
|
|
|
0f9f97 |
struct slbt_map_info * slbt_map_file(
|
|
|
0f9f97 |
int fdat,
|
|
|
0f9f97 |
const char * path,
|
|
|
0f9f97 |
uint32_t flags)
|
|
|
0f9f97 |
{
|
|
|
0f9f97 |
int fd;
|
|
|
0f9f97 |
void * addr;
|
|
|
0f9f97 |
struct stat st;
|
|
|
0f9f97 |
uint32_t oflag;
|
|
|
0f9f97 |
uint32_t mprot;
|
|
|
0f9f97 |
struct slbt_map_info * mapinfo;
|
|
|
0f9f97 |
|
|
|
0f9f97 |
if ((flags & SLBT_MAP_INPUT) && (flags & SLBT_MAP_OUTPUT)) {
|
|
|
0f9f97 |
oflag = O_RDWR;
|
|
|
0f9f97 |
mprot = PROT_READ|PROT_WRITE;
|
|
|
0f9f97 |
} else if (flags & SLBT_MAP_INPUT) {
|
|
|
0f9f97 |
oflag = O_RDONLY;
|
|
|
0f9f97 |
mprot = PROT_READ;
|
|
|
0f9f97 |
} else if (flags & SLBT_MAP_OUTPUT) {
|
|
|
0f9f97 |
oflag = O_WRONLY;
|
|
|
0f9f97 |
mprot = PROT_WRITE;
|
|
|
0f9f97 |
} else {
|
|
|
0f9f97 |
errno = EINVAL;
|
|
|
0f9f97 |
return 0;
|
|
|
0f9f97 |
}
|
|
|
0f9f97 |
|
|
|
0f9f97 |
if ((fd = openat(fdat,path,oflag,0)) < 0)
|
|
|
0f9f97 |
return 0;
|
|
|
0f9f97 |
|
|
|
0f9f97 |
if (fstat(fd,&st) < 0) {
|
|
|
0f9f97 |
close(fd);
|
|
|
0f9f97 |
return 0;
|
|
|
0f9f97 |
}
|
|
|
0f9f97 |
|
|
|
0f9f97 |
addr = st.st_size
|
|
|
0f9f97 |
? mmap(0,st.st_size,mprot,MAP_SHARED,fd,0)
|
|
|
0f9f97 |
: 0;
|
|
|
0f9f97 |
|
|
|
0f9f97 |
if (addr == MAP_FAILED) {
|
|
|
0f9f97 |
close(fd);
|
|
|
0f9f97 |
return 0;
|
|
|
0f9f97 |
}
|
|
|
0f9f97 |
|
|
|
0f9f97 |
if (!(mapinfo = malloc(sizeof(*mapinfo)))) {
|
|
|
0f9f97 |
close(fd);
|
|
|
0f9f97 |
slbt_munmap(addr,st.st_size);
|
|
|
0f9f97 |
return 0;
|
|
|
0f9f97 |
}
|
|
|
0f9f97 |
|
|
|
0f9f97 |
close(fd);
|
|
|
0f9f97 |
|
|
|
0f9f97 |
mapinfo->addr = addr;
|
|
|
0f9f97 |
mapinfo->size = st.st_size;
|
|
|
0f9f97 |
|
|
|
0f9f97 |
return mapinfo;
|
|
|
0f9f97 |
}
|
|
|
0f9f97 |
|
|
|
0f9f97 |
void slbt_unmap_file(struct slbt_map_info * mapinfo)
|
|
|
0f9f97 |
{
|
|
|
0f9f97 |
slbt_munmap(mapinfo->addr,mapinfo->size);
|
|
|
0f9f97 |
free(mapinfo);
|
|
|
0f9f97 |
}
|