From cd5db67f233f3e59da36d8a81d1c5e370fb85ef7 Mon Sep 17 00:00:00 2001 From: Avril Date: Sat, 21 Nov 2020 17:20:33 +0000 Subject: [PATCH] initial commit --- .gitignore | 1 + Makefile | 44 +++++++++++++++++++++++++++++++++++++++++ include/map.h | 26 ++++++++++++++++++++++++ src/main.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/map.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 181 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 include/map.h create mode 100644 src/main.c create mode 100644 src/map.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2416a67 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +obj/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..eae2261 --- /dev/null +++ b/Makefile @@ -0,0 +1,44 @@ +SRC = $(wildcard src/*.c) +INCLUDE=include + +PROJECT=fcmp + +OPT_FLAGS+= -fgraphite -fno-strict-aliasing + +RELEASE_CFLAGS?= -O3 -march=native -flto $(OPT_FLAGS) +RELEASE_LDFLAGS?= -O3 -flto + +DEBUG_CFLAGS?= -O0 -g +DEBUG_LDFLAGS?= -O0 + +CFLAGS+= -Wall -pedantic --std=gnu11 $(addprefix -I,$(INCLUDE)) +LDFLAGS+= + +OBJ = $(addprefix obj/,$(SRC:.c=.o)) + +.PHONY: release +release: | dirs $(PROJECT)-release + +.PHONY: debug +debug: | dirs $(PROJECT)-debug + +dirs: + @mkdir -p obj/src + +%.o: %.c + $(CC) -c $< $(CFLAGS) -o $@ $(LDFLAGS) + +$(PROJECT)-release: CFLAGS := $(RELEASE_CFLAGS) $(CFLAGS) +$(PROJECT)-release: LDFLAGS := $(RELEASE_LDFLAGS) $(LDFLAGS) +$(PROJECT)-release: $(OBJ) + $(CC) $^ $(CFLAGS) -o $@ $(LDFLAGS) + strip $@ + +$(PROJECT)-debug: CFLAGS := $(DEBUG_CFLAGS) $(CFLAGS) +$(PROJECT)-debug: LDFLAGS := $(DEBUG_LDFLAGS) $(LDFLAGS) +$(PROJECT)-debug: $(OBJ) + $(CC) $^ $(CFLAGS) -o $@ $(LDFLAGS) + +clean: + rm -rf obj + rm -f $(PROJECT)-{release,debug} diff --git a/include/map.h b/include/map.h new file mode 100644 index 0000000..7574cf2 --- /dev/null +++ b/include/map.h @@ -0,0 +1,26 @@ +#ifndef _MAP_H +#define _MAP_H + +#ifdef __cplusplus +extern "C" { +#define restrict __restrict__ +#endif + +#include + +typedef struct mmap { + int fd; + + void* ptr; + size_t len; +} mmap_t; + +int open_and_map(const char* file, mmap_t* restrict ptr); +int unmap_and_close(mmap_t map); + +#ifdef _cplusplus +} +#undef restrict +#endif + +#endif /* _MAP_H */ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..583ef16 --- /dev/null +++ b/src/main.c @@ -0,0 +1,55 @@ +#include +#include +#include + +#include + +static const char* _prog_name = "fcmp"; + +__attribute__((noreturn)) void usage() +{ + fprintf(stderr, "usage: %s \n", _prog_name); + exit(-1); +} + +__attribute__((always_inline)) static inline const void* die_if_null(const void* ptr) +{ + if (!ptr) usage(); + else return ptr; +} + +int main(int argc, char** argv) +{ + _prog_name = argv[0]; + + const char* f1 = die_if_null(argv[1]); + const char* f2 = die_if_null(argv[2]); + + mmap_t map1, map2; + if (!open_and_map(f1, &map1)) { + fprintf(stderr, "Failed to open or map %s\n", f1); + return -1; + } + if (!open_and_map(f2, &map2)) { + fprintf(stderr, "Failed to open or map %s\n", f2); + unmap_and_close(map1); + return -1; + } + + if (map1.len != map2.len) return 2; + + if (memcmp(map1.ptr, map2.ptr, map1.len) != 0) return 1; + + register int rval=0; + if(!unmap_and_close(map1)) { + fprintf(stderr, "Failed to unmap and close %s", f1); + rval=-1; + } + + if(!unmap_and_close(map2)) { + fprintf(stderr, "Failed to unmap and close %s", f2); + rval=-1; + } + + return rval; +} diff --git a/src/map.c b/src/map.c new file mode 100644 index 0000000..05d5f67 --- /dev/null +++ b/src/map.c @@ -0,0 +1,55 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#define FILEMODE S_IRWXU | S_IRGRP | S_IROTH + +#include + +int open_and_map(const char* file, mmap_t* restrict ptr) +{ + int fd; + struct stat st; + if ((fd = open(file, O_RDONLY, FILEMODE)) < 0) { + perror("Failed to open file"); + return 0; + } + + if (fstat(fd, &st) < 0) { + perror("Failed to stat file"); + close(fd); + return 0; + } + + register struct mmap map = { .fd = fd, .ptr = NULL, .len = st.st_size }; + + if ((map.ptr = mmap(NULL, map.len, PROT_READ, MAP_SHARED,fd, 0)) == MAP_FAILED) { + perror("mmam() failed"); + close(fd); + return 0; + } + + *ptr = map; + + return 1; +} + +int unmap_and_close(mmap_t map) +{ + if (munmap(map.ptr, map.len) < 0) { + perror("munmap() failed"); + return 0; + } + if (close(map.fd) <0) { + perror("Failed to close fd"); + return 0; + } + + return 1; +}