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:
Michael Lotz
2009-08-29 22:49:43 +00:00
parent 92e143c14a
commit da249e74e9
@@ -116,6 +116,8 @@ public:
void SetParentDir(OverlayInode *parentDir);
OverlayInode * ParentDir() { return fParentDir; }
bool IsNonEmptyDirectory();
status_t Lookup(const char *name, ino_t *inodeNumber);
void SetName(const char *name);
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
OverlayInode::Lookup(const char *name, ino_t *inodeNumber)
{
@@ -829,10 +847,26 @@ OverlayInode::RemoveEntry(const char *name, overlay_dirent **_entry)
if (!fHasDirents)
_PopulateDirents();
// TODO: we may not simply remove non-empty directories
for (uint32 i = 0; i < fDirentCount; i++) {
overlay_dirent *entry = fDirents[i];
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++)
fDirents[j - 1] = fDirents[j];
fDirentCount--;