@@ -40,10 +40,11 @@ #import "OFDate.h" #import "OFFile.h" #import "OFFileManager.h" #import "OFLocale.h" #import "OFNumber.h" +#import "OFSystemInfo.h" #import "OFURL.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif @@ -148,13 +149,21 @@ static int of_stat(OFString *path, of_stat_t *buffer) { #if defined(OF_WINDOWS) WIN32_FILE_ATTRIBUTE_DATA data; + bool success; - if (!GetFileAttributesExW(path.UTF16String, GetFileExInfoStandard, - &data)) { + if ([OFSystemInfo isWindowsNT]) + success = GetFileAttributesExW(path.UTF16String, + GetFileExInfoStandard, &data); + else + success = GetFileAttributesExA( + [path cStringWithEncoding: [OFLocale encoding]], + GetFileExInfoStandard, &data); + + if (!success) { setErrno(); return -1; } buffer->st_size = (uint64_t)data.nFileSizeHigh << 32 | @@ -161,10 +170,14 @@ data.nFileSizeLow; if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) buffer->st_mode = S_IFDIR; else if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + /* + * No need to use A functions in this branch: This is only + * available on NTFS (and hence Windows NT) anyway. + */ WIN32_FIND_DATAW findData; HANDLE findHandle; if ((findHandle = FindFirstFileW(path.UTF16String, &findData)) == INVALID_HANDLE_VALUE) { @@ -590,16 +603,21 @@ attributes: (of_file_attributes_t)attributes { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS uint16_t mode = permissions.uInt16Value & 0777; OFString *path = URL.fileSystemRepresentation; + int status; -# ifndef OF_WINDOWS - if (chmod([path cStringWithEncoding: [OFLocale encoding]], mode) != 0) -# else - if (_wchmod(path.UTF16String, mode) != 0) +# ifdef OF_WINDOWS + if ([OFSystemInfo isWindowsNT]) + status = _wchmod(path.UTF16String, mode); + else # endif + status = chmod( + [path cStringWithEncoding: [OFLocale encoding]], mode); + + if (status != 0) @throw [OFSetItemAttributesFailedException exceptionWithURL: URL attributes: attributes failedAttribute: of_file_attribute_key_posix_permissions errNo: errno]; @@ -778,11 +796,19 @@ @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; #if defined(OF_WINDOWS) - if (_wmkdir(path.UTF16String) != 0) + int status; + + if ([OFSystemInfo isWindowsNT]) + status = _wmkdir(path.UTF16String); + else + status = _mkdir( + [path cStringWithEncoding: [OFLocale encoding]]); + + if (status != 0) @throw [OFCreateDirectoryFailedException exceptionWithURL: URL errNo: errno]; #elif defined(OF_AMIGAOS) BPTR lock; @@ -844,49 +870,98 @@ path = URL.fileSystemRepresentation; #if defined(OF_WINDOWS) HANDLE handle; - WIN32_FIND_DATAW fd; path = [path stringByAppendingString: @"\\*"]; - if ((handle = FindFirstFileW(path.UTF16String, - &fd)) == INVALID_HANDLE_VALUE) { - int errNo = 0; - - if (GetLastError() == ERROR_FILE_NOT_FOUND) - errNo = ENOENT; - - @throw [OFOpenItemFailedException exceptionWithURL: URL - mode: nil - errNo: errNo]; - } - - @try { - do { - OFString *file; - - if (!wcscmp(fd.cFileName, L".") || - !wcscmp(fd.cFileName, L"..")) - continue; - - file = [[OFString alloc] - initWithUTF16String: fd.cFileName]; - @try { - [files addObject: file]; - } @finally { - [file release]; - } - } while (FindNextFileW(handle, &fd)); - - if (GetLastError() != ERROR_NO_MORE_FILES) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: 0 - errNo: EIO]; - } @finally { - FindClose(handle); + if ([OFSystemInfo isWindowsNT]) { + WIN32_FIND_DATAW fd; + + if ((handle = FindFirstFileW(path.UTF16String, + &fd)) == INVALID_HANDLE_VALUE) { + int errNo = 0; + + if (GetLastError() == ERROR_FILE_NOT_FOUND) + errNo = ENOENT; + + @throw [OFOpenItemFailedException + exceptionWithURL: URL + mode: nil + errNo: errNo]; + } + + @try { + do { + OFString *file; + + if (wcscmp(fd.cFileName, L".") == 0 || + wcscmp(fd.cFileName, L"..") == 0) + continue; + + file = [[OFString alloc] + initWithUTF16String: fd.cFileName]; + @try { + [files addObject: file]; + } @finally { + [file release]; + } + } while (FindNextFileW(handle, &fd)); + + if (GetLastError() != ERROR_NO_MORE_FILES) + @throw [OFReadFailedException + exceptionWithObject: self + requestedLength: 0 + errNo: EIO]; + } @finally { + FindClose(handle); + } + } else { + of_string_encoding_t encoding = [OFLocale encoding]; + WIN32_FIND_DATA fd; + + if ((handle = FindFirstFileA( + [path cStringWithEncoding: encoding], &fd)) == + INVALID_HANDLE_VALUE) { + int errNo = 0; + + if (GetLastError() == ERROR_FILE_NOT_FOUND) + errNo = ENOENT; + + @throw [OFOpenItemFailedException + exceptionWithURL: URL + mode: nil + errNo: errNo]; + } + + @try { + do { + OFString *file; + + if (strcmp(fd.cFileName, ".") == 0 || + strcmp(fd.cFileName, "..") == 0) + continue; + + file = [[OFString alloc] + initWithCString: fd.cFileName + encoding: encoding]; + @try { + [files addObject: file]; + } @finally { + [file release]; + } + } while (FindNextFileA(handle, &fd)); + + if (GetLastError() != ERROR_NO_MORE_FILES) + @throw [OFReadFailedException + exceptionWithObject: self + requestedLength: 0 + errNo: EIO]; + } @finally { + FindClose(handle); + } } #elif defined(OF_AMIGAOS) of_string_encoding_t encoding = [OFLocale encoding]; BPTR lock; @@ -1092,25 +1167,36 @@ objc_autoreleasePoolPop(pool2); } #ifndef OF_AMIGAOS -# ifndef OF_WINDOWS - if (rmdir([path cStringWithEncoding: [OFLocale encoding]]) != 0) -# else - if (_wrmdir(path.UTF16String) != 0) + int status; + +# ifdef OF_WINDOWS + if ([OFSystemInfo isWindowsNT]) + status = _wrmdir(path.UTF16String); + else # endif + status = rmdir( + [path cStringWithEncoding: [OFLocale encoding]]); + + if (status != 0) @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: errno]; } else { -# ifndef OF_WINDOWS - if (unlink([path cStringWithEncoding: - [OFLocale encoding]]) != 0) -# else - if (_wunlink(path.UTF16String) != 0) + int status; + +# ifdef OF_WINDOWS + if ([OFSystemInfo isWindowsNT]) + status = _wunlink(path.UTF16String); + else # endif + status = unlink( + [path cStringWithEncoding: [OFLocale encoding]]); + + if (status != 0) @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: errno]; #endif } @@ -1244,18 +1330,11 @@ destinationURL: destination errNo: EEXIST]; pool = objc_autoreleasePoolPush(); -#if defined(OF_WINDOWS) - if (_wrename(source.fileSystemRepresentation.UTF16String, - destination.fileSystemRepresentation.UTF16String) != 0) - @throw [OFMoveItemFailedException - exceptionWithSourceURL: source - destinationURL: destination - errNo: errno]; -#elif defined(OF_AMIGAOS) +#ifdef OF_AMIGAOS of_string_encoding_t encoding = [OFLocale encoding]; if (!Rename([source.fileSystemRepresentation cStringWithEncoding: encoding], [destination.fileSystemRepresentation @@ -1288,16 +1367,29 @@ exceptionWithSourceURL: source destinationURL: destination errNo: errNo]; } #else - of_string_encoding_t encoding = [OFLocale encoding]; + int status; + +# ifdef OF_WINDOWS + if ([OFSystemInfo isWindowsNT]) + status = _wrename(source.fileSystemRepresentation.UTF16String, + destination.fileSystemRepresentation.UTF16String); + else { +# endif + of_string_encoding_t encoding = [OFLocale encoding]; + + status = rename([source.fileSystemRepresentation + cStringWithEncoding: encoding], + [destination.fileSystemRepresentation + cStringWithEncoding: encoding]); +# ifdef OF_WINDOWS + } +# endif - if (rename([source.fileSystemRepresentation - cStringWithEncoding: encoding], - [destination.fileSystemRepresentation - cStringWithEncoding: encoding]) != 0) + if (status != 0) @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: errno]; #endif