parent
140b7c97a6
commit
6decefdc5b
@ -0,0 +1,152 @@
|
||||
//! -pipe -std=gnu17 -O3 -msse -fwhole-program -flto -fno-strict-aliasing -Wall -Wstrict-aliasing -Werror -Wl,-flto -Wl,-O3 -o
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define expect(expr, msg) ({ __auto_type _expect__expr = (expr); \
|
||||
if(__builtin_expect(!_expect__expr, 0)) { perror("Fatal error: `" #expr "` failed: " msg); exit(1); } \
|
||||
_expect__expr; })
|
||||
|
||||
union openfd {
|
||||
struct {
|
||||
off_t len;
|
||||
FILE* file;
|
||||
} buf;
|
||||
struct {
|
||||
off_t len;
|
||||
int fd;
|
||||
} raw;
|
||||
};
|
||||
|
||||
typedef struct mappedfd {
|
||||
int fd;
|
||||
size_t len;
|
||||
|
||||
uintptr_t origin;
|
||||
} mmap_t;
|
||||
|
||||
inline static void* map_ptr(const mmap_t* map)
|
||||
{
|
||||
return (void*)map->origin;
|
||||
}
|
||||
|
||||
bool filesz(int fd, off_t* restrict size)
|
||||
{
|
||||
if(fd<0) return false;
|
||||
struct stat st;
|
||||
if(fstat(fd, &st)) return false;
|
||||
*size = st.st_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bopen(const char* name, const char* perm, union openfd* restrict file)
|
||||
{
|
||||
FILE* f = fopen(name, perm);
|
||||
if(!f) return false;
|
||||
if(!filesz(fileno(f), &file->buf.len)) return (fclose(f), false);
|
||||
file->buf.file = f;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ropen(const char* name, int perm, union openfd* restrict file)
|
||||
{
|
||||
int fd = open(name, perm, 0);
|
||||
if(fd<0) return false;
|
||||
if(!filesz(fd, &file->raw.len)) return (close(fd), false);
|
||||
file->raw.fd = fd;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool btor(union openfd* restrict file)
|
||||
{
|
||||
if(fflush(file->buf.file)) return false;
|
||||
int fd = fileno(file->buf.file);
|
||||
|
||||
file->raw.len = file->buf.len;
|
||||
file->raw.fd = fd;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool rclose(union openfd file)
|
||||
{
|
||||
return close(file.raw.fd) != 0;
|
||||
}
|
||||
|
||||
inline void bclose(union openfd file)
|
||||
{
|
||||
fclose(file.buf.file);
|
||||
}
|
||||
|
||||
bool map_raw(union openfd* restrict file, mmap_t* restrict map)
|
||||
{
|
||||
void* origin = mmap(NULL, (size_t)file->raw.len, PROT_READ, MAP_SHARED, file->raw.fd, 0);
|
||||
if(origin == MAP_FAILED) return false;
|
||||
*map = (mmap_t){
|
||||
.fd = file->raw.fd,
|
||||
.len = (size_t)file->raw.len,
|
||||
.origin = (uintptr_t)origin,
|
||||
};
|
||||
file->raw.fd = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool map_clone(const mmap_t* from, mmap_t* restrict to)
|
||||
{
|
||||
void* origin = mmap((void*)from->origin, from->len, PROT_READ|PROT_WRITE, MAP_PRIVATE, from->fd, 0);
|
||||
if(origin == MAP_FAILED) return false;
|
||||
*to = (mmap_t){
|
||||
.fd = -1,
|
||||
.len = from->len,
|
||||
.origin = (uintptr_t)origin,
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
void map_close(mmap_t map)
|
||||
{
|
||||
munmap((void*)map.origin, map.len);
|
||||
if(map.fd >= 0) close(map.fd);
|
||||
}
|
||||
|
||||
inline bool map_buf(union openfd* restrict file, mmap_t* restrict map)
|
||||
{
|
||||
if(!btor(file)) return false;
|
||||
return map_raw(file, map);
|
||||
}
|
||||
|
||||
bool process(const mmap_t* io)
|
||||
{
|
||||
char* input = map_ptr(io);
|
||||
size_t size = io->len;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if(argc < 1) return 1;
|
||||
int rc = 0;
|
||||
|
||||
union openfd input;
|
||||
expect(ropen(argv[1], O_RDONLY, &input), "couldn't open input file");
|
||||
|
||||
mmap_t read;
|
||||
expect(map_raw(&input, &read), "failed to map file");
|
||||
mmap_t write;
|
||||
expect(map_clone(&read, &write), "failed to clone page");
|
||||
|
||||
if(!process(&write)) rc = (perror("failed to process"), 1);
|
||||
|
||||
map_close(write);
|
||||
map_close(read);
|
||||
return rc;
|
||||
}
|
||||
|
Loading…
Reference in new issue