diff options
author | yxliang01 <13267.okk@gmail.com> | 2018-04-29 05:51:35 -0700 |
---|---|---|
committer | MartinNowack <martin.nowack@gmail.com> | 2018-05-07 10:04:53 +0100 |
commit | fcffe19529007d065b0b729d12c7941f7a4112c6 (patch) | |
tree | e7b22615b6d8be1d6d727321627c36cb701343b1 | |
parent | 6a7b21b8f84035c262c2bc566a3dc35d44517d33 (diff) | |
download | klee-fcffe19529007d065b0b729d12c7941f7a4112c6.tar.gz |
Fixed utimes() behavior for symbolic files when the second argument is NULL
-rw-r--r-- | runtime/POSIX/fd.c | 9 | ||||
-rw-r--r-- | test/Runtime/POSIX/FileTime.c | 47 |
2 files changed, 56 insertions, 0 deletions
diff --git a/runtime/POSIX/fd.c b/runtime/POSIX/fd.c index e0e87604..84d0bdc5 100644 --- a/runtime/POSIX/fd.c +++ b/runtime/POSIX/fd.c @@ -28,6 +28,7 @@ #include <termios.h> #include <sys/select.h> #include <klee/klee.h> +#include <sys/time.h> /* Returns pointer to the symbolic file structure fs the pathname is symbolic */ static exe_disk_file_t *__get_sym_file(const char *pathname) { @@ -246,6 +247,14 @@ int utimes(const char *path, const struct timeval times[2]) { exe_disk_file_t *dfile = __get_sym_file(path); if (dfile) { + + if (!times) { + struct timeval newTimes[2]; + gettimeofday(&(newTimes[0]), NULL); + newTimes[1] = newTimes[0]; + times = newTimes; + } + /* don't bother with usecs */ dfile->stat->st_atime = times[0].tv_sec; dfile->stat->st_mtime = times[1].tv_sec; diff --git a/test/Runtime/POSIX/FileTime.c b/test/Runtime/POSIX/FileTime.c new file mode 100644 index 00000000..bf669e36 --- /dev/null +++ b/test/Runtime/POSIX/FileTime.c @@ -0,0 +1,47 @@ +// This tests the functionality of setting and getting file access time and modification time +// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc +// RUN: rm -rf %t.klee-out +// RUN: %klee --output-dir=%t.klee-out --libc=uclibc --posix-runtime %t1.bc --sym-files 0 0 --max-fail 1 + +#include <stdio.h> +#include <assert.h> +#include <sys/stat.h> +#include <sys/time.h> + +const char filePath[] = "Some-File"; + +int main(int argc, char** argv) { + + // Create the file + FILE* const f = fopen(filePath, "w"); + assert(f); + const int r = fclose(f); + assert(r == 0); + + struct timeval now; + gettimeofday(&now, NULL); + + struct timeval times[2] = {now}; + times[1].tv_sec += 100; // Introduce difference between access time and modification time + utimes(filePath, times); + + struct stat sb; + stat(filePath, &sb); + + assert(sb.st_atim.tv_sec == times[0].tv_sec); + assert(sb.st_mtim.tv_sec == times[1].tv_sec); + + gettimeofday(&now, NULL); + // Test with setting access time and modification time to current time + utimes(filePath, NULL); + + struct timeval someTimeAfter; + gettimeofday(&someTimeAfter, NULL); + + stat(filePath, &sb); + + assert(sb.st_atim.tv_sec >= now.tv_sec && sb.st_atim.tv_sec <= someTimeAfter.tv_sec); + assert(sb.st_mtim.tv_sec >= now.tv_sec && sb.st_mtim.tv_sec <= someTimeAfter.tv_sec); + + return 0; +} |