|
|
139ca7 |
/*******************************************************************/
|
|
|
139ca7 |
/* slibtool: a skinny libtool implementation, written in C */
|
|
|
139ca7 |
/* Copyright (C) 2016--2018 Z. Gilboa */
|
|
|
139ca7 |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
139ca7 |
/*******************************************************************/
|
|
|
139ca7 |
|
|
|
7c9e3a |
#ifndef _POSIX_C_SOURCE
|
|
|
7c9e3a |
#define _POSIX_C_SOURCE 200809L
|
|
|
7c9e3a |
#endif
|
|
|
7c9e3a |
|
|
|
0f9f97 |
#include <fcntl.h>
|
|
|
0f9f97 |
#include <errno.h>
|
|
|
0f9f97 |
#include <unistd.h>
|
|
|
0f9f97 |
#include <stdint.h>
|
|
|
0f9f97 |
#include <stdlib.h>
|
|
|
62ed2e |
#include <string.h>
|
|
|
0f9f97 |
#include <sys/mman.h>
|
|
|
0f9f97 |
#include <sys/stat.h>
|
|
|
62ed2e |
|
|
|
62ed2e |
#include "slibtool_errinfo_impl.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;
|
|
|
62ed2e |
mapinfo->mark = addr;
|
|
|
62ed2e |
mapinfo->cap = &mapinfo->mark[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 |
}
|
|
|
62ed2e |
|
|
|
62ed2e |
int slbt_mapped_readline(
|
|
|
62ed2e |
const struct slbt_driver_ctx * dctx,
|
|
|
62ed2e |
struct slbt_map_info * mapinfo,
|
|
|
62ed2e |
char * buf,
|
|
|
62ed2e |
size_t buflen)
|
|
|
62ed2e |
{
|
|
|
62ed2e |
const char * ch;
|
|
|
62ed2e |
const char * cap;
|
|
|
62ed2e |
const char * mark;
|
|
|
62ed2e |
const char * newline;
|
|
|
62ed2e |
size_t len;
|
|
|
62ed2e |
|
|
|
62ed2e |
mark = mapinfo->mark;
|
|
|
62ed2e |
cap = mapinfo->cap;
|
|
|
62ed2e |
|
|
|
62ed2e |
for (ch=mark, newline=0; ch
|
|
|
62ed2e |
if (*ch == '\n')
|
|
|
62ed2e |
newline = ch;
|
|
|
62ed2e |
|
|
|
62ed2e |
len = ch - mark;
|
|
|
62ed2e |
|
|
|
62ed2e |
if (newline && (buflen <= len))
|
|
|
62ed2e |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_FLOW_ERROR);
|
|
|
62ed2e |
|
|
|
62ed2e |
if (!newline)
|
|
|
62ed2e |
return SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_BAD_DATA);
|
|
|
62ed2e |
|
|
|
62ed2e |
memcpy(buf,mark,len);
|
|
|
62ed2e |
buf[len] = 0;
|
|
|
62ed2e |
|
|
|
62ed2e |
mapinfo->mark += len;
|
|
|
62ed2e |
|
|
|
62ed2e |
return 0;
|
|
|
62ed2e |
}
|