X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/42562649917058c3aff682741854ac12ffe72d20..813d5a25e307bf86169ac6f30b120c02ff116667:/syscall.c diff --git a/syscall.c b/syscall.c index aba0009d..1ed36f3c 100644 --- a/syscall.c +++ b/syscall.c @@ -29,6 +29,10 @@ #include #endif +#if defined HAVE_SYS_FALLOCATE && !defined HAVE_FALLOCATE +#include +#endif + extern int dry_run; extern int am_root; extern int am_sender; @@ -226,6 +230,22 @@ int do_rename(const char *fname1, const char *fname2) return rename(fname1, fname2); } +#ifdef HAVE_FTRUNCATE +int do_ftruncate(int fd, OFF_T size) +{ + int ret; + + if (dry_run) return 0; + RETURN_ERROR_IF_RO_OR_LO; + + do { + ret = ftruncate(fd, size); + } while (ret < 0 && errno == EINTR); + + return ret; +} +#endif + void trim_trailing_slashes(char *name) { int l; @@ -327,3 +347,99 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence) return lseek(fd, offset, whence); #endif } + +#ifdef HAVE_UTIMENSAT +int do_utimensat(const char *fname, time_t modtime, uint32 mod_nsec) +{ + struct timespec t[2]; + + if (dry_run) return 0; + RETURN_ERROR_IF_RO_OR_LO; + + t[0].tv_sec = 0; + t[0].tv_nsec = UTIME_NOW; + t[1].tv_sec = modtime; + t[1].tv_nsec = mod_nsec; + return utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW); +} +#endif + +#ifdef HAVE_LUTIMES +int do_lutimes(const char *fname, time_t modtime, uint32 mod_nsec) +{ + struct timeval t[2]; + + if (dry_run) return 0; + RETURN_ERROR_IF_RO_OR_LO; + + t[0].tv_sec = time(NULL); + t[0].tv_usec = 0; + t[1].tv_sec = modtime; + t[1].tv_usec = mod_nsec / 1000; + return lutimes(fname, t); +} +#endif + +#ifdef HAVE_UTIMES +int do_utimes(const char *fname, time_t modtime, uint32 mod_nsec) +{ + struct timeval t[2]; + + if (dry_run) return 0; + RETURN_ERROR_IF_RO_OR_LO; + + t[0].tv_sec = time(NULL); + t[0].tv_usec = 0; + t[1].tv_sec = modtime; + t[1].tv_usec = mod_nsec / 1000; + return utimes(fname, t); +} + +#elif defined HAVE_UTIME +int do_utime(const char *fname, time_t modtime, UNUSED(uint32 mod_nsec)) +{ +#ifdef HAVE_STRUCT_UTIMBUF + struct utimbuf tbuf; +#else + time_t t[2]; +#endif + + if (dry_run) return 0; + RETURN_ERROR_IF_RO_OR_LO; + +# ifdef HAVE_STRUCT_UTIMBUF + tbuf.actime = time(NULL); + tbuf.modtime = modtime; + return utime(fname, &tbuf); +# else + t[0] = time(NULL); + t[1] = modtime; + return utime(fname, t); +# endif +} + +#else +#error Need utimes or utime function. +#endif + +#ifdef SUPPORT_PREALLOCATION +int do_fallocate(int fd, OFF_T offset, OFF_T length) +{ +#ifdef FALLOC_FL_KEEP_SIZE +#define DO_FALLOC_OPTIONS FALLOC_FL_KEEP_SIZE +#else +#define DO_FALLOC_OPTIONS 0 +#endif + RETURN_ERROR_IF(dry_run, 0); + RETURN_ERROR_IF_RO_OR_LO; +#if defined HAVE_FALLOCATE + return fallocate(fd, DO_FALLOC_OPTIONS, offset, length); +#elif defined HAVE_SYS_FALLOCATE + return syscall(SYS_fallocate, fd, DO_FALLOC_OPTIONS, (loff_t)offset, (loff_t)length); +#elif defined HAVE_EFFICIENT_POSIX_FALLOCATE + return posix_fallocate(fd, offset, length); +#else +#error Coding error in SUPPORT_PREALLOCATION logic. +#endif +} +#endif