Make it compile on AIX.
[gnulib.git] / tests / test-stat-time.c
1 /* Test of <stat-time.h>.
2    Copyright (C) 2007 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 /* Written by James Youngman <jay@gnu.org>, 2007.  */
19
20 #include <config.h>
21
22 #include "stat-time.h"
23
24 #include <fcntl.h>
25 #include <signal.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30
31 #define ASSERT(condition) if (!(condition)) abort ()
32
33 enum { NFILES = 4 };
34
35 static void
36 cleanup (int sig)
37 {
38   /* Remove temporary files.  */
39   unlink ("t-stt-stamp1");
40   unlink ("t-stt-testfile");
41   unlink ("t-stt-stamp2");
42   unlink ("t-stt-renamed");
43   unlink ("t-stt-stamp3");
44
45   if (sig != 0)
46     _exit (1);
47 }
48
49 static int
50 open_file (const char *filename, int flags)
51 {
52   int fd = open (filename, flags | O_WRONLY, 0500);
53   if (fd >= 0)
54     {
55       close (fd);
56       return 1;
57     }
58   else
59     {
60       return 0;
61     }
62 }
63
64 static void
65 create_file (const char *filename)
66 {
67   ASSERT (open_file (filename, O_CREAT | O_EXCL));
68 }
69
70 static void
71 do_stat (const char *filename, struct stat *p)
72 {
73   ASSERT (stat (filename, p) == 0);
74 }
75
76 static void
77 prepare_test (struct stat *statinfo, struct timespec *modtimes)
78 {
79   int i;
80
81   create_file ("t-stt-stamp1");
82   sleep (2);
83   create_file ("t-stt-testfile");
84   sleep (2);
85   create_file ("t-stt-stamp2");
86   sleep (2);
87   ASSERT (rename ("t-stt-testfile", "t-stt-renamed") == 0);
88   sleep (2);
89   create_file ("t-stt-stamp3");
90
91   do_stat ("t-stt-stamp1",  &statinfo[0]);
92   do_stat ("t-stt-renamed", &statinfo[1]);
93   do_stat ("t-stt-stamp2",  &statinfo[2]);
94   do_stat ("t-stt-stamp3",  &statinfo[3]);
95
96   /* Now use our access functions. */
97   for (i = 0; i < NFILES; ++i)
98     {
99       modtimes[i] = get_stat_mtime (&statinfo[i]);
100     }
101 }
102
103 static void
104 test_mtime (const struct stat *statinfo, struct timespec *modtimes)
105 {
106   int i;
107
108   /* Use the struct stat fields directly. */
109   ASSERT (statinfo[0].st_mtime < statinfo[2].st_mtime); /* mtime(stamp1) < mtime(stamp2) */
110   ASSERT (statinfo[2].st_mtime < statinfo[3].st_mtime); /* mtime(stamp2) < mtime(stamp3) */
111   ASSERT (statinfo[2].st_mtime < statinfo[1].st_ctime); /* mtime(stamp2) < ctime(renamed) */
112
113   /* Now check the result of the access functions. */
114   ASSERT (modtimes[0].tv_sec < modtimes[2].tv_sec); /* mtime(stamp1) < mtime(stamp2) */
115   ASSERT (modtimes[2].tv_sec < modtimes[3].tv_sec); /* mtime(stamp2) < mtime(stamp3) */
116
117   /* verify equivalence */
118   for (i = 0; i < NFILES; ++i)
119     {
120       struct timespec ts;
121       ts = get_stat_mtime (&statinfo[i]);
122       ASSERT (ts.tv_sec == statinfo[i].st_mtime);
123     }
124
125   ASSERT (statinfo[2].st_mtime < statinfo[1].st_ctime); /* mtime(stamp2) < ctime(renamed) */
126 }
127
128 static void
129 test_birthtime (const struct stat *statinfo,
130                 const struct timespec *modtimes,
131                 struct timespec *birthtimes)
132 {
133   int i;
134
135   /* Collect the birth times.. */
136   for (i = 0; i < NFILES; ++i)
137     {
138       birthtimes[i] = get_stat_birthtime (&statinfo[i]);
139       if (birthtimes[i].tv_nsec < 0)
140         return;
141     }
142
143   ASSERT (modtimes[0].tv_sec < birthtimes[1].tv_sec); /* mtime(stamp1) < birthtime(renamed) */
144   ASSERT (birthtimes[1].tv_sec < modtimes[2].tv_sec); /* birthtime(renamed) < mtime(stamp2) */
145 }
146
147 int
148 main ()
149 {
150   struct stat statinfo[NFILES];
151   struct timespec modtimes[NFILES];
152   struct timespec birthtimes[NFILES];
153
154 #ifdef SIGHUP
155   signal (SIGHUP, cleanup);
156 #endif
157 #ifdef SIGINT
158   signal (SIGINT, cleanup);
159 #endif
160 #ifdef SIGQUIT
161   signal (SIGQUIT, cleanup);
162 #endif
163 #ifdef SIGTERM
164   signal (SIGTERM, cleanup);
165 #endif
166
167   prepare_test (statinfo, modtimes);
168   test_mtime (statinfo, modtimes);
169   test_birthtime (statinfo, modtimes, birthtimes);
170
171   cleanup (0);
172   return 0;
173 }