Fold integer-gmp.git into ghc.git (re #8545)
[ghc.git] / utils / touchy / touchy.c
1 /*
2 * Simple 'touch' program for Windows
3 *
4 */
5 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_WIN32)
6 #error "Win32-only, the platform you're using is supposed to have 'touch' already."
7 #else
8 #include <stdio.h>
9 #include <sys/stat.h>
10 #include <sys/types.h>
11 #include <fcntl.h>
12 #include <errno.h>
13 #include <utime.h>
14 #include <windows.h>
15
16 /*
17 With Windows 7 in a virtual box VM on OS X, some very odd things happen
18 with dates and time stamps when SSHing into cygwin. e.g. here the
19 "Change" time is in the past:
20
21 $ date; touch foo; stat foo
22 Fri Dec 2 16:58:07 GMTST 2011
23 File: `foo'
24 Size: 0 Blocks: 0 IO Block: 65536 regular
25 empty file
26 Device: 540aba0bh/1409989131d Inode: 562949953592977 Links: 1
27 Access: (0644/-rw-r--r--) Uid: ( 1000/ ian) Gid: ( 513/ None)
28 Access: 2011-12-02 16:58:07.414457900 +0000
29 Modify: 2011-12-02 16:58:07.414457900 +0000
30 Change: 2011-12-02 16:58:03.495141800 +0000
31 Birth: 2011-12-02 16:57:57.731469900 +0000
32
33 And if we copy such a file, then the copy is older (as determined by the
34 "Modify" time) than the original:
35
36 $ date; touch foo; stat foo; cp foo bar; stat bar
37 Fri Dec 2 16:59:10 GMTST 2011
38 File: `foo'
39 Size: 0 Blocks: 0 IO Block: 65536 regular
40 empty file
41 Device: 540aba0bh/1409989131d Inode: 1407374883725128 Links: 1
42 Access: (0644/-rw-r--r--) Uid: ( 1000/ ian) Gid: ( 513/ None)
43 Access: 2011-12-02 16:59:10.118457900 +0000
44 Modify: 2011-12-02 16:59:10.118457900 +0000
45 Change: 2011-12-02 16:59:06.189477700 +0000
46 Birth: 2011-12-02 16:57:57.731469900 +0000
47 File: `bar'
48 Size: 0 Blocks: 0 IO Block: 65536 regular
49 empty file
50 Device: 540aba0bh/1409989131d Inode: 281474976882512 Links: 1
51 Access: (0644/-rw-r--r--) Uid: ( 1000/ ian) Gid: ( 513/ None)
52 Access: 2011-12-02 16:59:06.394555800 +0000
53 Modify: 2011-12-02 16:59:06.394555800 +0000
54 Change: 2011-12-02 16:59:06.395532400 +0000
55 Birth: 2011-12-02 16:58:40.921899600 +0000
56
57 This means that make thinks that things are out of date when it
58 shouldn't, so reinvokes itself repeatedly until the MAKE_RESTARTS
59 infinite-recursion test triggers.
60
61 The touchy program, like most other programs, creates files with both
62 Modify and Change in the past, which is still a little odd, but is
63 consistent, so doesn't break make.
64
65 We used to use _utime(argv[i],NULL)) to set the file modification times,
66 but after a BST -> GMT change this started giving files a modification
67 time an hour in the future:
68
69 $ date; utils/touchy/dist/build/tmp/touchy testfile; stat testfile
70 Tue, Oct 30, 2012 11:33:06 PM
71 File: `testfile'
72 Size: 0 Blocks: 0 IO Block: 65536 regular empty file
73 Device: 540aba0bh/1409989131d Inode: 9851624184986293 Links: 1
74 Access: (0755/-rwxr-xr-x) Uid: ( 1000/ ian) Gid: ( 513/ None)
75 Access: 2012-10-31 00:33:06.000000000 +0000
76 Modify: 2012-10-31 00:33:06.000000000 +0000
77 Change: 2012-10-30 23:33:06.769118900 +0000
78 Birth: 2012-10-30 23:33:06.769118900 +0000
79
80 so now we use the Win32 functions GetSystemTimeAsFileTime and SetFileTime.
81 */
82
83 int
84 main(int argc, char** argv)
85 {
86 int i;
87 FILETIME ft;
88 BOOL b;
89 HANDLE hFile;
90
91 if (argc == 1) {
92 fprintf(stderr, "Usage: %s <files>\n", argv[0]);
93 return 1;
94 }
95
96 for (i = 1; i < argc; i++) {
97 hFile = CreateFile(argv[i], GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
98 FILE_ATTRIBUTE_NORMAL, NULL);
99 if (hFile == INVALID_HANDLE_VALUE) {
100 fprintf(stderr, "Unable to open %s\n", argv[i]);
101 exit(1);
102 }
103 GetSystemTimeAsFileTime(&ft);
104 b = SetFileTime(hFile, (LPFILETIME) NULL, (LPFILETIME) NULL, &ft);
105 if (b == 0) {
106 fprintf(stderr, "Unable to change mod. time for %s\n", argv[i]);
107 exit(1);
108 }
109 b = CloseHandle(hFile);
110 if (b == 0) {
111 fprintf(stderr, "Closing failed for %s\n", argv[i]);
112 exit(1);
113 }
114 }
115
116 return 0;
117 }
118 #endif