diff --git a/day3/mkinput b/day3/mkinput-old similarity index 100% rename from day3/mkinput rename to day3/mkinput-old diff --git a/day3/mkinput.c b/day3/mkinput.c new file mode 100644 index 0000000..260d186 --- /dev/null +++ b/day3/mkinput.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} +