/*******************************************************************/ /* slibtool: a skinny libtool implementation, written in C */ /* Copyright (C) 2016--2018 Z. Gilboa */ /* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ /*******************************************************************/ #include #include #include #include #include #include #include #include #include "slibtool_errinfo_impl.h" #include "slibtool_mapfile_impl.h" static void slbt_munmap(void * addr, size_t size) { if (addr) { munmap(addr,size); } } struct slbt_map_info * slbt_map_file( int fdat, const char * path, uint32_t flags) { int fd; void * addr; struct stat st; uint32_t oflag; uint32_t mprot; struct slbt_map_info * mapinfo; if ((flags & SLBT_MAP_INPUT) && (flags & SLBT_MAP_OUTPUT)) { oflag = O_RDWR; mprot = PROT_READ|PROT_WRITE; } else if (flags & SLBT_MAP_INPUT) { oflag = O_RDONLY; mprot = PROT_READ; } else if (flags & SLBT_MAP_OUTPUT) { oflag = O_WRONLY; mprot = PROT_WRITE; } else { errno = EINVAL; return 0; } if ((fd = openat(fdat,path,oflag,0)) < 0) return 0; if (fstat(fd,&st) < 0) { close(fd); return 0; } addr = st.st_size ? mmap(0,st.st_size,mprot,MAP_SHARED,fd,0) : 0; if (addr == MAP_FAILED) { close(fd); return 0; } if (!(mapinfo = malloc(sizeof(*mapinfo)))) { close(fd); slbt_munmap(addr,st.st_size); return 0; } close(fd); mapinfo->addr = addr; mapinfo->size = st.st_size; mapinfo->mark = addr; mapinfo->cap = &mapinfo->mark[st.st_size]; return mapinfo; } void slbt_unmap_file(struct slbt_map_info * mapinfo) { slbt_munmap(mapinfo->addr,mapinfo->size); free(mapinfo); } int slbt_mapped_readline( const struct slbt_driver_ctx * dctx, struct slbt_map_info * mapinfo, char * buf, size_t buflen) { const char * ch; const char * cap; const char * mark; const char * newline; size_t len; mark = mapinfo->mark; cap = mapinfo->cap; for (ch=mark, newline=0; chmark += len; return 0; }