Implement TODO: Check for non-empty directories before removing an entry. This
fixes #4358, there changing the Tracker preferences causes some default directories to be created, like "home" and "config", which were previously simply killing off the real ones. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32822 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -116,6 +116,8 @@ public:
|
|||||||
void SetParentDir(OverlayInode *parentDir);
|
void SetParentDir(OverlayInode *parentDir);
|
||||||
OverlayInode * ParentDir() { return fParentDir; }
|
OverlayInode * ParentDir() { return fParentDir; }
|
||||||
|
|
||||||
|
bool IsNonEmptyDirectory();
|
||||||
|
|
||||||
status_t Lookup(const char *name, ino_t *inodeNumber);
|
status_t Lookup(const char *name, ino_t *inodeNumber);
|
||||||
void SetName(const char *name);
|
void SetName(const char *name);
|
||||||
status_t GetName(char *buffer, size_t bufferSize);
|
status_t GetName(char *buffer, size_t bufferSize);
|
||||||
@@ -287,6 +289,22 @@ OverlayInode::SetParentDir(OverlayInode *parentDir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
OverlayInode::IsNonEmptyDirectory()
|
||||||
|
{
|
||||||
|
if (!fHasStat)
|
||||||
|
ReadStat(NULL);
|
||||||
|
|
||||||
|
if (!S_ISDIR(fStat.st_mode))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!fHasDirents)
|
||||||
|
_PopulateDirents();
|
||||||
|
|
||||||
|
return fDirentCount > 2; // accounting for "." and ".." entries
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
OverlayInode::Lookup(const char *name, ino_t *inodeNumber)
|
OverlayInode::Lookup(const char *name, ino_t *inodeNumber)
|
||||||
{
|
{
|
||||||
@@ -829,10 +847,26 @@ OverlayInode::RemoveEntry(const char *name, overlay_dirent **_entry)
|
|||||||
if (!fHasDirents)
|
if (!fHasDirents)
|
||||||
_PopulateDirents();
|
_PopulateDirents();
|
||||||
|
|
||||||
// TODO: we may not simply remove non-empty directories
|
|
||||||
for (uint32 i = 0; i < fDirentCount; i++) {
|
for (uint32 i = 0; i < fDirentCount; i++) {
|
||||||
overlay_dirent *entry = fDirents[i];
|
overlay_dirent *entry = fDirents[i];
|
||||||
if (strcmp(entry->name, name) == 0) {
|
if (strcmp(entry->name, name) == 0) {
|
||||||
|
if (_entry == NULL) {
|
||||||
|
// check for non-empty directories when trying
|
||||||
|
// to dispose the entry
|
||||||
|
OverlayInode *node = NULL;
|
||||||
|
status_t result = get_vnode(Volume(), entry->inode_number,
|
||||||
|
(void **)&node);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (node->IsNonEmptyDirectory())
|
||||||
|
result = B_DIRECTORY_NOT_EMPTY;
|
||||||
|
|
||||||
|
put_vnode(Volume(), entry->inode_number);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32 j = i + 1; j < fDirentCount; j++)
|
for (uint32 j = i + 1; j < fDirentCount; j++)
|
||||||
fDirents[j - 1] = fDirents[j];
|
fDirents[j - 1] = fDirents[j];
|
||||||
fDirentCount--;
|
fDirentCount--;
|
||||||
|
|||||||
Reference in New Issue
Block a user