* {BEntry,BNode}::GetStat() were still passing the BeOS struct stat size to

the syscall. Anything beyond st_mtim was therefore not filled in. Fixes
  the incorrectly shown creation times in Tracker.
* The BStatable::GetStat() solution was not sufficient yet. We still have to
  provide the old GetStat() symbol for BNode and BEntry, since those could be
  used by old applications/libraries. We also still have to implement the old
  GetStat() slots in the derived classes, but don't need to implement it in
  the base class (was purely virtual before and is private now).
* The old BStatable::_OhSoStatable1() slot function was not implemented
  correctly. Calling the virtual function at the vtable slot obviously results
  in an infinite recursion. The correct implementation would make use of the
  Perform() method, but Be didn't provide one for BStatable, so we have to use
  the old GetStat() method. Fixed #3960.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30851 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-05-25 14:03:38 +00:00
parent a474455132
commit 42c9b01aa6
7 changed files with 205 additions and 96 deletions

View File

@ -1,7 +1,7 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
/*
* Copyright 2002-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
/*!
\file Entry.h
BEntry and entry_ref interface declarations.
@ -27,7 +27,7 @@ struct entry_ref {
entry_ref(dev_t dev, ino_t dir, const char *name);
entry_ref(const entry_ref &ref);
~entry_ref();
status_t set_name(const char *name);
bool operator==(const entry_ref &ref) const;
@ -87,29 +87,33 @@ private:
virtual void _PennyEntry4();
virtual void _PennyEntry5();
virtual void _PennyEntry6();
/*! Currently unused. */
uint32 _pennyData[4];
/*! BEntry implementation of BStatable::set_stat() */
virtual status_t set_stat(struct stat &st, uint32 what);
status_t set(int dir, const char *path, bool traverse);
/*! File descriptor for the entry's parent directory. */
int fDirFd;
/*! Leaf name of the entry. */
char *fName;
/*! The object's initialization status. */
status_t fCStatus;
status_t set_name(const char *name);
status_t _Rename(BEntry& target, bool clobber);
void Dump(const char *name = NULL);
status_t _GetStat(struct stat *st) const;
virtual status_t _GetStat(struct stat_beos *st) const;
private:
/*! Currently unused. */
uint32 _pennyData[4];
/*! File descriptor for the entry's parent directory. */
int fDirFd;
/*! Leaf name of the entry. */
char *fName;
/*! The object's initialization status. */
status_t fCStatus;
};
// C functions

View File

@ -1,13 +1,13 @@
/*
* Copyright 2002-2007, Haiku, Inc. All Rights Reserved.
* Copyright 2002-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _NODE_H
#define _NODE_H
#include <Statable.h>
class BDirectory;
class BEntry;
class BString;
@ -22,7 +22,7 @@ struct entry_ref;
@version 0.0.0
*/
struct node_ref {
node_ref();
node_ref();
node_ref(const node_ref &ref);
bool operator==(const node_ref &ref) const;
@ -93,15 +93,13 @@ private:
friend class BDirectory;
friend class BSymLink;
virtual void _RudeNode1();
virtual void _RudeNode1();
virtual void _RudeNode2();
virtual void _RudeNode3();
virtual void _RudeNode4();
virtual void _RudeNode5();
virtual void _RudeNode6();
uint32 rudeData[4];
private:
status_t set_fd(int fd);
virtual void close_fd();
@ -112,6 +110,11 @@ private:
virtual status_t set_stat(struct stat &st, uint32 what);
status_t _GetStat(struct stat *st) const;
virtual status_t _GetStat(struct stat_beos *st) const;
private:
uint32 rudeData[4];
int fFd;
int fAttrFd;
status_t fCStatus;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2007, Haiku, Inc. All Rights Reserved.
* Copyright 2002-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _STATABLE_H
@ -24,7 +24,7 @@ class BStatable {
#endif
private:
virtual status_t _GetStat(struct stat_beos *st) const;
virtual status_t _GetStat(struct stat_beos *st) const = 0;
// provided for BeOS compatibility
public:
@ -58,9 +58,12 @@ public:
status_t GetVolume(BVolume *vol) const;
class Private;
private:
friend class BEntry;
friend class BNode;
friend class Private;
virtual void _OhSoStatable2();
virtual void _OhSoStatable3();

View File

@ -21,10 +21,6 @@
#include <string>
// R5 compatibility
#define R5_STAT_SIZE 60
namespace BPrivate {
namespace Storage {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2006, Haiku Inc.
* Copyright 2002-2009, Haiku Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -13,13 +13,7 @@
BEntry and entry_ref implementations.
*/
#include <Directory.h>
#include <Entry.h>
#include <Path.h>
#include <SymLink.h>
#include "storage_support.h"
#include <syscalls.h>
#include <fcntl.h>
#include <new>
@ -28,6 +22,17 @@
#include <string.h>
#include <unistd.h>
#include <compat/sys/stat.h>
#include <Directory.h>
#include <Path.h>
#include <SymLink.h>
#include <syscalls.h>
#include "storage_support.h"
using namespace std;
@ -326,7 +331,8 @@ BEntry::Exists() const
}
/*! \brief Fills in a stat structure for the entry. The information is copied into
/*! \fn status_t BEntry::GetStat(struct stat *result) const
\brief Fills in a stat structure for the entry. The information is copied into
the \c stat structure pointed to by \a result.
\b NOTE: The BStatable object does not cache the stat structure; every time you
@ -337,14 +343,6 @@ BEntry::Exists() const
- \c B_OK - Success
- "error code" - Failure
*/
status_t
BEntry::GetStat(struct stat *result) const
{
if (fCStatus != B_OK)
return B_NO_INIT;
return _kern_read_stat(fDirFd, fName, false, result, R5_STAT_SIZE);
}
/*! \brief Reinitializes the BEntry to the path or directory path combination,
@ -1060,6 +1058,30 @@ BEntry::Dump(const char *name)
}
status_t
BEntry::_GetStat(struct stat *st) const
{
if (fCStatus != B_OK)
return B_NO_INIT;
return _kern_read_stat(fDirFd, fName, false, st, sizeof(struct stat));
}
status_t
BEntry::_GetStat(struct stat_beos *st) const
{
struct stat newStat;
status_t error = _GetStat(&newStat);
if (error != B_OK)
return error;
convert_to_stat_beos(&newStat, st);
return B_OK;
}
// get_ref_for_path
/*! \brief Returns an entry_ref for a given path.
\param path The path name referring to the entry
@ -1103,3 +1125,29 @@ operator<(const entry_ref & a, const entry_ref & b)
|| (a.name != NULL && b.name != NULL
&& strcmp(a.name, b.name) < 0))))));
}
// #pragma mark - symbol versions
#if __GNUC__ == 2 // gcc 2
// BeOS compatible GetStat()
B_DEFINE_SYMBOL_VERSION("_GetStat__C6BEntryP9stat_beos",
"GetStat__C6BEntryP4stat@LIBBE_BASE");
// Haiku GetStat()
B_DEFINE_SYMBOL_VERSION("_GetStat__C6BEntryP4stat",
"GetStat__C6BEntryP4stat@@LIBBE_1_ALPHA1");
#else // gcc 4
// BeOS compatible GetStat()
B_DEFINE_SYMBOL_VERSION("_ZNK6BEntry8_GetStatEP9stat_beos",
"_ZNK6BEntry7GetStatEP4stat@LIBBE_BASE");
// Haiku GetStat()
B_DEFINE_SYMBOL_VERSION("_ZNK6BEntry8_GetStatEP4stat",
"_ZNK6BEntry7GetStatEP4stat@@LIBBE_1_ALPHA1");
#endif // gcc 4

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2006, Haiku Inc.
* Copyright 2002-2009, Haiku Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -13,16 +13,7 @@
BNode implementation.
*/
#include "storage_support.h"
#include <Directory.h>
#include <Entry.h>
#include <fs_attr.h>
#include <Node.h>
#include <String.h>
#include <TypeConstants.h>
#include <syscalls.h>
#include <errno.h>
#include <fcntl.h>
@ -30,6 +21,18 @@
#include <string.h>
#include <unistd.h>
#include <compat/sys/stat.h>
#include <Directory.h>
#include <Entry.h>
#include <fs_attr.h>
#include <String.h>
#include <TypeConstants.h>
#include <syscalls.h>
#include "storage_support.h"
// #pragma mark - node_ref
@ -188,7 +191,8 @@ BNode::InitCheck() const
}
/*! \brief Fills in the given stat structure with \code stat() \endcode
/*! \fn status_t BNode::GetStat(struct stat *st) const
\brief Fills in the given stat structure with \code stat() \endcode
information for this object.
\param st a pointer to a stat structure to be filled in
\return
@ -196,13 +200,6 @@ BNode::InitCheck() const
- \c B_BAD_VALUE: \c NULL \a st.
- another error code, e.g., if the object wasn't properly initialized
*/
status_t
BNode::GetStat(struct stat *st) const
{
return fCStatus != B_OK
? fCStatus
: _kern_read_stat(fFd, NULL, false, st, R5_STAT_SIZE);
}
/*! \brief Reinitializes the object to the specified entry_ref.
@ -283,7 +280,7 @@ void
BNode::Unset()
{
close_fd();
fCStatus = B_NO_INIT;
fCStatus = B_NO_INIT;
}
@ -480,7 +477,7 @@ BNode::GetNextAttrName(char *buffer)
return B_BAD_VALUE; // /new R5 crashed when passed NULL
if (InitAttrDir() != B_OK)
return B_FILE_ERROR;
BPrivate::Storage::LongDirEntry entry;
ssize_t result = _kern_read_dir(fAttrFd, &entry, sizeof(entry), 1);
if (result < 0)
@ -502,7 +499,7 @@ status_t
BNode::RewindAttrs()
{
if (InitAttrDir() != B_OK)
return B_FILE_ERROR;
return B_FILE_ERROR;
return _kern_rewind_dir(fAttrFd);
}
@ -556,14 +553,14 @@ BNode::ReadAttrString(const char *name, BString *result) const
error = GetAttrInfo(name, &info);
if (error != B_OK)
return error;
return error;
// Lock the string's buffer so we can meddle with it
// Lock the string's buffer so we can meddle with it
char *data = result->LockBuffer(info.size + 1);
if (!data)
return B_NO_MEMORY;
// Read the attribute
// Read the attribute
ssize_t bytes = ReadAttr(name, B_STRING_TYPE, 0, data, info.size);
// Check for failure
if (bytes < 0) {
@ -574,7 +571,7 @@ BNode::ReadAttrString(const char *name, BString *result) const
// Null terminate the new string just to be sure (since it *is*
// possible to read and write non-NULL-terminated strings)
data[bytes] = 0;
data[bytes] = 0;
result->UnlockBuffer();
return error;
}
@ -589,10 +586,10 @@ BNode::operator=(const BNode &node)
{
// No need to do any assignment if already equal
if (*this == node)
return *this;
return *this;
// Close down out current state
Unset();
Unset();
// We have to manually dup the node, because R5::BNode::Dup()
// is not declared to be const (which IMO is retarded).
fFd = _kern_dup(node.fFd);
@ -611,7 +608,7 @@ bool
BNode::operator==(const BNode &node) const
{
if (fCStatus == B_NO_INIT && node.InitCheck() == B_NO_INIT)
return true;
return true;
if (fCStatus == B_OK && node.InitCheck() == B_OK) {
// compare the node_refs
node_ref ref1, ref2;
@ -620,8 +617,8 @@ BNode::operator==(const BNode &node) const
if (node.GetNodeRef(&ref2) != B_OK)
return false;
return (ref1 == ref2);
}
return false;
}
return false;
}
@ -692,11 +689,11 @@ BNode::close_fd()
if (fAttrFd >= 0) {
_kern_close(fAttrFd);
fAttrFd = -1;
}
}
if (fFd >= 0) {
_kern_close(fFd);
fFd = -1;
}
}
}
@ -824,7 +821,29 @@ BNode::InitAttrDir()
// set close on exec flag
fcntl(fAttrFd, F_SETFD, FD_CLOEXEC);
}
return fCStatus;
return fCStatus;
}
status_t
BNode::_GetStat(struct stat *st) const
{
return fCStatus != B_OK
? fCStatus
: _kern_read_stat(fFd, NULL, false, st, sizeof(struct stat));
}
status_t
BNode::_GetStat(struct stat_beos *st) const
{
struct stat newStat;
status_t error = _GetStat(&newStat);
if (error != B_OK)
return error;
convert_to_stat_beos(&newStat, st);
return B_OK;
}
@ -839,3 +858,29 @@ BNode::InitAttrDir()
/*! \var BNode::fCStatus
The object's initialization status.
*/
// #pragma mark - symbol versions
#if __GNUC__ == 2 // gcc 2
// BeOS compatible GetStat()
B_DEFINE_SYMBOL_VERSION("_GetStat__C5BNodeP9stat_beos",
"GetStat__C5BNodeP4stat@LIBBE_BASE");
// Haiku GetStat()
B_DEFINE_SYMBOL_VERSION("_GetStat__C5BNodeP4stat",
"GetStat__C5BNodeP4stat@@LIBBE_1_ALPHA1");
#else // gcc 4
// BeOS compatible GetStat()
B_DEFINE_SYMBOL_VERSION("_ZNK5BNode8_GetStatEP9stat_beos",
"_ZNK5BNode7GetStatEP4stat@LIBBE_BASE");
// Haiku GetStat()
B_DEFINE_SYMBOL_VERSION("_ZNK5BNode8_GetStatEP4stat",
"_ZNK5BNode7GetStatEP4stat@@LIBBE_1_ALPHA1");
#endif // gcc 4

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2007, Haiku, Inc. All Rights Reserved.
* Copyright 2002-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -23,6 +23,24 @@
#include <Volume.h>
class BStatable::Private {
public:
Private(const BStatable* object)
:
fObject(object)
{
}
status_t GetStatBeOS(struct stat_beos* st)
{
return fObject->_GetStat(st);
}
private:
const BStatable* fObject;
};
#if __GNUC__ > 2
BStatable::~BStatable()
{
@ -41,21 +59,6 @@ BStatable::~BStatable()
*/
/*! \brief GetStat() compatibility version.
*/
status_t
BStatable::_GetStat(struct stat_beos *st) const
{
struct stat newStat;
status_t error = GetStat(&newStat);
if (error != B_OK)
return error;
convert_to_stat_beos(&newStat, st);
return B_OK;
}
/*! \brief Returns if the current node is a file.
\return \c true, if the BNode is properly initialized and is a file,
\c false otherwise.
@ -330,7 +333,14 @@ _OhSoStatable1__9BStatable(const BStatable *self, struct stat *st)
_ZN9BStatable14_OhSoStatable1Ev(const BStatable *self, struct stat *st)
#endif
{
return self->GetStat(st);
// No Perform() method -- we have to use the old GetStat() method instead.
struct stat_beos oldStat;
status_t error = BStatable::Private(self).GetStatBeOS(&oldStat);
if (error != B_OK)
return error;
convert_from_stat_beos(&oldStat, st);
return B_OK;
}