* {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:
parent
a474455132
commit
42c9b01aa6
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -21,10 +21,6 @@
|
||||
#include <string>
|
||||
|
||||
|
||||
// R5 compatibility
|
||||
#define R5_STAT_SIZE 60
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
namespace Storage {
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user