1 #include "git-compat-util.h"
2 #include "environment.h"
5 void fill_stat_data(struct stat_data
*sd
, struct stat
*st
)
7 sd
->sd_ctime
.sec
= (unsigned int)st
->st_ctime
;
8 sd
->sd_mtime
.sec
= (unsigned int)st
->st_mtime
;
9 sd
->sd_ctime
.nsec
= ST_CTIME_NSEC(*st
);
10 sd
->sd_mtime
.nsec
= ST_MTIME_NSEC(*st
);
11 sd
->sd_dev
= st
->st_dev
;
12 sd
->sd_ino
= st
->st_ino
;
13 sd
->sd_uid
= st
->st_uid
;
14 sd
->sd_gid
= st
->st_gid
;
15 sd
->sd_size
= st
->st_size
;
18 int match_stat_data(const struct stat_data
*sd
, struct stat
*st
)
22 if (sd
->sd_mtime
.sec
!= (unsigned int)st
->st_mtime
)
23 changed
|= MTIME_CHANGED
;
24 if (trust_ctime
&& check_stat
&&
25 sd
->sd_ctime
.sec
!= (unsigned int)st
->st_ctime
)
26 changed
|= CTIME_CHANGED
;
29 if (check_stat
&& sd
->sd_mtime
.nsec
!= ST_MTIME_NSEC(*st
))
30 changed
|= MTIME_CHANGED
;
31 if (trust_ctime
&& check_stat
&&
32 sd
->sd_ctime
.nsec
!= ST_CTIME_NSEC(*st
))
33 changed
|= CTIME_CHANGED
;
37 if (sd
->sd_uid
!= (unsigned int) st
->st_uid
||
38 sd
->sd_gid
!= (unsigned int) st
->st_gid
)
39 changed
|= OWNER_CHANGED
;
40 if (sd
->sd_ino
!= (unsigned int) st
->st_ino
)
41 changed
|= INODE_CHANGED
;
46 * st_dev breaks on network filesystems where different
47 * clients will have different views of what "device"
48 * the filesystem is on
50 if (check_stat
&& sd
->sd_dev
!= (unsigned int) st
->st_dev
)
51 changed
|= INODE_CHANGED
;
54 if (sd
->sd_size
!= (unsigned int) st
->st_size
)
55 changed
|= DATA_CHANGED
;
60 void stat_validity_clear(struct stat_validity
*sv
)
62 FREE_AND_NULL(sv
->sd
);
65 int stat_validity_check(struct stat_validity
*sv
, const char *path
)
69 if (stat(path
, &st
) < 0)
70 return sv
->sd
== NULL
;
73 return S_ISREG(st
.st_mode
) && !match_stat_data(sv
->sd
, &st
);
76 void stat_validity_update(struct stat_validity
*sv
, int fd
)
80 if (fstat(fd
, &st
) < 0 || !S_ISREG(st
.st_mode
))
81 stat_validity_clear(sv
);
84 CALLOC_ARRAY(sv
->sd
, 1);
85 fill_stat_data(sv
->sd
, &st
);