diff options
-rw-r--r-- | backends/fs/amigaos4/amigaos4-fs.cpp | 90 |
1 files changed, 57 insertions, 33 deletions
diff --git a/backends/fs/amigaos4/amigaos4-fs.cpp b/backends/fs/amigaos4/amigaos4-fs.cpp index 7657bf20c0..806bd1e956 100644 --- a/backends/fs/amigaos4/amigaos4-fs.cpp +++ b/backends/fs/amigaos4/amigaos4-fs.cpp @@ -40,7 +40,7 @@ const char *lastPathComponent(const Common::String &str) { int offset = str.size(); if (offset <= 0) { - debug(6, "Bad offset"); + debug(6, "Bad offset!"); return 0; } @@ -71,31 +71,30 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(const Common::String &p) { int offset = p.size(); - //assert(offset > 0); - if (offset <= 0) { - debug(6, "Bad offset"); + debug(6, "Bad offset!"); return; } - // WORKAROUND: - // This is a bug in AmigaOS4 newlib.library 53.30 and lower. - // It will be removed once a fixed version is available to public. - // DESCRIPTION: - // We need to explicitly open dos.library and its IDOS interface. - // Otherwise we will hit an IDOS NULL pointer after compiling a - // shared binary with (shared) plugins. - // The hit will happen on loading a game from any engine, if more - // than one engine/(shared) plugin is available. - DOSBase = IExec->OpenLibrary("dos.library", 0); - IDOS = (struct DOSIFace *)IExec->GetInterface(DOSBase, "main", 1, NULL); - _sPath = p; _sDisplayName = ::lastPathComponent(_sPath); _pFileLock = 0; _bIsDirectory = false; _bIsValid = false; + // WORKAROUND: + // This is a workaround for a bug present in AmigaOS4's + // newlib.library 53.30 and lower. + // It will be removed once a fixed version of said library is + // available to the public. + // DESCRIPTION: + // We need to explicitly open dos.library and it's IDOS interface. + // Otherwise it will hit a NULL pointer with a shared binary build. + // The hit will happen on loading a game from any engine, if + // more than one engine (shared) plugin is available. + DOSBase = IExec->OpenLibrary("dos.library", 0); + IDOS = (struct DOSIFace *)IExec->GetInterface(DOSBase, "main", 1, NULL); + // Check whether the node exists and if it's a directory. struct ExamineData * pExd = IDOS->ExamineObjectTags(EX_StringNameInput,_sPath.c_str(),TAG_END); if (pExd) { @@ -105,7 +104,7 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(const Common::String &p) { _pFileLock = IDOS->Lock((CONST_STRPTR)_sPath.c_str(), SHARED_LOCK); _bIsValid = (_pFileLock != 0); - // Add a trailing slash if needed. + // Add a trailing slash, if needed. const char c = _sPath.lastChar(); if (c != '/' && c != ':') _sPath += '/'; @@ -127,6 +126,7 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(const Common::String &p) { AmigaOSFilesystemNode::AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayName) { ENTER(); + int bufSize = MAXPATHLEN; _pFileLock = 0; @@ -151,17 +151,20 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayNam delete[] n; } - _bIsValid = false; _bIsDirectory = false; + _bIsValid = false; + // Check whether the node exists and if it's a directory. struct ExamineData * pExd = IDOS->ExamineObjectTags(EX_FileLockInput,pLock,TAG_END); if (pExd) { _nProt = pExd->Protection; if (EXD_IS_DIRECTORY(pExd)) { _bIsDirectory = true; + _pFileLock = IDOS->DupLock(pLock); _bIsValid = _pFileLock != 0; + // Add a trailing slash, if needed. const char c = _sPath.lastChar(); if (c != '/' && c != ':') _sPath += '/'; @@ -172,7 +175,7 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayNam IDOS->FreeDosObject(DOS_EXAMINEDATA, pExd); } else { - debug(6, "ExamineObject() returned NULL"); + debug(6, "ExamineObject() returned NULL!"); } LEAVE(); @@ -222,12 +225,31 @@ bool AmigaOSFilesystemNode::exists() const { // IDOS->FreeDosObject(DOS_FIB, fib); // // ============================= New code + + // WORKAROUND: + // This is a workaround for a bug present in AmigaOS4's + // newlib.library 53.30 and lower. + // It will be removed once a fixed version of said library is + // available to the public. + // DESCRIPTION: + // We need to explicitly open dos.library and it's IDOS interface. + // Otherwise it will hit a NULL pointer with a shared binary build. + // The hit will happen on loading a game from any engine, if + // more than one engine (shared) plugin is available. + DOSBase = IExec->OpenLibrary("dos.library", 0); + IDOS = (struct DOSIFace *)IExec->GetInterface(DOSBase, "main", 1, NULL); + BPTR pLock = IDOS->Lock(_sPath.c_str(), SHARED_LOCK); if (pLock) { nodeExists = true; IDOS->UnLock(pLock); } + // WORKAROUND 2: + // Close dos.library and its IDOS interface again. + IExec->DropInterface((struct Interface *)IDOS); + IExec->CloseLibrary(DOSBase); + LEAVE(); return nodeExists; } @@ -235,7 +257,7 @@ bool AmigaOSFilesystemNode::exists() const { AbstractFSNode *AmigaOSFilesystemNode::getChild(const Common::String &n) const { ENTER(); if (!_bIsDirectory) { - debug(6, "Not a directory"); + debug(6, "Not a directory!"); return 0; } @@ -255,30 +277,31 @@ bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b bool ret = false; if (!_bIsValid) { - debug(6, "Invalid node"); + debug(6, "Invalid node!"); LEAVE(); return false; // Empty list } if (!_bIsDirectory) { - debug(6, "Not a directory"); + debug(6, "Not a directory!"); LEAVE(); return false; // Empty list } if (isRootNode()) { - debug(6, "Root node"); + debug(6, "Root node!"); LEAVE(); myList = listVolumes(); return true; } APTR context = IDOS->ObtainDirContextTags( EX_FileLockInput, _pFileLock, - EX_DoCurrentDir, TRUE, /* for softlinks */ - EX_DataFields, (EXF_NAME|EXF_LINK|EXF_TYPE), - TAG_END); + EX_DoCurrentDir, TRUE, /* for softlinks */ + EX_DataFields, (EXF_NAME|EXF_LINK|EXF_TYPE), + TAG_END); if (context) { - struct ExamineData * pExd = NULL; // NB: No need to free the value after usage, everything will be dealt with by the DirContext release + struct ExamineData * pExd = NULL; // No need to free the value after usage, everything + // will be dealt with by the DirContext release. AmigaOSFilesystemNode *entry; while ( (pExd = IDOS->ExamineDir(context)) ) { @@ -300,7 +323,7 @@ bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b } if (ERROR_NO_MORE_ENTRIES != IDOS->IoErr() ) { - debug(6, "An error occurred during ExamineDir"); + debug(6, "IoErr() - ExamineDir (NO_MORE_ENTRIES)!"); ret = false; } else { ret = true; @@ -309,7 +332,7 @@ bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b IDOS->ReleaseDirContext(context); } else { - debug(6, "Unable to ObtainDirContext"); + debug(6, "Unable to ObtainDirContext!"); ret = false; } @@ -322,7 +345,7 @@ AbstractFSNode *AmigaOSFilesystemNode::getParent() const { ENTER(); if (isRootNode()) { - debug(6, "Root node"); + debug(6, "Root node!"); LEAVE(); return new AmigaOSFilesystemNode(*this); } @@ -388,7 +411,7 @@ AbstractFSList AmigaOSFilesystemNode::listVolumes() const { struct DosList *dosList = IDOS->LockDosList(kLockFlags); if (!dosList) { - debug(6, "Cannot lock the DOS list"); + debug(6, "Cannot lock DOS list!"); LEAVE(); return myList; } @@ -408,7 +431,7 @@ AbstractFSList AmigaOSFilesystemNode::listVolumes() const { // which errored using SDK 53.24 with a // 'struct dosList' has no member called 'dol_Task' // The reason for that was, that - // 1) dol_Task wasn't a task pointer, it is a message port instead. + // 1) dol_Task wasn't a task pointer, it was a message port instead. // 2) it was redefined to be dol_Port in dos/obsolete.h in aforementioned SDK. // Copy name to buffer. @@ -429,7 +452,7 @@ AbstractFSList AmigaOSFilesystemNode::listVolumes() const { // Find device name. IDOS->DevNameFromLock(volumeLock, devName, MAXPATHLEN, DN_DEVICEONLY); - sprintf(buffer, "%s (%s)", volName, devName); + snprintf(buffer, MAXPATHLEN, "%s (%s)", volName, devName); delete[] devName; @@ -467,3 +490,4 @@ bool AmigaOSFilesystemNode::createDirectory() { } #endif //defined(__amigaos4__) + |