1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
/* Distilled from issue found with tar and symlinks.
* Make sure that the whole stat struct between runs
* is agreeable.
*/
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <time.h>
void show_stat(struct stat *st)
{
printf(
"------------------\n"
"st_dev = %li\n"
"st_ino = %li\n"
"st_mode = %li\n"
"st_nlink = %li\n"
"st_uid = %li\n"
"st_gid = %li\n"
"st_rdev = %li\n"
"st_size = %li\n"
"st_blksize = %li\n"
"st_blocks = %li\n"
"st_atime = %li\n"
"st_ansec = %li\n"
"st_mtime = %li\n"
"st_mnsec = %li\n"
"st_ctime = %li\n"
"st_cnsec = %li\n",
(long int)st->st_dev,
(long int)st->st_ino,
(long int)st->st_mode,
(long int)st->st_nlink,
(long int)st->st_uid,
(long int)st->st_gid,
(long int)st->st_rdev,
(long int)st->st_size,
(long int)st->st_blksize,
(long int)st->st_blocks,
#ifndef __UCLIBC__
(long int)st->st_atime,
(long int)st->st_atim.tv_nsec,
(long int)st->st_mtime,
(long int)st->st_mtim.tv_nsec,
(long int)st->st_ctime,
(long int)st->st_ctim.tv_nsec
#else
(long int)st->st_atime,
(long int)st->st_atimensec,
(long int)st->st_mtime,
(long int)st->st_mtimensec,
(long int)st->st_ctime,
(long int)st->st_ctimensec
#endif
);
}
int main()
{
int ret;
int fd;
struct stat fst, st;
memset(&fst, 0xAA, sizeof(fst));
memset(&st, 0x55, sizeof(st));
unlink(".testfile");
fd = open(".testfile", O_WRONLY | O_CREAT | O_EXCL, 0);
if (fd < 0) {
perror("open(.testfile) failed");
return 1;
}
ret = fstat(fd, &fst);
if (ret != 0) {
perror("fstat(.testfile) failed");
return 1;
}
close(fd);
ret = stat(".testfile", &st);
if (ret != 0) {
perror("stat(.testfile) failed");
return 1;
}
ret = memcmp(&fst, &st, sizeof(fst));
if (ret != 0) {
printf("FAILED: memcmp() = %i\n", ret);
show_stat(&fst);
show_stat(&st);
}
unlink(".testfile");
return ret;
}
|