X-Git-Url: https://jxself.org/git/?p=carl9170fw.git;a=blobdiff_plain;f=config%2Fconfdata.c;fp=config%2Fconfdata.c;h=da208c47fcb844e3101382fdf38dcc9f773d24b8;hp=da98566ccc6a45e68f1be3b03e7383831a7eb1a0;hb=42306a155d227ba90624c190a28344d61d566f46;hpb=04d2c0bc4dc1b10c5824fa54ceee7ee3547ca880 diff --git a/config/confdata.c b/config/confdata.c index da98566..da208c4 100644 --- a/config/confdata.c +++ b/config/confdata.c @@ -3,6 +3,7 @@ * Copyright (C) 2002 Roman Zippel */ +#include #include #include #include @@ -36,6 +37,52 @@ static bool is_dir(const char *path) return S_ISDIR(st.st_mode); } +/* return true if the given two files are the same, false otherwise */ +static bool is_same(const char *file1, const char *file2) +{ + int fd1, fd2; + struct stat st1, st2; + void *map1, *map2; + bool ret = false; + + fd1 = open(file1, O_RDONLY); + if (fd1 < 0) + return ret; + + fd2 = open(file2, O_RDONLY); + if (fd2 < 0) + goto close1; + + ret = fstat(fd1, &st1); + if (ret) + goto close2; + ret = fstat(fd2, &st2); + if (ret) + goto close2; + + if (st1.st_size != st2.st_size) + goto close2; + + map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); + if (map1 == MAP_FAILED) + goto close2; + + map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); + if (map2 == MAP_FAILED) + goto close2; + + if (bcmp(map1, map2, st1.st_size)) + goto close2; + + ret = true; +close2: + close(fd2); +close1: + close(fd1); + + return ret; +} + /* * Create the parent directory of the given path. * @@ -934,6 +981,13 @@ next: fclose(out); if (*tmpname) { + if (is_same(name, tmpname)) { + conf_message("No change to %s", name); + unlink(tmpname); + sym_set_change_count(0); + return 0; + } + snprintf(oldname, sizeof(oldname), "%s.old", name); rename(name, oldname); if (rename(tmpname, name))