| 72 | } |
| 73 | |
| 74 | bool FsFileNode::remove() { |
| 75 | BOXEDWINE_CRITICAL_SECTION_WITH_MUTEX(this->openNodesMutex); |
| 76 | bool result = false; |
| 77 | bool exists = Fs::doesNativePathExist(this->nativePath); |
| 78 | |
| 79 | if (!exists) { |
| 80 | this->removeNodeFromParent(); |
| 81 | return true; |
| 82 | } |
| 83 | #ifdef BOXEDWINE_ZLIB |
| 84 | if (zipNode) { |
| 85 | std::shared_ptr<FsZip> fsZip = zipNode->fsZip.lock(); |
| 86 | if (fsZip) { |
| 87 | fsZip->remove(this->path); |
| 88 | } |
| 89 | zipNode = nullptr; |
| 90 | result = true; |
| 91 | } |
| 92 | #endif |
| 93 | if (exists) { |
| 94 | BString dosAttrib = nativePath + EXT_DOSATTRIB; |
| 95 | unlink(dosAttrib.c_str()); |
| 96 | result = unlink(nativePath.c_str()) == 0; |
| 97 | } |
| 98 | // if the file failed to be deleted and it exists then its because someone else has it open, |
| 99 | // so we need to close all references, move the file then re-open the file for those handles |
| 100 | // that still have it open. By moving the file it will appear that it was deleted, but handles |
| 101 | // that have it open can still use it, just like Linux does. |
| 102 | if (!result && exists && this->openNodes.size()) { |
| 103 | S64* tmpPos = new S64[this->openNodes.size()]; |
| 104 | U32 i=0; |
| 105 | |
| 106 | this->openNodes.for_each([&tmpPos,&i](KListNode<FsOpenNode*>* n) { |
| 107 | FsOpenNode* openNode = n->data; |
| 108 | if (openNode->isOpen()) { |
| 109 | tmpPos[i++] = openNode->getFilePointer(); |
| 110 | openNode->close(); |
| 111 | } |
| 112 | }); |
| 113 | |
| 114 | Fs::makeLocalDirs(B("/tmp/del")); |
| 115 | std::shared_ptr<FsNode> delDir = Fs::getNodeFromLocalPath(B(""), B("/tmp/del"), true); |
| 116 | |
| 117 | BString newNativePath = FsFileNode::getNativeTmpPath(); |
| 118 | |
| 119 | if (::rename(nativePath.c_str(), newNativePath.c_str())!=0) { |
| 120 | klog_fmt("could not rename %s", nativePath.c_str()); |
| 121 | } |
| 122 | |
| 123 | this->nativePath = newNativePath; |
| 124 | |
| 125 | i=0; |
| 126 | this->openNodes.for_each([&tmpPos,&i](KListNode<FsOpenNode*>* n) { |
| 127 | FsOpenNode* openNode = n->data; |
| 128 | openNode->reopen(); |
| 129 | if (openNode->isOpen()) { |
| 130 | openNode->seek(tmpPos[i++]); |
| 131 | } |
no test coverage detected