]> git.lizzy.rs Git - nothing.git/blob - src/system/file.c
Merge pull request #899 from RIscRIpt/898
[nothing.git] / src / system / file.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <errno.h>
4 #ifdef __linux__
5 #include <sys/stat.h>
6 #include <sys/types.h>
7 #elif defined(_WIN32)
8 #include <Windows.h>
9 #define WINDOWS_TICK 10000000
10 #define SEC_TO_UNIX_EPOCH 11644473600LL
11 #endif
12
13 #include "system/stacktrace.h"
14 #include "file.h"
15
16 int last_modified(const char *filepath, time_t *time)
17 {
18     trace_assert(filepath);
19     trace_assert(time);
20
21 #ifdef __linux__
22
23     struct stat attr;
24     if (stat(filepath, &attr) < 0) {
25         // errno is set by stat
26         return -1;
27     }
28     *time = attr.st_mtime;
29     return 0;
30
31 #elif defined(_WIN32)
32
33     // CreateFile opens file (see flag OPEN_EXISTING)
34     HANDLE hFile = CreateFile(
35         filepath,
36         GENERIC_READ,
37         FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
38         NULL,
39         OPEN_EXISTING,
40         0,
41         NULL
42     );
43     if (hFile == INVALID_HANDLE_VALUE) {
44         // TODO: convert GetLastError() to errno
45         // for now let's just assume that file was not found.
46         errno = ENOENT;
47         return -1;
48     }
49     FILETIME filetime = { 0 };
50     BOOL res = GetFileTime(hFile, NULL, NULL, &filetime);
51     CloseHandle(hFile);
52     if (!res) {
53         errno = EPERM;
54         return -1;
55     }
56     unsigned long long mod_time = filetime.dwHighDateTime;
57     mod_time <<= 32;
58     mod_time |= filetime.dwLowDateTime;
59     // Taken from https://stackoverflow.com/a/6161842/1901561
60     *time = mod_time / WINDOWS_TICK - SEC_TO_UNIX_EPOCH;
61     return 0;
62
63 #elif defined(__APPLE__)
64
65     // TODO: implement last_modified for Mac OS X
66     #warning last_modified is not implemented
67     return -1;
68
69 #else
70
71     #error Unsupported OS
72     return -1;
73
74 #endif
75 }