Provide futimens(), utimensat() missing on FreeBSD
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef _HAIKU_BUILD_COMPATIBILITY_FREEBSD_SYS_STAT
|
||||||
|
#define _HAIKU_BUILD_COMPATIBILITY_FREEBSD_SYS_STAT
|
||||||
|
|
||||||
|
#include_next <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTIME_NOW
|
||||||
|
# define UTIME_NOW (-1)
|
||||||
|
# define UTIME_OMIT (-2)
|
||||||
|
|
||||||
|
/* assume that futimens() and utimensat() aren't available */
|
||||||
|
int futimens(int fd, const struct timespec times[2]);
|
||||||
|
int utimensat(int fd, const char* path, const struct timespec times[2],
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
# ifndef _HAIKU_BUILD_NO_FUTIMENS
|
||||||
|
# define _HAIKU_BUILD_NO_FUTIMENS 1
|
||||||
|
# endif
|
||||||
|
# ifndef _HAIKU_BUILD_NO_UTIMENSAT
|
||||||
|
# define _HAIKU_BUILD_NO_UTIMENSAT 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _HAIKU_BUILD_COMPATIBILITY_FREEBSD_SYS_STAT */
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008, Samuel Rodriguez Perez, [email protected].
|
* Copyright 2008, Samuel Rodriguez Perez, [email protected].
|
||||||
|
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -7,12 +8,13 @@
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/disk.h>
|
#include <sys/disk.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -252,3 +254,127 @@ haiku_freebsd_writev(int fd, const struct iovec *vecs, size_t count)
|
|||||||
|
|
||||||
return bytesWritten;
|
return bytesWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_HAIKU_BUILD_NO_FUTIMENS) || defined(_HAIKU_BUILD_NO_FUTIMENS)
|
||||||
|
|
||||||
|
template<typename File>
|
||||||
|
static int
|
||||||
|
utimes_helper(File& file, const struct timespec times[2])
|
||||||
|
{
|
||||||
|
if (times == NULL)
|
||||||
|
return file.SetTimes(NULL);
|
||||||
|
|
||||||
|
timeval timeBuffer[2];
|
||||||
|
timeBuffer[0].tv_sec = times[0].tv_sec;
|
||||||
|
timeBuffer[0].tv_usec = times[0].tv_nsec / 1000;
|
||||||
|
timeBuffer[1].tv_sec = times[1].tv_sec;
|
||||||
|
timeBuffer[1].tv_usec = times[1].tv_nsec / 1000;
|
||||||
|
|
||||||
|
if (times[0].tv_nsec == UTIME_OMIT || times[1].tv_nsec == UTIME_OMIT) {
|
||||||
|
struct stat st;
|
||||||
|
if (file.GetStat(st) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (times[0].tv_nsec == UTIME_OMIT) {
|
||||||
|
timeBuffer[0].tv_sec = st.st_atimespec.tv_sec;
|
||||||
|
timeBuffer[0].tv_usec = st.st_atimespec.tv_nsec / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (times[1].tv_nsec == UTIME_OMIT) {
|
||||||
|
timeBuffer[1].tv_sec = st.st_mtimespec.tv_sec;
|
||||||
|
timeBuffer[1].tv_usec = st.st_mtimespec.tv_nsec / 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW) {
|
||||||
|
timeval now;
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
|
||||||
|
if (times[0].tv_nsec == UTIME_NOW)
|
||||||
|
timeBuffer[0] = now;
|
||||||
|
|
||||||
|
if (times[1].tv_nsec == UTIME_NOW)
|
||||||
|
timeBuffer[1] = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
return file.SetTimes(timeBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _HAIKU_BUILD_NO_FUTIMENS || _HAIKU_BUILD_NO_FUTIMENS
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _HAIKU_BUILD_NO_FUTIMENS
|
||||||
|
|
||||||
|
struct FDFile {
|
||||||
|
FDFile(int fd)
|
||||||
|
:
|
||||||
|
fFD(fd)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetStat(struct stat& _st)
|
||||||
|
{
|
||||||
|
return fstat(fFD, &_st);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SetTimes(const timeval times[2])
|
||||||
|
{
|
||||||
|
return futimes(fFD, times);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int fFD;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
futimens(int fd, const struct timespec times[2])
|
||||||
|
{
|
||||||
|
FDFile file(fd);
|
||||||
|
return utimes_helper(file, times);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _HAIKU_BUILD_NO_FUTIMENS
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _HAIKU_BUILD_NO_UTIMENSAT
|
||||||
|
|
||||||
|
struct FDPathFile {
|
||||||
|
FDPathFile(int fd, const char* path, int flag)
|
||||||
|
:
|
||||||
|
fFD(fd),
|
||||||
|
fPath(path),
|
||||||
|
fFlag(flag)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetStat(struct stat& _st)
|
||||||
|
{
|
||||||
|
return fstatat(fFD, fPath, &_st, fFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SetTimes(const timeval times[2])
|
||||||
|
{
|
||||||
|
// TODO: fFlag (AT_SYMLINK_NOFOLLOW) is not supported here!
|
||||||
|
return futimesat(fFD, fPath, times);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int fFD;
|
||||||
|
const char* fPath;
|
||||||
|
int fFlag;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
utimensat(int fd, const char* path, const struct timespec times[2], int flag)
|
||||||
|
{
|
||||||
|
FDPathFile file(fd, path, flag);
|
||||||
|
return utimes_helper(file, times);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _HAIKU_BUILD_NO_UTIMENSAT
|
||||||
|
|||||||
Reference in New Issue
Block a user