commit
cd5db67f23
@ -0,0 +1 @@
|
||||
obj/
|
@ -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}
|
@ -0,0 +1,26 @@
|
||||
#ifndef _MAP_H
|
||||
#define _MAP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#define restrict __restrict__
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
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 */
|
@ -0,0 +1,55 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <map.h>
|
||||
|
||||
static const char* _prog_name = "fcmp";
|
||||
|
||||
__attribute__((noreturn)) void usage()
|
||||
{
|
||||
fprintf(stderr, "usage: %s <file1> <file2>\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;
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
#define _GNU_SOURCE
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include<string.h>
|
||||
#include<unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include<sys/mman.h>
|
||||
#include<fcntl.h>
|
||||
|
||||
#define FILEMODE S_IRWXU | S_IRGRP | S_IROTH
|
||||
|
||||
#include <map.h>
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in new issue