Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -582,11 +582,11 @@ AC_DEFINE(OF_HAVE_ATOMIC_OPS, 1, [Whether we have atomic operations]) AC_SUBST(ATOMIC_H, "atomic.h") ]) AC_MSG_RESULT($atomic_ops) -AC_CHECK_FUNCS([sysconf gmtime_r localtime_r nanosleep]) +AC_CHECK_FUNCS([sysconf gmtime_r localtime_r nanosleep lstat]) AC_CHECK_HEADERS([pwd.h grp.h]) AC_CHECK_FUNC(chmod, [ AC_DEFINE(OF_HAVE_CHMOD, 1, [Whether we have chmod()]) ]) Index: src/OFFile.h ================================================================== --- src/OFFile.h +++ src/OFFile.h @@ -20,15 +20,22 @@ #ifndef __STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS #endif #include +#include #import "OFSeekableStream.h" @class OFArray; @class OFDate; + +#ifndef _WIN32 +typedef struct stat of_stat_t; +#else +typedef struct _stat of_stat_t; +#endif /*! * @brief A class which provides functions to read, write and manipulate files. */ @interface OFFile: OFSeekableStream @@ -285,5 +292,14 @@ * @param fd A file descriptor, returned from for example open(). * It is not closed when the OFFile object is deallocated! */ - initWithFileDescriptor: (int)fd; @end + +#ifdef __cplusplus +extern "C" { +#endif +extern int of_stat(OFString *path, of_stat_t *buffer); +extern int of_lstat(OFString *path, of_stat_t *buffer); +#ifdef __cplusplus +} +#endif Index: src/OFFile.m ================================================================== --- src/OFFile.m +++ src/OFFile.m @@ -28,12 +28,10 @@ #include #include #include -#include -#include #include #include #ifdef HAVE_PWD_H # include @@ -105,10 +103,35 @@ #define DIR_MODE DEFAULT_MODE | S_IXUSR | S_IXGRP | S_IXOTH #if defined(OF_HAVE_CHOWN) && defined(OF_HAVE_THREADS) static of_mutex_t mutex; #endif + +int +of_stat(OFString *path, of_stat_t *buffer) +{ +#ifdef _WIN32 + return _wstat([path UTF16String], buffer); +#else + return stat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + buffer); +#endif +} + +int +of_lstat(OFString *path, of_stat_t *buffer) +{ +#if defined(_WIN32) + return _wstat([path UTF16String], buffer); +#elif defined(HAVE_LSTAT) + return lstat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + buffer); +#else + return stat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + buffer); +#endif +} static int parseMode(const char *mode) { if (!strcmp(mode, "r")) @@ -194,49 +217,33 @@ return ret; } + (bool)fileExistsAtPath: (OFString*)path { + of_stat_t s; + if (path == nil) @throw [OFInvalidArgumentException exception]; -#ifndef _WIN32 - struct stat s; - - if (stat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], - &s) == -1) - return false; -#else - struct _stat s; - - if (_wstat([path UTF16String], &s) == -1) - return false; -#endif + if (of_stat(path, &s) == -1) + return false; if (S_ISREG(s.st_mode)) return true; return false; } + (bool)directoryExistsAtPath: (OFString*)path { + of_stat_t s; + if (path == nil) @throw [OFInvalidArgumentException exception]; -#ifndef _WIN32 - struct stat s; - - if (stat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], - &s) == -1) - return false; -#else - struct _stat s; - - if (_wstat([path UTF16String], &s) == -1) - return false; -#endif + if (of_stat(path, &s) == -1) + return false; if (S_ISDIR(s.st_mode)) return true; return false; @@ -243,17 +250,16 @@ } #ifdef OF_HAVE_SYMLINK + (bool)symbolicLinkExistsAtPath: (OFString*)path { - struct stat s; + of_stat_t s; if (path == nil) @throw [OFInvalidArgumentException exception]; - if (lstat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], - &s) == -1) + if (of_lstat(path, &s) == -1) return false; if (S_ISLNK(s.st_mode)) return true; @@ -408,46 +414,32 @@ exceptionWithPath: path]; } + (off_t)sizeOfFileAtPath: (OFString*)path { + of_stat_t s; + if (path == nil) @throw [OFInvalidArgumentException exception]; -#ifndef _WIN32 - struct stat s; - - if (stat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], - &s) == -1) -#else - struct _stat s; - - if (_wstat([path UTF16String], &s) == -1) -#endif + if (of_stat(path, &s) == -1) /* FIXME: Maybe use another exception? */ @throw [OFOpenFileFailedException exceptionWithPath: path mode: @"r"]; - /* On Android, off_t is 32 bit, but st_size is long long there */ + /* FIXME: On Android, off_t is 32 bit, but st_size is long long there */ return (off_t)s.st_size; } + (OFDate*)modificationDateOfFileAtPath: (OFString*)path { + of_stat_t s; + if (path == nil) @throw [OFInvalidArgumentException exception]; -#ifndef _WIN32 - struct stat s; - - if (stat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], - &s) == -1) -#else - struct _stat s; - - if (_wstat([path UTF16String], &s) == -1) -#endif + if (of_stat(path, &s) == -1) /* FIXME: Maybe use another exception? */ @throw [OFOpenFileFailedException exceptionWithPath: path mode: @"r"]; /* FIXME: We could be more precise on some OSes */ @@ -532,38 +524,25 @@ + (void)copyItemAtPath: (OFString*)source toPath: (OFString*)destination { void *pool; -#ifndef _WIN32 - struct stat s; -#else - struct _stat s; -#endif + of_stat_t s; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); -#ifndef _WIN32 - if (lstat([destination - cStringWithEncoding: OF_STRING_ENCODING_NATIVE], &s) == 0) { -#else - if (_wstat([destination UTF16String], &s) == 0) { -#endif + if (of_lstat(destination, &s) == 0) { errno = EEXIST; @throw [OFCopyItemFailedException exceptionWithSourcePath: source destinationPath: destination]; } -#ifndef _WIN32 - if (lstat([source cStringWithEncoding: OF_STRING_ENCODING_NATIVE], &s)) -#else - if (_wstat([source UTF16String], &s)) -#endif + if (of_lstat(source, &s)) @throw [OFCopyItemFailedException exceptionWithSourcePath: source destinationPath: destination]; if (S_ISDIR(s.st_mode)) { @@ -667,27 +646,18 @@ + (void)moveItemAtPath: (OFString*)source toPath: (OFString*)destination { void *pool; -#ifndef _WIN32 - struct stat s; -#else - struct _stat s; -#endif + of_stat_t s; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); -#ifndef _WIN32 - if (lstat([destination - cStringWithEncoding: OF_STRING_ENCODING_NATIVE], &s) == 0) { -#else - if (_wstat([destination UTF16String], &s) == 0) { -#endif + if (of_lstat(destination, &s) == 0) { errno = EEXIST; @throw [OFCopyItemFailedException exceptionWithSourcePath: source destinationPath: destination]; } @@ -726,26 +696,18 @@ } + (void)removeItemAtPath: (OFString*)path { void *pool; -#ifndef _WIN32 - struct stat s; -#else - struct _stat s; -#endif + of_stat_t s; if (path == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); -#ifndef _WIN32 - if (lstat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], &s)) -#else - if (_wstat([path UTF16String], &s)) -#endif + if (of_lstat(path, &s)) @throw [OFRemoveItemFailedException exceptionWithPath: path]; if (S_ISDIR(s.st_mode)) { OFArray *contents; OFEnumerator *enumerator;