Updated filesystem traversal code to skip files/devices that don't
support attributes. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1325 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -14,6 +14,9 @@
|
|||||||
#include <RegistrarThread.h>
|
#include <RegistrarThread.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <pair.h>
|
||||||
|
|
||||||
struct entry_ref;
|
struct entry_ref;
|
||||||
class BMessage;
|
class BMessage;
|
||||||
|
|
||||||
@@ -37,8 +40,12 @@ protected:
|
|||||||
const bool fRecursive;
|
const bool fRecursive;
|
||||||
const bool fForce;
|
const bool fForce;
|
||||||
BMessage *fReplyee;
|
BMessage *fReplyee;
|
||||||
|
|
||||||
|
bool DeviceSupportsAttributes(dev_t device);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::list< std::pair<dev_t, bool> > fAttributeSupportList;
|
||||||
|
|
||||||
status_t UpdateEntry(const entry_ref *ref);
|
status_t UpdateEntry(const entry_ref *ref);
|
||||||
|
|
||||||
status_t fStatus;
|
status_t fStatus;
|
||||||
|
|||||||
@@ -10,9 +10,11 @@
|
|||||||
#include "mime/MimeUpdateThread.h"
|
#include "mime/MimeUpdateThread.h"
|
||||||
|
|
||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
|
#include <kernel_interface.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <RegistrarDefs.h>
|
#include <RegistrarDefs.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@@ -60,6 +62,7 @@ MimeUpdateThread::MimeUpdateThread(const char *name, int32 priority, BMessenger
|
|||||||
*/
|
*/
|
||||||
MimeUpdateThread::~MimeUpdateThread()
|
MimeUpdateThread::~MimeUpdateThread()
|
||||||
{
|
{
|
||||||
|
// delete our acquired BMessage
|
||||||
if (InitCheck() == B_OK)
|
if (InitCheck() == B_OK)
|
||||||
delete fReplyee;
|
delete fReplyee;
|
||||||
}
|
}
|
||||||
@@ -110,6 +113,53 @@ MimeUpdateThread::ThreadFunction()
|
|||||||
find_thread(NULL), err));
|
find_thread(NULL), err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeviceSupportsAttributes
|
||||||
|
/*! \brief Returns true if the given device supports attributes, false
|
||||||
|
if not (or if an error occurs while determining).
|
||||||
|
|
||||||
|
Device numbers and their corresponding support info are cached in
|
||||||
|
a std::list to save unnecessarily \c statvfs()ing devices that have
|
||||||
|
already been statvfs()ed (which might otherwise happen quite often
|
||||||
|
for a device that did in fact support attributes).
|
||||||
|
|
||||||
|
\return
|
||||||
|
- \c true: The device supports attributes
|
||||||
|
- \c false: The device does not support attributes, or there was an
|
||||||
|
error while determining
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
MimeUpdateThread::DeviceSupportsAttributes(dev_t device)
|
||||||
|
{
|
||||||
|
// See if an entry for this device already exists
|
||||||
|
std::list< std::pair<dev_t,bool> >::iterator i;
|
||||||
|
for (i = fAttributeSupportList.begin();
|
||||||
|
i != fAttributeSupportList.end();
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
if (i->first == device)
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
// If we get here, no such device is yet in our list,
|
||||||
|
// so we attempt to remedy the situation
|
||||||
|
BVolume volume;
|
||||||
|
status_t err = volume.SetTo(device);
|
||||||
|
if (!err) {
|
||||||
|
result = volume.KnowsAttr();
|
||||||
|
// devices supporting attributes are likely to be queried
|
||||||
|
// again, devices not supporting attributes are not
|
||||||
|
std::pair<dev_t,bool> p(device, result);
|
||||||
|
if (result)
|
||||||
|
fAttributeSupportList.push_front(p);
|
||||||
|
else
|
||||||
|
fAttributeSupportList.push_back(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateEntry
|
// UpdateEntry
|
||||||
/*! \brief Updates the given entry and then recursively updates all the entry's child
|
/*! \brief Updates the given entry and then recursively updates all the entry's child
|
||||||
entries if the entry is a directory and \c fRecursive is true.
|
entries if the entry is a directory and \c fRecursive is true.
|
||||||
@@ -120,39 +170,47 @@ MimeUpdateThread::UpdateEntry(const entry_ref *ref)
|
|||||||
status_t err = ref ? B_OK : B_BAD_VALUE;
|
status_t err = ref ? B_OK : B_BAD_VALUE;
|
||||||
bool entryIsDir = false;
|
bool entryIsDir = false;
|
||||||
|
|
||||||
// Update this entry
|
|
||||||
if (!err) {
|
|
||||||
DoMimeUpdate(ref, &entryIsDir);
|
|
||||||
// err = DoMimeUpdate(ref, &entryIsDir);
|
|
||||||
/* BPath path(ref);
|
|
||||||
printf("Updating '%s'... ", path.Path());
|
|
||||||
fflush(stdout);
|
|
||||||
printf("0x%lx\n", DoMimeUpdate(ref, &entryIsDir));
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
// Look to see if we're being terminated
|
// Look to see if we're being terminated
|
||||||
if (!err && fShouldExit)
|
if (!err && fShouldExit)
|
||||||
err = B_CANCELED;
|
err = B_CANCELED;
|
||||||
// If we're recursing and this is a directory, update
|
|
||||||
// each of the directory's children as well
|
// Before we update, make sure this entry lives on a device that supports
|
||||||
if (!err && fRecursive && entryIsDir) {
|
// attributes. If not, we skip it and any of its children for
|
||||||
BDirectory dir;
|
// updates (we don't signal an error, however).
|
||||||
err = dir.SetTo(ref);
|
|
||||||
|
//BPath path(ref);
|
||||||
|
//printf("Updating '%s' (%s)... \n", path.Path(),
|
||||||
|
// (DeviceSupportsAttributes(ref->device) ? "yes" : "no"));
|
||||||
|
|
||||||
|
if (!err
|
||||||
|
&& (device_is_root_device(ref->device)
|
||||||
|
|| DeviceSupportsAttributes(ref->device))) {
|
||||||
|
// Update this entry
|
||||||
if (!err) {
|
if (!err) {
|
||||||
entry_ref childRef;
|
// R5 appears to ignore whether or not the update succeeds.
|
||||||
while (!err) {
|
DoMimeUpdate(ref, &entryIsDir);
|
||||||
err = dir.GetNextRef(&childRef);
|
}
|
||||||
if (err) {
|
// If we're recursing and this is a directory, update
|
||||||
// If we've come to the end of the directory listing,
|
// each of the directory's children as well
|
||||||
// it's not an error.
|
if (!err && fRecursive && entryIsDir) {
|
||||||
if (err == B_ENTRY_NOT_FOUND)
|
BDirectory dir;
|
||||||
err = B_OK;
|
err = dir.SetTo(ref);
|
||||||
break;
|
if (!err) {
|
||||||
} else {
|
entry_ref childRef;
|
||||||
err = UpdateEntry(&childRef);
|
while (!err) {
|
||||||
}
|
err = dir.GetNextRef(&childRef);
|
||||||
}
|
if (err) {
|
||||||
}
|
// If we've come to the end of the directory listing,
|
||||||
|
// it's not an error.
|
||||||
|
if (err == B_ENTRY_NOT_FOUND)
|
||||||
|
err = B_OK;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
err = UpdateEntry(&childRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user