summaryrefslogtreecommitdiffstats
path: root/winpr/libwinpr/file/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'winpr/libwinpr/file/file.c')
-rw-r--r--winpr/libwinpr/file/file.c159
1 files changed, 85 insertions, 74 deletions
diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c
index 01328b8..a016beb 100644
--- a/winpr/libwinpr/file/file.c
+++ b/winpr/libwinpr/file/file.c
@@ -21,11 +21,7 @@
#include <winpr/config.h>
#include <winpr/debug.h>
-
-#if defined(__FreeBSD_kernel__) && defined(__GLIBC__)
-#define _GNU_SOURCE
-#define KFREEBSD
-#endif
+#include <winpr/assert.h>
#include <winpr/wtypes.h>
#include <winpr/crt.h>
@@ -100,14 +96,15 @@ static BOOL FileCloseHandle(HANDLE handle)
static BOOL FileSetEndOfFile(HANDLE hFile)
{
WINPR_FILE* pFile = (WINPR_FILE*)hFile;
- INT64 size = 0;
if (!hFile)
return FALSE;
- size = _ftelli64(pFile->fp);
+ const INT64 size = _ftelli64(pFile->fp);
+ if (size < 0)
+ return FALSE;
- if (ftruncate(fileno(pFile->fp), size) < 0)
+ if (ftruncate(fileno(pFile->fp), (off_t)size) < 0)
{
char ebuffer[256] = { 0 };
WLog_ERR(TAG, "ftruncate %s failed with %s [0x%08X]", pFile->lpFileName,
@@ -565,100 +562,114 @@ static UINT64 FileTimeToUS(const FILETIME* ft)
return tmp;
}
+#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L)
+static struct timespec filetimeToTimespec(const FILETIME* ftime)
+{
+ WINPR_ASSERT(ftime);
+ UINT64 tmp = FileTimeToUS(ftime);
+ struct timespec ts = { 0 };
+ ts.tv_sec = tmp / 1000000ULL;
+ ts.tv_nsec = (tmp % 1000000ULL) * 1000ULL;
+ return ts;
+}
+
static BOOL FileSetFileTime(HANDLE hFile, const FILETIME* lpCreationTime,
const FILETIME* lpLastAccessTime, const FILETIME* lpLastWriteTime)
{
- int rc = 0;
-#if defined(__APPLE__) || defined(ANDROID) || defined(__FreeBSD__) || defined(KFREEBSD)
- struct stat buf;
- /* OpenBSD, NetBSD and DragonflyBSD support POSIX futimens */
- struct timeval timevals[2];
-#else
- struct timespec times[2]; /* last access, last modification */
-#endif
+ struct timespec times[2] = { { UTIME_OMIT, UTIME_OMIT },
+ { UTIME_OMIT, UTIME_OMIT } }; /* last access, last modification */
WINPR_FILE* pFile = (WINPR_FILE*)hFile;
if (!hFile)
return FALSE;
-#if defined(__APPLE__) || defined(ANDROID) || defined(__FreeBSD__) || defined(KFREEBSD)
- rc = fstat(fileno(pFile->fp), &buf);
+ if (lpLastAccessTime)
+ times[0] = filetimeToTimespec(lpLastAccessTime);
- if (rc < 0)
+ if (lpLastWriteTime)
+ times[1] = filetimeToTimespec(lpLastWriteTime);
+
+ // TODO: Creation time can not be handled!
+ const int rc = futimens(fileno(pFile->fp), times);
+ if (rc != 0)
return FALSE;
-#endif
+ return TRUE;
+}
+#elif defined(__APPLE__) || defined(ANDROID) || defined(__FreeBSD__) || defined(KFREEBSD)
+static struct timeval filetimeToTimeval(const FILETIME* ftime)
+{
+ WINPR_ASSERT(ftime);
+ UINT64 tmp = FileTimeToUS(ftime);
+ struct timeval tv = { 0 };
+ tv.tv_sec = tmp / 1000000ULL;
+ tv.tv_usec = tmp % 1000000ULL;
+ return tv;
+}
- if (!lpLastAccessTime)
- {
+static struct timeval statToTimeval(const struct stat* sval)
+{
+ WINPR_ASSERT(sval);
+ struct timeval tv = { 0 };
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(KFREEBSD)
- timevals[0].tv_sec = buf.st_atime;
+ tv.tv_sec = sval->st_atime;
#ifdef _POSIX_SOURCE
- TIMESPEC_TO_TIMEVAL(&timevals[0], &buf.st_atim);
+ TIMESPEC_TO_TIMEVAL(&tv, &sval->st_atim);
#else
- TIMESPEC_TO_TIMEVAL(&timevals[0], &buf.st_atimespec);
+ TIMESPEC_TO_TIMEVAL(&tv, &sval->st_atimespec);
#endif
#elif defined(ANDROID)
- timevals[0].tv_sec = buf.st_atime;
- timevals[0].tv_usec = buf.st_atimensec / 1000UL;
-#else
- times[0].tv_sec = UTIME_OMIT;
- times[0].tv_nsec = UTIME_OMIT;
+ tv.tv_sec = sval->st_atime;
+ tv.tv_usec = sval->st_atimensec / 1000UL;
#endif
- }
- else
- {
- UINT64 tmp = FileTimeToUS(lpLastAccessTime);
-#if defined(ANDROID) || defined(__FreeBSD__) || defined(__APPLE__) || defined(KFREEBSD)
- timevals[0].tv_sec = tmp / 1000000ULL;
- timevals[0].tv_usec = tmp % 1000000ULL;
-#else
- times[0].tv_sec = tmp / 1000000ULL;
- times[0].tv_nsec = (tmp % 1000000ULL) * 1000ULL;
-#endif
- }
+ return tv;
+}
- if (!lpLastWriteTime)
- {
-#if defined(__FreeBSD__) || defined(__APPLE__) || defined(KFREEBSD)
- timevals[1].tv_sec = buf.st_mtime;
-#ifdef _POSIX_SOURCE
- TIMESPEC_TO_TIMEVAL(&timevals[1], &buf.st_mtim);
-#else
- TIMESPEC_TO_TIMEVAL(&timevals[1], &buf.st_mtimespec);
-#endif
-#elif defined(ANDROID)
- timevals[1].tv_sec = buf.st_mtime;
- timevals[1].tv_usec = buf.st_mtimensec / 1000UL;
-#else
- times[1].tv_sec = UTIME_OMIT;
- times[1].tv_nsec = UTIME_OMIT;
-#endif
- }
- else
+static BOOL FileSetFileTime(HANDLE hFile, const FILETIME* lpCreationTime,
+ const FILETIME* lpLastAccessTime, const FILETIME* lpLastWriteTime)
+{
+ struct stat buf = { 0 };
+ /* OpenBSD, NetBSD and DragonflyBSD support POSIX futimens */
+ WINPR_FILE* pFile = (WINPR_FILE*)hFile;
+
+ if (!hFile)
+ return FALSE;
+
+ const int rc = fstat(fileno(pFile->fp), &buf);
+ if (rc < 0)
+ return FALSE;
+
+ struct timeval timevals[2] = { statToTimeval(&buf), statToTimeval(&buf) };
+ if (lpLastAccessTime)
+ timevals[0] = filetimeToTimeval(lpLastAccessTime);
+
+ if (lpLastWriteTime)
+ timevals[1] = filetimeToTimeval(lpLastWriteTime);
+
+ // TODO: Creation time can not be handled!
{
- UINT64 tmp = FileTimeToUS(lpLastWriteTime);
-#if defined(ANDROID) || defined(__FreeBSD__) || defined(__APPLE__) || defined(KFREEBSD)
- timevals[1].tv_sec = tmp / 1000000ULL;
- timevals[1].tv_usec = tmp % 1000000ULL;
-#else
- times[1].tv_sec = tmp / 1000000ULL;
- times[1].tv_nsec = (tmp % 1000000ULL) * 1000ULL;
-#endif
+ const int rc = utimes(pFile->lpFileName, timevals);
+ if (rc != 0)
+ return FALSE;
}
- // TODO: Creation time can not be handled!
-#if defined(ANDROID) || defined(__FreeBSD__) || defined(__APPLE__) || defined(KFREEBSD)
- rc = utimes(pFile->lpFileName, timevals);
+ return TRUE;
+}
#else
- rc = futimens(fileno(pFile->fp), times);
-#endif
+static BOOL FileSetFileTime(HANDLE hFile, const FILETIME* lpCreationTime,
+ const FILETIME* lpLastAccessTime, const FILETIME* lpLastWriteTime)
+{
+ WINPR_FILE* pFile = (WINPR_FILE*)hFile;
- if (rc != 0)
+ if (!hFile)
return FALSE;
+ WLog_WARN(TAG, "TODO: Creation, Access and Write time can not be handled!");
+ WLog_WARN(TAG,
+ "TODO: Define _POSIX_C_SOURCE >= 200809L or implement a platform specific handler!");
return TRUE;
}
+#endif
static HANDLE_OPS fileOps = {
FileIsHandled,