Support --crtimes on Cygwin.

This commit is contained in:
Wayne Davison
2021-07-08 18:47:21 -07:00
parent 9dad3721a9
commit 291a042b3e
7 changed files with 43 additions and 11 deletions

View File

@@ -50,7 +50,7 @@ popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
popt/popthelp.o popt/poptparse.o
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) @SIMD@ $(DAEMON_OBJ) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@
TLS_OBJ = tls.o syscall.o t_stub.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@
TLS_OBJ = tls.o syscall.o util2.o t_stub.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@
# Programs we must have to run the test cases
CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) getfsdev$(EXEEXT) \
@@ -155,7 +155,7 @@ getgroups$(EXEEXT): getgroups.o
getfsdev$(EXEEXT): getfsdev.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ getfsdev.o $(LIBS)
TRIMSLASH_OBJ = trimslash.o syscall.o t_stub.o lib/compat.o lib/snprintf.o
TRIMSLASH_OBJ = trimslash.o syscall.o util2.o t_stub.o lib/compat.o lib/snprintf.o
trimslash$(EXEEXT): $(TRIMSLASH_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TRIMSLASH_OBJ) $(LIBS)

View File

@@ -1438,7 +1438,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
F_ATIME(file) = st.st_atime;
#ifdef SUPPORT_CRTIMES
if (crtimes_ndx)
F_CRTIME(file) = get_create_time(fname);
F_CRTIME(file) = get_create_time(fname, &st);
#endif
if (basename != thisname)

View File

@@ -399,7 +399,7 @@ static inline int any_time_differs(stat_x *sxp, struct file_struct *file, UNUSED
#ifdef SUPPORT_CRTIMES
if (!differs && crtimes_ndx) {
if (sxp->crtime == 0)
sxp->crtime = get_create_time(fname);
sxp->crtime = get_create_time(fname, &sxp->st);
differs = !same_time(sxp->crtime, 0, F_CRTIME(file), 0);
}
#endif
@@ -525,7 +525,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
#ifdef SUPPORT_CRTIMES
if (crtimes_ndx) {
if (sxp->crtime == 0)
sxp->crtime = get_create_time(fnamecmp);
sxp->crtime = get_create_time(fnamecmp, &sxp->st);
if (!same_time(sxp->crtime, 0, F_CRTIME(file), 0))
iflags |= ITEM_REPORT_CRTIME;
}

View File

@@ -620,7 +620,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
if (crtimes_ndx && !(flags & ATTRS_SKIP_CRTIME)) {
time_t file_crtime = F_CRTIME(file);
if (sxp->crtime == 0)
sxp->crtime = get_create_time(fname);
sxp->crtime = get_create_time(fname, &sxp->st);
if (!same_time(sxp->crtime, 0L, file_crtime, 0L)
&& set_create_time(fname, file_crtime) == 0)
updated = 1;

View File

@@ -587,7 +587,7 @@ typedef unsigned int size_t;
#define SUPPORT_ATIMES 1
#endif
#ifdef HAVE_GETATTRLIST
#if defined HAVE_GETATTRLIST || defined __CYGWIN__
#define SUPPORT_CRTIMES 1
#endif

View File

@@ -55,12 +55,16 @@ extern int open_noatime;
#endif
#ifdef SUPPORT_CRTIMES
#ifdef HAVE_GETATTRLIST
#pragma pack(push, 4)
struct create_time {
uint32 length;
struct timespec crtime;
};
#pragma pack(pop)
#elif defined __CYGWIN__
#include <windows.h>
#endif
#endif
#define RETURN_ERROR_IF(x,e) \
@@ -407,23 +411,30 @@ int do_setattrlist_times(const char *fname, STRUCT_STAT *stp)
#endif
#ifdef SUPPORT_CRTIMES
time_t get_create_time(const char *path)
time_t get_create_time(const char *path, STRUCT_STAT *stp)
{
#ifdef HAVE_GETATTRLIST
static struct create_time attrBuf;
struct attrlist attrList;
(void)stp;
memset(&attrList, 0, sizeof attrList);
attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
attrList.commonattr = ATTR_CMN_CRTIME;
if (getattrlist(path, &attrList, &attrBuf, sizeof attrBuf, FSOPT_NOFOLLOW) < 0)
return 0;
return attrBuf.crtime.tv_sec;
}
#elif defined __CYGWIN__
(void)path;
return stp->st_birthtime;
#else
#error Unknown crtimes implementation
#endif
}
#ifdef SUPPORT_CRTIMES
int set_create_time(const char *path, time_t crtime)
{
#ifdef HAVE_GETATTRLIST
struct attrlist attrList;
struct timespec ts;
@@ -437,6 +448,27 @@ int set_create_time(const char *path, time_t crtime)
attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
attrList.commonattr = ATTR_CMN_CRTIME;
return setattrlist(path, &attrList, &ts, sizeof ts, FSOPT_NOFOLLOW);
#elif defined __CYGWIN__
int cnt = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
if (cnt == 0)
return -1;
WCHAR *pathw = new_array(WCHAR, cnt);
if (!pathw)
return -1;
MultiByteToWideChar(CP_UTF8, 0, path, -1, pathw, cnt);
HANDLE handle = CreateFileW(pathw, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
free(pathw);
if (handle == INVALID_HANDLE_VALUE)
return -1;
int64 temp_time = Int32x32To64(crtime, 10000000) + 116444736000000000LL;
FILETIME birth_time;
birth_time.dwLowDateTime = (DWORD)temp_time;
birth_time.dwHighDateTime = (DWORD)(temp_time >> 32);
int ok = SetFileTime(handle, &birth_time, NULL, NULL);
CloseHandle(handle);
return ok ? 0 : -1;
#endif
}
#endif

2
tls.c
View File

@@ -160,7 +160,7 @@ static void list_file(const char *fname)
if (do_lstat(fname, &buf) < 0)
failed("stat", fname);
#ifdef SUPPORT_CRTIMES
if (display_crtimes && (crtime = get_create_time(fname)) == 0)
if (display_crtimes && (crtime = get_create_time(fname, &buf)) == 0)
failed("get_create_time", fname);
#endif
#ifdef SUPPORT_XATTRS