Index: src/OFFileManager.m ================================================================== --- src/OFFileManager.m +++ src/OFFileManager.m @@ -58,10 +58,11 @@ #import "OFLockFailedException.h" #import "OFMoveItemFailedException.h" #import "OFNotImplementedException.h" #import "OFOpenItemFailedException.h" #import "OFOutOfMemoryException.h" +#import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFRemoveItemFailedException.h" #import "OFStatItemFailedException.h" #import "OFUnlockFailedException.h" @@ -102,10 +103,21 @@ #endif #ifdef OF_WINDOWS static WINAPI BOOLEAN (*func_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD); #endif + +#ifdef OF_MORPHOS +static bool dirChanged = false; +static BPTR originalDirLock = 0; + +OF_DESTRUCTOR() +{ + if (dirChanged) + UnLock(CurrentDir(originalDirLock)); +} +#endif static int of_stat(OFString *path, of_stat_t *buffer) { #if defined(OF_WINDOWS) @@ -228,30 +240,48 @@ return defaultManager; } - (OFString *)currentDirectoryPath { +#if defined(OF_WINDOWS) OFString *ret; -#ifndef OF_WINDOWS - char *buffer = getcwd(NULL, 0); -#else wchar_t *buffer = _wgetcwd(NULL, 0); -#endif @try { -#ifndef OF_WINDOWS + ret = [OFString stringWithUTF16String: buffer]; + } @finally { + free(buffer); + } + + return ret; +#elif defined(OF_MORPHOS) + char buffer[512]; + + if (!NameFromLock(((struct Process *)FindTask(NULL))->pr_CurrentDir, + buffer, 512)) { + if (IoErr() == ERROR_LINE_TOO_LONG) + @throw [OFOutOfRangeException exception]; + + return nil; + } + + return [OFString stringWithCString: buffer + encoding: [OFLocalization encoding]]; +#else + OFString *ret; + char *buffer = getcwd(NULL, 0); + + @try { ret = [OFString stringWithCString: buffer encoding: [OFLocalization encoding]]; -#else - ret = [OFString stringWithUTF16String: buffer]; -#endif } @finally { free(buffer); } return ret; +#endif } - (bool)fileExistsAtPath: (OFString *)path { of_stat_t s; @@ -309,19 +339,58 @@ - (void)createDirectoryAtPath: (OFString *)path { if (path == nil) @throw [OFInvalidArgumentException exception]; -#ifndef OF_WINDOWS +#if defined(OF_WINDOWS) + if (_wmkdir([path UTF16String]) != 0) + @throw [OFCreateDirectoryFailedException + exceptionWithPath: path + errNo: errno]; +#elif defined(OF_MORPHOS) + BPTR lock; + + if ((lock = CreateDir( + [path cStringWithEncoding: [OFLocalization encoding]])) == 0) { + int errNo; + + switch (IoErr()) { + case ERROR_NO_FREE_STORE: + case ERROR_DISK_FULL: + errNo = ENOSPC; + break; + case ERROR_OBJECT_IN_USE: + case ERROR_DISK_NOT_VALIDATED: + errNo = EBUSY; + break; + case ERROR_OBJECT_EXISTS: + errNo = EEXIST; + break; + case ERROR_OBJECT_NOT_FOUND: + errNo = ENOENT; + break; + case ERROR_DISK_WRITE_PROTECTED: + errNo = EROFS; + break; + default: + errNo = 0; + break; + } + + @throw [OFCreateDirectoryFailedException + exceptionWithPath: path + errNo: errNo]; + } + + UnLock(lock); +#else if (mkdir([path cStringWithEncoding: [OFLocalization encoding]], 0777) != 0) -#else - if (_wmkdir([path UTF16String]) != 0) -#endif @throw [OFCreateDirectoryFailedException exceptionWithPath: path errNo: errno]; +#endif } - (void)createDirectoryAtPath: (OFString *)path createParents: (bool)createParents { @@ -482,18 +551,54 @@ - (void)changeCurrentDirectoryPath: (OFString *)path { if (path == nil) @throw [OFInvalidArgumentException exception]; -#ifndef OF_WINDOWS - if (chdir([path cStringWithEncoding: [OFLocalization encoding]]) != 0) -#else +#if defined(OF_WINDOWS) if (_wchdir([path UTF16String]) != 0) -#endif + @throw [OFChangeCurrentDirectoryPathFailedException + exceptionWithPath: path + errNo: errno]; +#elif defined(OF_MORPHOS) + BPTR lock, oldLock; + + if ((lock = Lock([path cStringWithEncoding: [OFLocalization encoding]], + SHARED_LOCK)) == 0) { + int errNo; + + switch (IoErr()) { + case ERROR_OBJECT_IN_USE: + case ERROR_DISK_NOT_VALIDATED: + errNo = EBUSY; + break; + case ERROR_OBJECT_NOT_FOUND: + errNo = ENOENT; + break; + default: + errNo = 0; + break; + } + + @throw [OFChangeCurrentDirectoryPathFailedException + exceptionWithPath: path + errNo: errNo]; + } + + oldLock = CurrentDir(lock); + + if (!dirChanged) + originalDirLock = oldLock; + else + UnLock(oldLock); + + dirChanged = true; +#else + if (chdir([path cStringWithEncoding: [OFLocalization encoding]]) != 0) @throw [OFChangeCurrentDirectoryPathFailedException exceptionWithPath: path errNo: errno]; +#endif } - (of_offset_t)sizeOfFileAtPath: (OFString *)path { of_stat_t s;