* Made our struct stat POSIX compliant again -- the time_t fields have been

replaced by timespec fields. Via macros the structure is still source
  compatible with the old one.
* Introduced header <compat/sys/stat.h> that defines the old stat structure
  (as stat_beos) and conversion functions
* Introduced versions for [l,f]stat().
* Added symbol versions for BDirectory::GetStatFor() for sake of binary
  compatibility.
* BStatable::GetStat(): Renamed the old method, changed its parameter to
  stat_beos*, and and made it private. Added a new version (using up a
  reserved vtable slot). It remains source and binary compatible.
* BRefFilter::Filter(): Changed the struct stat* parameter to struct stat_beos*
  for sake of binary compatibility. This breaks source compatibility, though,
  which we can't help, since the class doesn't have reserved vtable slots.
* Fixed several issues with the stat structure change, mostly adjusted uses of
  BRefFilter.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30830 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-05-22 15:15:16 +00:00
parent f15e418bab
commit bcfe344c53
18 changed files with 360 additions and 136 deletions

View File

@ -10,8 +10,10 @@
#include <EntryList.h> #include <EntryList.h>
#include <StorageDefs.h> #include <StorageDefs.h>
class BFile; class BFile;
class BSymLink; class BSymLink;
struct stat_beos;
class BDirectory : public BNode, public BEntryList { class BDirectory : public BNode, public BEntryList {
@ -64,6 +66,9 @@ class BDirectory : public BNode, public BEntryList {
friend class BEntry; friend class BEntry;
friend class BFile; friend class BFile;
status_t _GetStatFor(const char *path, struct stat *st) const;
status_t _GetStatFor(const char *path, struct stat_beos *st) const;
virtual void _ErectorDirectory1(); virtual void _ErectorDirectory1();
virtual void _ErectorDirectory2(); virtual void _ErectorDirectory2();
virtual void _ErectorDirectory3(); virtual void _ErectorDirectory3();

View File

@ -14,6 +14,7 @@ class BMessage;
class BMessenger; class BMessenger;
class BWindow; class BWindow;
struct stat; struct stat;
struct stat_beos;
class BRefFilter { class BRefFilter {
@ -22,7 +23,7 @@ class BRefFilter {
virtual ~BRefFilter() {}; virtual ~BRefFilter() {};
#endif #endif
virtual bool Filter(const entry_ref* ref, BNode* node, virtual bool Filter(const entry_ref* ref, BNode* node,
struct stat* stat, const char* mimeType) = 0; struct stat_beos* stat, const char* mimeType) = 0;
}; };

View File

@ -11,9 +11,11 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
struct node_ref; struct node_ref;
struct stat_beos;
class BVolume; class BVolume;
class BStatable { class BStatable {
public: public:
@ -21,6 +23,11 @@ class BStatable {
virtual ~BStatable(); virtual ~BStatable();
#endif #endif
private:
virtual status_t _GetStat(struct stat_beos *st) const;
// provided for BeOS compatibility
public:
virtual status_t GetStat(struct stat *st) const = 0; virtual status_t GetStat(struct stat *st) const = 0;
bool IsFile() const; bool IsFile() const;
@ -38,7 +45,7 @@ class BStatable {
status_t GetPermissions(mode_t *perms) const; status_t GetPermissions(mode_t *perms) const;
status_t SetPermissions(mode_t perms); status_t SetPermissions(mode_t perms);
status_t GetSize(off_t *size) const; status_t GetSize(off_t *size) const;
status_t GetModificationTime(time_t *mtime) const; status_t GetModificationTime(time_t *mtime) const;
status_t SetModificationTime(time_t mtime); status_t SetModificationTime(time_t mtime);
@ -55,7 +62,6 @@ class BStatable {
friend class BEntry; friend class BEntry;
friend class BNode; friend class BNode;
virtual void _OhSoStatable1();
virtual void _OhSoStatable2(); virtual void _OhSoStatable2();
virtual void _OhSoStatable3(); virtual void _OhSoStatable3();
uint32 _reserved[4]; uint32 _reserved[4];

View File

@ -0,0 +1,48 @@
/*
* Copyright 2002-2009, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _COMPAT_SYS_STAT_H_
#define _COMPAT_SYS_STAT_H_
#include <sys/stat.h>
/* helper struct allowing us to avoid problems with the st_*time macros */
typedef struct {
time_t tv_sec;
} stat_beos_time;
struct stat_beos {
dev_t st_dev; /* device ID that this file resides on */
ino_t st_ino; /* this file's serial inode ID */
mode_t st_mode; /* file mode (rwx for user, group, etc) */
nlink_t st_nlink; /* number of hard links to this file */
uid_t st_uid; /* user ID of the owner of this file */
gid_t st_gid; /* group ID of the owner of this file */
off_t st_size; /* size in bytes of this file */
dev_t st_rdev; /* device type (not used) */
blksize_t st_blksize; /* preferred block size for I/O */
stat_beos_time st_atim; /* last access time */
stat_beos_time st_mtim; /* last modification time */
stat_beos_time st_ctim; /* last change time, not creation time */
stat_beos_time st_crtim; /* creation time */
};
#ifdef __cplusplus
extern "C" {
#endif
extern void convert_to_stat_beos(const struct stat* stat,
struct stat_beos* beosStat);
extern void convert_from_stat_beos(const struct stat_beos* beosStat,
struct stat* stat);
#ifdef __cplusplus
}
#endif
#endif /* _COMPAT_SYS_STAT_H_ */

View File

@ -7,6 +7,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <time.h>
struct stat { struct stat {
@ -19,14 +20,21 @@ struct stat {
off_t st_size; /* size in bytes of this file */ off_t st_size; /* size in bytes of this file */
dev_t st_rdev; /* device type (not used) */ dev_t st_rdev; /* device type (not used) */
blksize_t st_blksize; /* preferred block size for I/O */ blksize_t st_blksize; /* preferred block size for I/O */
time_t st_atime; /* last access time */ struct timespec st_atim; /* last access time */
time_t st_mtime; /* last modification time */ struct timespec st_mtim; /* last modification time */
time_t st_ctime; /* last change time, not creation time */ struct timespec st_ctim; /* last change time, not creation time */
time_t st_crtime; /* creation time */ struct timespec st_crtim; /* creation time */
unsigned int st_type; /* attribute/index type */ unsigned int st_type; /* attribute/index type */
blkcnt_t st_blocks; /* number of blocks allocated for object */ blkcnt_t st_blocks; /* number of blocks allocated for object */
}; };
/* source compatibility with old stat structure */
#define st_atime st_atim.tv_sec
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
#define st_crtime st_crtim.tv_sec
/* extended file types */ /* extended file types */
#define S_ATTR_DIR 01000000000 /* attribute directory */ #define S_ATTR_DIR 01000000000 /* attribute directory */
#define S_ATTR 02000000000 /* attribute */ #define S_ATTR 02000000000 /* attribute */

View File

@ -10,6 +10,12 @@
#define BEOS_FS_API_VERSION 2 #define BEOS_FS_API_VERSION 2
/* helper struct allowing us to avoid problems with the st_*time macros */
typedef struct {
time_t tv_sec;
} stat_beos_time;
// BeOS structures // BeOS structures
typedef struct beos_iovec { typedef struct beos_iovec {
@ -36,10 +42,10 @@ struct beos_stat {
off_t st_size; off_t st_size;
dev_t st_rdev; dev_t st_rdev;
size_t st_blksize; size_t st_blksize;
time_t st_atime; stat_beos_time st_atim;
time_t st_mtime; stat_beos_time st_mtim;
time_t st_ctime; stat_beos_time st_ctim;
time_t st_crtime; stat_beos_time st_crtim;
}; };
struct beos_fs_info { struct beos_fs_info {
@ -161,7 +167,7 @@ typedef int beos_op_read_indexdir(void *ns, void *cookie, long *num,
typedef int beos_op_create_index(void *ns, const char *name, int type, typedef int beos_op_create_index(void *ns, const char *name, int type,
int flags); int flags);
typedef int beos_op_remove_index(void *ns, const char *name); typedef int beos_op_remove_index(void *ns, const char *name);
typedef int beos_op_rename_index(void *ns, const char *oldname, typedef int beos_op_rename_index(void *ns, const char *oldname,
const char *newname); const char *newname);
typedef int beos_op_stat_index(void *ns, const char *name, typedef int beos_op_stat_index(void *ns, const char *name,
struct beos_index_info *buf); struct beos_index_info *buf);

View File

@ -14,6 +14,8 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <compat/sys/stat.h>
DirectoryRefFilter::DirectoryRefFilter() DirectoryRefFilter::DirectoryRefFilter()
{ {
@ -21,8 +23,8 @@ DirectoryRefFilter::DirectoryRefFilter()
bool bool
DirectoryRefFilter::Filter(const entry_ref *ref, BNode* node, struct stat *st, DirectoryRefFilter::Filter(const entry_ref *ref, BNode* node,
const char *filetype) struct stat_beos *st, const char *filetype)
{ {
if (S_ISDIR(st->st_mode)) if (S_ISDIR(st->st_mode))
return true; return true;

View File

@ -19,7 +19,7 @@ const uint32 MSG_DIRECTORY = 'mDIR';
class DirectoryRefFilter : public BRefFilter { class DirectoryRefFilter : public BRefFilter {
public: public:
DirectoryRefFilter(); DirectoryRefFilter();
bool Filter(const entry_ref *ref, BNode* node, struct stat *st, bool Filter(const entry_ref *ref, BNode* node, struct stat_beos *st,
const char *filetype); const char *filetype);
}; };

View File

@ -13,6 +13,8 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <compat/sys/stat.h>
ExpanderRule::ExpanderRule(BString mimetype, BString filenameExtension, ExpanderRule::ExpanderRule(BString mimetype, BString filenameExtension,
BString listingCmd, BString expandCmd) BString listingCmd, BString expandCmd)
@ -127,7 +129,7 @@ ExpanderRules::MatchingRule(BString &fileName, const char *filetype)
if (rule->MimeType().IsValid() && rule->MimeType() == filetype) if (rule->MimeType().IsValid() && rule->MimeType() == filetype)
return rule; return rule;
int32 extPosition = fileName.FindLast(rule->FilenameExtension()); int32 extPosition = fileName.FindLast(rule->FilenameExtension());
if (extPosition != -1 if (extPosition != -1
&& extPosition == (length - rule->FilenameExtension().Length())) && extPosition == (length - rule->FilenameExtension().Length()))
return rule; return rule;
} }
@ -156,7 +158,7 @@ RuleRefFilter::RuleRefFilter(ExpanderRules &rules)
bool bool
RuleRefFilter::Filter(const entry_ref *ref, BNode* node, struct stat *st, RuleRefFilter::Filter(const entry_ref *ref, BNode* node, struct stat_beos *st,
const char *filetype) const char *filetype)
{ {
if (node->IsDirectory() || node->IsSymLink()) if (node->IsDirectory() || node->IsSymLink())

View File

@ -46,7 +46,7 @@ class ExpanderRules {
class RuleRefFilter : public BRefFilter { class RuleRefFilter : public BRefFilter {
public: public:
RuleRefFilter(ExpanderRules &rules); RuleRefFilter(ExpanderRules &rules);
bool Filter(const entry_ref *ref, BNode* node, struct stat *st, bool Filter(const entry_ref *ref, BNode* node, struct stat_beos *st,
const char *filetype); const char *filetype);
protected: protected:
ExpanderRules &fRules; ExpanderRules &fRules;

View File

@ -66,8 +66,8 @@ enum {
class DirectoryRefFilter : public BRefFilter { class DirectoryRefFilter : public BRefFilter {
public: public:
virtual ~DirectoryRefFilter() {} virtual ~DirectoryRefFilter() {}
bool Filter(const entry_ref* ref, BNode* node, struct stat* stat, bool Filter(const entry_ref* ref, BNode* node,
const char* filetype) struct stat_beos* stat, const char* filetype)
{ {
return node->IsDirectory(); return node->IsDirectory();
} }
@ -501,7 +501,7 @@ ScreenshotWindow::_UpdatePreviewPanel()
{ {
float height = 150.0f; float height = 150.0f;
float width = (fScreenshot->Bounds().Width() / float width = (fScreenshot->Bounds().Width() /
fScreenshot->Bounds().Height()) * height; fScreenshot->Bounds().Height()) * height;
// to prevent a preview way too wide // to prevent a preview way too wide
@ -517,7 +517,7 @@ ScreenshotWindow::_UpdatePreviewPanel()
fPreview->ClearViewBitmap(); fPreview->ClearViewBitmap();
fPreview->SetViewBitmap(fScreenshot, fScreenshot->Bounds(), fPreview->SetViewBitmap(fScreenshot, fScreenshot->Bounds(),
fPreview->Bounds(), B_FOLLOW_ALL, 0); fPreview->Bounds(), B_FOLLOW_ALL, 0);
BCardLayout* layout = dynamic_cast<BCardLayout*> (GetLayout()); BCardLayout* layout = dynamic_cast<BCardLayout*> (GetLayout());
if (layout) if (layout)
layout->SetVisibleItem(1L); layout->SetVisibleItem(1L);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008, Haiku Inc. * Copyright 2002-2009, Haiku Inc.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@ -11,7 +11,10 @@
#include "storage_support.h" #include "storage_support.h"
#include <syscalls.h> #include <fcntl.h>
#include <string.h>
#include <compat/sys/stat.h>
#include <Directory.h> #include <Directory.h>
#include <Entry.h> #include <Entry.h>
@ -20,8 +23,7 @@
#include <Path.h> #include <Path.h>
#include <SymLink.h> #include <SymLink.h>
#include <fcntl.h> #include <syscalls.h>
#include <string.h>
extern mode_t __gUmask; extern mode_t __gUmask;
@ -509,7 +511,7 @@ BDirectory::Contains(const BEntry *entry, int32 nodeFlags) const
return false; return false;
uint32 dirLen = strlen(dirPath.Path()); uint32 dirLen = strlen(dirPath.Path());
if (!strncmp(dirPath.Path(), entryPath.Path(), dirLen)) { if (!strncmp(dirPath.Path(), entryPath.Path(), dirLen)) {
// if the paths are identical, return a match to stay consistent with // if the paths are identical, return a match to stay consistent with
// BeOS behavior. // BeOS behavior.
@ -520,7 +522,8 @@ BDirectory::Contains(const BEntry *entry, int32 nodeFlags) const
} }
/*! \brief Returns the stat structure of the entry referred to by the supplied /*! \fn status_t BDirectory::GetStatFor(const char *path, struct stat *st) const
\brief Returns the stat structure of the entry referred to by the supplied
path name. path name.
\param path the entry's path name. May be relative to this directory or \param path the entry's path name. May be relative to this directory or
absolute, or \c NULL to get the directories stat info. absolute, or \c NULL to get the directories stat info.
@ -538,21 +541,7 @@ BDirectory::Contains(const BEntry *entry, int32 nodeFlags) const
- \c B_NO_MORE_FDS: The application has run out of file descriptors. - \c B_NO_MORE_FDS: The application has run out of file descriptors.
- \c B_NOT_A_DIRECTORY: \a path includes a non-directory. - \c B_NOT_A_DIRECTORY: \a path includes a non-directory.
*/ */
status_t // Implemented as BDirectory::_GetStatFor().
BDirectory::GetStatFor(const char *path, struct stat *st) const
{
if (!st)
return B_BAD_VALUE;
if (InitCheck() != B_OK)
return B_NO_INIT;
if (path != NULL) {
if (path[0] == '\0')
return B_ENTRY_NOT_FOUND;
return _kern_read_stat(fDirFd, path, false, st, sizeof(struct stat));
}
return GetStat(st);
}
/*! \brief Returns the BDirectory's next entry as a BEntry. /*! \brief Returns the BDirectory's next entry as a BEntry.
@ -866,6 +855,36 @@ BDirectory::operator=(const BDirectory &dir)
} }
status_t
BDirectory::_GetStatFor(const char *path, struct stat *st) const
{
if (!st)
return B_BAD_VALUE;
if (InitCheck() != B_OK)
return B_NO_INIT;
if (path != NULL) {
if (path[0] == '\0')
return B_ENTRY_NOT_FOUND;
return _kern_read_stat(fDirFd, path, false, st, sizeof(struct stat));
}
return GetStat(st);
}
status_t
BDirectory::_GetStatFor(const char *path, struct stat_beos *st) const
{
struct stat newStat;
status_t error = _GetStatFor(path, &newStat);
if (error != B_OK)
return error;
convert_to_stat_beos(&newStat, st);
return B_OK;
}
// FBC // FBC
void BDirectory::_ErectorDirectory1() {} void BDirectory::_ErectorDirectory1() {}
void BDirectory::_ErectorDirectory2() {} void BDirectory::_ErectorDirectory2() {}
@ -969,3 +988,28 @@ create_directory(const char *path, mode_t mode)
return B_OK; return B_OK;
} }
// #pragma mark - symbol versions
#if __GNUC__ == 2 // gcc 2
// BeOS compatible GetStatFor()
B_DEFINE_SYMBOL_VERSION("_GetStatFor__C10BDirectoryPCcP9stat_beos",
"GetStatFor__C10BDirectoryPCcP4stat@LIBBE_BASE");
// Haiku GetStatFor()
B_DEFINE_SYMBOL_VERSION("_GetStatFor__C10BDirectoryPCcP4stat",
"GetStatFor__C10BDirectoryPCcP4stat@@LIBBE_1_ALPHA1");
#else // gcc 4
// BeOS compatible GetStatFor()
B_DEFINE_SYMBOL_VERSION("_ZNK10BDirectory11_GetStatForEPKcP9stat_beos",
"_ZNK10BDirectory10GetStatForEPKcP4stat@LIBBE_BASE");
// Haiku GetStatFor()
B_DEFINE_SYMBOL_VERSION("_ZNK10BDirectory11_GetStatForEPKcP4stat",
"_ZNK10BDirectory10GetStatForEPKcP4stat@@LIBBE_1_ALPHA1");
#endif // gcc 4

View File

@ -13,14 +13,17 @@
*/ */
#include <Statable.h> #include <Statable.h>
#include <sys/stat.h>
#include <compat/sys/stat.h>
#include <Node.h> #include <Node.h>
#include <NodeMonitor.h> #include <NodeMonitor.h>
#include <Volume.h> #include <Volume.h>
#include <sys/stat.h>
#if __GNUC__ > 2
#if __GNUC__ > 3
BStatable::~BStatable() BStatable::~BStatable()
{ {
} }
@ -37,6 +40,22 @@ BStatable::~BStatable()
- \c B_NOT_ALLOWED: Read only node or volume. - \c B_NOT_ALLOWED: Read only node or volume.
*/ */
/*! \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. /*! \brief Returns if the current node is a file.
\return \c true, if the BNode is properly initialized and is a file, \return \c true, if the BNode is properly initialized and is a file,
\c false otherwise. \c false otherwise.
@ -47,7 +66,7 @@ BStatable::IsFile() const
struct stat statData; struct stat statData;
if (GetStat(&statData) == B_OK) if (GetStat(&statData) == B_OK)
return S_ISREG(statData.st_mode); return S_ISREG(statData.st_mode);
else else
return false; return false;
} }
@ -61,7 +80,7 @@ BStatable::IsDirectory() const
struct stat statData; struct stat statData;
if (GetStat(&statData) == B_OK) if (GetStat(&statData) == B_OK)
return S_ISDIR(statData.st_mode); return S_ISDIR(statData.st_mode);
else else
return false; return false;
} }
@ -75,15 +94,15 @@ BStatable::IsSymLink() const
struct stat statData; struct stat statData;
if (GetStat(&statData) == B_OK) if (GetStat(&statData) == B_OK)
return S_ISLNK(statData.st_mode); return S_ISLNK(statData.st_mode);
else else
return false; return false;
} }
/*! \brief Returns a node_ref for the current node. /*! \brief Returns a node_ref for the current node.
\param ref the node_ref structure to be filled in \param ref the node_ref structure to be filled in
\see GetStat() for return codes \see GetStat() for return codes
*/ */
status_t status_t
BStatable::GetNodeRef(node_ref *ref) const BStatable::GetNodeRef(node_ref *ref) const
{ {
status_t error = (ref ? B_OK : B_BAD_VALUE); status_t error = (ref ? B_OK : B_BAD_VALUE);
@ -96,12 +115,12 @@ BStatable::GetNodeRef(node_ref *ref) const
} }
return error; return error;
} }
/*! \brief Returns the owner of the node. /*! \brief Returns the owner of the node.
\param owner a pointer to a uid_t variable to be set to the result \param owner a pointer to a uid_t variable to be set to the result
\see GetStat() for return codes \see GetStat() for return codes
*/ */
status_t status_t
BStatable::GetOwner(uid_t *owner) const BStatable::GetOwner(uid_t *owner) const
{ {
status_t error = (owner ? B_OK : B_BAD_VALUE); status_t error = (owner ? B_OK : B_BAD_VALUE);
@ -117,14 +136,14 @@ BStatable::GetOwner(uid_t *owner) const
\param owner the new owner \param owner the new owner
\see GetStat() for return codes \see GetStat() for return codes
*/ */
status_t status_t
BStatable::SetOwner(uid_t owner) BStatable::SetOwner(uid_t owner)
{ {
struct stat statData; struct stat statData;
statData.st_uid = owner; statData.st_uid = owner;
return set_stat(statData, B_STAT_UID); return set_stat(statData, B_STAT_UID);
} }
/*! \brief Returns the group owner of the node. /*! \brief Returns the group owner of the node.
\param group a pointer to a gid_t variable to be set to the result \param group a pointer to a gid_t variable to be set to the result
\see GetStat() for return codes \see GetStat() for return codes
@ -152,7 +171,7 @@ BStatable::SetGroup(gid_t group)
statData.st_gid = group; statData.st_gid = group;
return set_stat(statData, B_STAT_GID); return set_stat(statData, B_STAT_GID);
} }
/*! \brief Returns the permissions of the node. /*! \brief Returns the permissions of the node.
\param perms a pointer to a mode_t variable to be set to the result \param perms a pointer to a mode_t variable to be set to the result
\see GetStat() for return codes \see GetStat() for return codes
@ -302,7 +321,18 @@ BStatable::GetVolume(BVolume *vol) const
return error; return error;
} }
void BStatable::_OhSoStatable1() {}
// _OhSoStatable1() -> GetStat()
extern "C" status_t
#if __GNUC__ == 2
_OhSoStatable1__9BStatable(const BStatable *self, struct stat *st)
#else
_ZN9BStatable14_OhSoStatable1Ev(const BStatable *self, struct stat *st)
#endif
{
return self->GetStat(st);
}
void BStatable::_OhSoStatable2() {} void BStatable::_OhSoStatable2() {}
void BStatable::_OhSoStatable3() {} void BStatable::_OhSoStatable3() {}

View File

@ -32,20 +32,22 @@ names are registered trademarks or trademarks of their respective holders.
All rights reserved. All rights reserved.
*/ */
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <float.h> #include <float.h>
#include <fs_attr.h>
#include <fs_info.h>
#include <ctype.h>
#include <stdlib.h>
#include <map> #include <map>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <compat/sys/stat.h>
#include <Alert.h> #include <Alert.h>
#include <Application.h> #include <Application.h>
#include <Clipboard.h> #include <Clipboard.h>
#include <Debug.h> #include <Debug.h>
#include <Dragger.h> #include <Dragger.h>
#include <fs_attr.h>
#include <fs_info.h>
#include <Screen.h> #include <Screen.h>
#include <Query.h> #include <Query.h>
#include <List.h> #include <List.h>
@ -140,7 +142,7 @@ const unsigned char kCopyCursor[] = { 16, 1, 1, 1,
0x00, 0x00, 0x70, 0x00, 0x78, 0x00, 0x78, 0x00, 0x00, 0x00, 0x70, 0x00, 0x78, 0x00, 0x78, 0x00,
0x3f, 0xc0, 0x3f, 0xf8, 0x1f, 0xfc, 0x1f, 0xfe, 0x3f, 0xc0, 0x3f, 0xf8, 0x1f, 0xfc, 0x1f, 0xfe,
0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0x7f, 0xfe,
0x1f, 0xfe, 0x07, 0xfe, 0x03, 0xf8, 0x00, 0x00 0x1f, 0xfe, 0x07, 0xfe, 0x03, 0xf8, 0x00, 0x00
}; };
const char *kNoCopyToTrashStr = "Sorry, you can't copy items to the Trash."; const char *kNoCopyToTrashStr = "Sorry, you can't copy items to the Trash.";
@ -177,7 +179,7 @@ AddPosesResult::ReleaseModels(void)
static BPose * static BPose *
BSearch(PoseList *table, const BPose* key, BPoseView *view, BSearch(PoseList *table, const BPose* key, BPoseView *view,
int (*cmp)(const BPose *, const BPose *, BPoseView *), int (*cmp)(const BPose *, const BPose *, BPoseView *),
bool returnClosest = true); bool returnClosest = true);
static int static int
@ -647,7 +649,7 @@ BPoseView::SaveState(AttributeStreamNode *node)
node->Write(viewStateAttr, viewStateAttrForeign, B_RAW_TYPE, node->Write(viewStateAttr, viewStateAttrForeign, B_RAW_TYPE,
stream.Position(), stream.Buffer()); stream.Position(), stream.Buffer());
fStateNeedsSaving = false; fStateNeedsSaving = false;
} }
@ -874,7 +876,7 @@ void
BPoseView::ScrollTo(BPoint point) BPoseView::ScrollTo(BPoint point)
{ {
_inherited::ScrollTo(point); _inherited::ScrollTo(point);
//keep the view state in sync. //keep the view state in sync.
if (ViewMode() == kListMode) if (ViewMode() == kListMode)
fViewState->SetListOrigin(LeftTop()); fViewState->SetListOrigin(LeftTop());
@ -1385,7 +1387,7 @@ BPoseView::AddPosesTask(void *castToParams)
BMessage finishedSending(kAddPosesCompleted); BMessage finishedSending(kAddPosesCompleted);
lock.Target().SendMessage(&finishedSending); lock.Target().SendMessage(&finishedSending);
} catch (failToLock) { } catch (failToLock) {
// we are here because the window got closed or otherwise failed to // we are here because the window got closed or otherwise failed to
// lock // lock
@ -1632,7 +1634,7 @@ BPoseView::CreatePoses(Model **models, PoseInfo *poseInfoArray, int32 count,
// pose adopts model and deletes it when done // pose adopts model and deletes it when done
if (fInsertedNodes.find(*(model->NodeRef())) != fInsertedNodes.end() if (fInsertedNodes.find(*(model->NodeRef())) != fInsertedNodes.end()
|| FindZombie(model->NodeRef())) { || FindZombie(model->NodeRef())) {
watch_node(model->NodeRef(), B_STOP_WATCHING, this); watch_node(model->NodeRef(), B_STOP_WATCHING, this);
delete model; delete model;
@ -1793,7 +1795,7 @@ BPoseView::CreatePoses(Model **models, PoseInfo *poseInfoArray, int32 count,
model->CloseNode(); model->CloseNode();
} }
be_clipboard->Unlock(); be_clipboard->Unlock();
FinishPendingScroll(listViewScrollBy, viewBounds); FinishPendingScroll(listViewScrollBy, viewBounds);
@ -1820,8 +1822,14 @@ BPoseView::ShouldShowPose(const Model *model, const PoseInfo *poseInfo)
return false; return false;
// check filter before adding item // check filter before adding item
return !fRefFilter || fRefFilter->Filter(model->EntryRef(), model->Node(), if (!fRefFilter)
const_cast<StatStruct *>(model->StatBuf()), model->MimeType()); return true;
struct stat_beos statBeOS;
convert_to_stat_beos(model->StatBuf(), &statBeOS);
return fRefFilter->Filter(model->EntryRef(), model->Node(), &statBeOS,
model->MimeType());
} }
@ -2441,7 +2449,7 @@ BPoseView::RemoveColumn(BColumn *columnToRemove, bool runAlert)
// make sure last column is not removed // make sure last column is not removed
if (CountColumns() == 1) { if (CountColumns() == 1) {
if (runAlert) { if (runAlert) {
BAlert *alert = new BAlert("", BAlert *alert = new BAlert("",
"You must have at least one Attribute showing.", "You must have at least one Attribute showing.",
"Cancel", 0, 0, B_WIDTH_AS_USUAL, B_WARNING_ALERT); "Cancel", 0, 0, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
alert->SetShortcut(0, B_ESCAPE); alert->SetShortcut(0, B_ESCAPE);
@ -4028,7 +4036,7 @@ bool
BPoseView::HandleMessageDropped(BMessage *message) BPoseView::HandleMessageDropped(BMessage *message)
{ {
ASSERT(message->WasDropped()); ASSERT(message->WasDropped());
// reset system cursor in case it was altered by drag and drop // reset system cursor in case it was altered by drag and drop
SetViewCursor(B_CURSOR_SYSTEM_DEFAULT); SetViewCursor(B_CURSOR_SYSTEM_DEFAULT);
fCursorCheck = false; fCursorCheck = false;
@ -4550,7 +4558,7 @@ void
BPoseView::MoveSelectionInto(Model *destFolder, BContainerWindow *srcWindow, BPoseView::MoveSelectionInto(Model *destFolder, BContainerWindow *srcWindow,
BContainerWindow *destWindow, uint32 buttons, BPoint loc, bool forceCopy, BContainerWindow *destWindow, uint32 buttons, BPoint loc, bool forceCopy,
bool forceMove, bool createLink, bool relativeLink, BPoint clickPt, bool dropOnGrid) bool forceMove, bool createLink, bool relativeLink, BPoint clickPt, bool dropOnGrid)
{ {
AutoLock<BWindow> lock(srcWindow); AutoLock<BWindow> lock(srcWindow);
if (!lock) if (!lock)
return; return;
@ -4593,11 +4601,11 @@ BPoseView::MoveSelectionInto(Model *destFolder, BContainerWindow *srcWindow,
targetView->DuplicateSelection(&clickPt, &loc); targetView->DuplicateSelection(&clickPt, &loc);
return; return;
} }
if (targetView->ViewMode() == kListMode) // can't move in list view if (targetView->ViewMode() == kListMode) // can't move in list view
return; return;
BPoint delta = loc - clickPt; BPoint delta = loc - clickPt;
int32 count = targetView->fSelectionList->CountItems(); int32 count = targetView->fSelectionList->CountItems();
for (int32 index = 0; index < count; index++) { for (int32 index = 0; index < count; index++) {
BPose *pose = targetView->fSelectionList->ItemAt(index); BPose *pose = targetView->fSelectionList->ItemAt(index);
@ -4691,7 +4699,7 @@ BPoseView::MoveSelectionInto(Model *destFolder, BContainerWindow *srcWindow,
if (!CheckDevicesEqual(srcList->ItemAt(0), destFolder)) if (!CheckDevicesEqual(srcList->ItemAt(0), destFolder))
moveMode = kCopySelectionTo; moveMode = kCopySelectionTo;
} }
FSMoveToFolder(srcList, destEntry, moveMode, pointList); FSMoveToFolder(srcList, destEntry, moveMode, pointList);
return; return;
} }
@ -4719,7 +4727,7 @@ BPoseView::MoveSelectionTo(BPoint dropPt, BPoint clickPt,
uint32 buttons = (uint32)window->CurrentMessage()->FindInt32("buttons"); uint32 buttons = (uint32)window->CurrentMessage()->FindInt32("buttons");
bool pinToGrid = (modifiers() & B_COMMAND_KEY) != 0; bool pinToGrid = (modifiers() & B_COMMAND_KEY) != 0;
MoveSelectionInto(TargetModel(), srcWindow, window, buttons, dropPt, MoveSelectionInto(TargetModel(), srcWindow, window, buttons, dropPt,
false, false, false, false, clickPt, pinToGrid); false, false, false, false, clickPt, pinToGrid);
} }
@ -5535,7 +5543,7 @@ CheckVolumeReadOnly(const entry_ref *ref)
alert->Go(); alert->Go();
return false; return false;
} }
return true; return true;
} }
@ -6602,7 +6610,7 @@ BPoseView::DragSelectedPoses(const BPose *pose, BPoint clickPoint)
if (strcasecmp(type, kPlainTextMimeType) == 0) { if (strcasecmp(type, kPlainTextMimeType) == 0) {
// got a text file // got a text file
file.Seek(0, SEEK_SET); file.Seek(0, SEEK_SET);
off_t size = 0; off_t size = 0;
file.GetSize(&size); file.GetSize(&size);
@ -7303,7 +7311,7 @@ bool
BPoseView::DeletePose(const node_ref *itemNode, BPose *pose, int32 index) BPoseView::DeletePose(const node_ref *itemNode, BPose *pose, int32 index)
{ {
watch_node(itemNode, B_STOP_WATCHING, this); watch_node(itemNode, B_STOP_WATCHING, this);
if (!pose) if (!pose)
pose = fPoseList->FindPose(itemNode, &index); pose = fPoseList->FindPose(itemNode, &index);
@ -7640,13 +7648,13 @@ BPoseView::SwitchDir(const entry_ref *newDirRef, AttributeStreamNode *node)
// Restore state, might fail if the state has never been saved for this node // Restore state, might fail if the state has never been saved for this node
uint32 oldMode = ViewMode(); uint32 oldMode = ViewMode();
bool viewStateRestored = false; bool viewStateRestored = false;
if (node) { if (node) {
BViewState *previousState = fViewState; BViewState *previousState = fViewState;
RestoreState(node); RestoreState(node);
viewStateRestored = (fViewState != previousState); viewStateRestored = (fViewState != previousState);
} }
if (viewStateRestored) { if (viewStateRestored) {
// Make sure the title view reset its items // Make sure the title view reset its items
fTitleView->Reset(); fTitleView->Reset();
@ -7708,7 +7716,7 @@ BPoseView::SwitchDir(const entry_ref *newDirRef, AttributeStreamNode *node)
else AddPoses(TargetModel()); else AddPoses(TargetModel());
TargetModel()->CloseNode(); TargetModel()->CloseNode();
Invalidate(); Invalidate();
fLastKeyTime = 0; fLastKeyTime = 0;
} }
@ -7818,7 +7826,7 @@ BPoseView::SetDefaultPrinter()
BMessenger tracker(kTrackerSignature); BMessenger tracker(kTrackerSignature);
if (!tracker.IsValid()) { if (!tracker.IsValid()) {
BAlert *alert = new BAlert("", "The Tracker must be running " BAlert *alert = new BAlert("", "The Tracker must be running "
"to see set the default printer.", "Cancel", NULL, "to see set the default printer.", "Cancel", NULL,
NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT); NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
alert->SetShortcut(0, B_ESCAPE); alert->SetShortcut(0, B_ESCAPE);
alert->Go(); alert->Go();
@ -8180,7 +8188,7 @@ BPoseView::UpdateScrollRange()
// set proportions for bars // set proportions for bars
BRect totalExtent(extent | bounds); BRect totalExtent(extent | bounds);
if (fHScrollBar && totalExtent.Width() != 0.0) { if (fHScrollBar && totalExtent.Width() != 0.0) {
float proportion = bounds.Width() / totalExtent.Width(); float proportion = bounds.Width() / totalExtent.Width();
if (fHScrollBar->Proportion() != proportion) if (fHScrollBar->Proportion() != proportion)
@ -8880,7 +8888,7 @@ BPoseView::UpdateDropTarget(BPoint mouseLoc, const BMessage *dragMessage,
|| (trackingContextMenu && !targetPose)) || (trackingContextMenu && !targetPose))
// no change // no change
return false; return false;
fCursorCheck = true; fCursorCheck = true;
if (fDropTarget && !DragSelectionContains(fDropTarget, dragMessage)) if (fDropTarget && !DragSelectionContains(fDropTarget, dragMessage))
HiliteDropTarget(false); HiliteDropTarget(false);
@ -8905,23 +8913,23 @@ BPoseView::UpdateDropTarget(BPoint mouseLoc, const BMessage *dragMessage,
fDropTarget = NULL; fDropTarget = NULL;
fCursorCheck = false; fCursorCheck = false;
} }
} }
if (targetModel == NULL) if (targetModel == NULL)
targetModel = TargetModel(); targetModel = TargetModel();
entry_ref srcRef; entry_ref srcRef;
if (targetModel->IsDirectory() && dragMessage->HasRef("refs") if (targetModel->IsDirectory() && dragMessage->HasRef("refs")
&& dragMessage->FindRef("refs", &srcRef) == B_OK) { && dragMessage->FindRef("refs", &srcRef) == B_OK) {
Model srcModel (&srcRef); Model srcModel (&srcRef);
if (!CheckDevicesEqual(&srcRef, targetModel) if (!CheckDevicesEqual(&srcRef, targetModel)
&& !srcModel.IsVolume() && !srcModel.IsVolume()
&& !srcModel.IsRoot()) { && !srcModel.IsRoot()) {
BCursor copyCursor(kCopyCursor); BCursor copyCursor(kCopyCursor);
SetViewCursor(&copyCursor); SetViewCursor(&copyCursor);
return true; return true;
} }
} }
SetViewCursor(B_CURSOR_SYSTEM_DEFAULT); SetViewCursor(B_CURSOR_SYSTEM_DEFAULT);
return true; return true;
} }
@ -9066,7 +9074,7 @@ BPoseView::HiliteDropTarget(bool hiliteState)
return; return;
} }
// don't unselect the fAlreadySelectedDropTarget // don't unselect the fAlreadySelectedDropTarget
if ((fAlreadySelectedDropTarget == fDropTarget) && !hiliteState) { if ((fAlreadySelectedDropTarget == fDropTarget) && !hiliteState) {
fAlreadySelectedDropTarget = NULL; fAlreadySelectedDropTarget = NULL;
return; return;

View File

@ -162,7 +162,7 @@ CustomRefFilter::CustomRefFilter(bool imageFiltering)
bool bool
CustomRefFilter::Filter(const entry_ref *ref, BNode* node, CustomRefFilter::Filter(const entry_ref *ref, BNode* node,
struct stat *stat, const char *filetype) struct stat_beos *stat, const char *filetype)
{ {
if (!fImageFiltering) if (!fImageFiltering)
return node->IsDirectory(); return node->IsDirectory();

View File

@ -21,7 +21,7 @@ class CustomRefFilter : public BRefFilter {
CustomRefFilter(bool imageFiltering); CustomRefFilter(bool imageFiltering);
virtual ~CustomRefFilter() {}; virtual ~CustomRefFilter() {};
bool Filter(const entry_ref *ref, BNode* node, struct stat *st, bool Filter(const entry_ref *ref, BNode* node, struct stat_beos *st,
const char *filetype); const char *filetype);
protected: protected:

View File

@ -1,5 +1,7 @@
SubDir HAIKU_TOP src system kernel lib ; SubDir HAIKU_TOP src system kernel lib ;
UsePrivateHeaders shared ;
# kernel libroot os files # kernel libroot os files
KernelMergeObject kernel_os_main.o : KernelMergeObject kernel_os_main.o :
@ -114,8 +116,6 @@ KernelMergeObject kernel_lib_posix.o :
# misc # misc
UsePrivateHeaders shared ;
SEARCH_SOURCE = [ FDirName $(HAIKU_TOP) src kits support ] ; SEARCH_SOURCE = [ FDirName $(HAIKU_TOP) src kits support ] ;
KernelMergeObject kernel_misc.o : KernelMergeObject kernel_misc.o :

View File

@ -1,88 +1,152 @@
/* /*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. All rights reserved.
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include <syscalls.h> #include <syscalls.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h> #include <errno.h>
#include <compat/sys/stat.h>
#define RETURN_AND_SET_ERRNO(err) \ #include <symbol_versioning.h>
if (err < 0) { \ #include <syscall_utils.h>
errno = err; \
return -1; \
} \
return err;
// BeOS compatibility // prototypes for the compiler
#define BEOS_STAT_SIZE 60 int _stat_current(const char* path, struct stat* stat);
int _fstat_current(int fd, struct stat* stat);
int _lstat_current(const char* path, struct stat* stat);
int _stat_beos(const char* path, struct stat_beos* beosStat);
int _fstat_beos(int fd, struct stat_beos* beosStat);
int _lstat_beos(const char* path, struct stat_beos* beosStat);
int int
stat(const char *path, struct stat *stat) _stat_current(const char* path, struct stat* stat)
{ {
int status = _kern_read_stat(-1, path, true, stat, BEOS_STAT_SIZE/*sizeof(struct stat)*/); int status = _kern_read_stat(-1, path, true, stat, sizeof(struct stat));
RETURN_AND_SET_ERRNO(status); RETURN_AND_SET_ERRNO(status);
} }
int int
fstat(int fd, struct stat *stat) _fstat_current(int fd, struct stat* stat)
{ {
int status = _kern_read_stat(fd, NULL, false, stat, BEOS_STAT_SIZE/*sizeof(struct stat)*/); int status = _kern_read_stat(fd, NULL, false, stat, sizeof(struct stat));
RETURN_AND_SET_ERRNO(status); RETURN_AND_SET_ERRNO(status);
} }
int int
lstat(const char *path, struct stat *stat) _lstat_current(const char* path, struct stat* stat)
{ {
int status = _kern_read_stat(-1, path, false, stat, BEOS_STAT_SIZE/*sizeof(struct stat)*/); int status = _kern_read_stat(-1, path, false, stat, sizeof(struct stat));
RETURN_AND_SET_ERRNO(status); RETURN_AND_SET_ERRNO(status);
} }
// #pragma mark - BeOS compatibility // #pragma mark - BeOS compatibility
#ifndef _KERNEL_MODE void
convert_to_stat_beos(const struct stat* stat, struct stat_beos* beosStat)
int __be_stat(const char *path, struct stat *stat);
int __be_fstat(int fd, struct stat *stat);
int __be_lstat(const char *path, struct stat *stat);
int
__be_stat(const char *path, struct stat *stat)
{ {
int status = _kern_read_stat(-1, path, true, stat, BEOS_STAT_SIZE); if (stat == NULL || beosStat == NULL)
return;
RETURN_AND_SET_ERRNO(status); beosStat->st_dev = stat->st_dev;
beosStat->st_ino = stat->st_ino;
beosStat->st_mode = stat->st_mode;
beosStat->st_nlink = stat->st_nlink;
beosStat->st_uid = stat->st_uid;
beosStat->st_gid = stat->st_gid;
beosStat->st_size = stat->st_size;
beosStat->st_rdev = stat->st_rdev;
beosStat->st_blksize = stat->st_blksize;
beosStat->st_atime = stat->st_atime;
beosStat->st_mtime = stat->st_mtime;
beosStat->st_ctime = stat->st_ctime;
beosStat->st_crtime = stat->st_crtime;
}
void
convert_from_stat_beos(const struct stat_beos* beosStat, struct stat* stat)
{
if (stat == NULL || beosStat == NULL)
return;
stat->st_dev = beosStat->st_dev;
stat->st_ino = beosStat->st_ino;
stat->st_mode = beosStat->st_mode;
stat->st_nlink = beosStat->st_nlink;
stat->st_uid = beosStat->st_uid;
stat->st_gid = beosStat->st_gid;
stat->st_size = beosStat->st_size;
stat->st_rdev = beosStat->st_rdev;
stat->st_blksize = beosStat->st_blksize;
stat->st_atim.tv_sec = beosStat->st_atime;
stat->st_atim.tv_nsec = 0;
stat->st_mtim.tv_sec = beosStat->st_mtime;
stat->st_mtim.tv_nsec = 0;
stat->st_ctim.tv_sec = beosStat->st_ctime;
stat->st_ctim.tv_nsec = 0;
stat->st_crtim.tv_sec = beosStat->st_crtime;
stat->st_crtim.tv_nsec = 0;
stat->st_type = 0;
stat->st_blocks = 0;
} }
int int
__be_fstat(int fd, struct stat *stat) _stat_beos(const char* path, struct stat_beos* beosStat)
{ {
int status = _kern_read_stat(fd, NULL, false, stat, BEOS_STAT_SIZE); struct stat stat;
if (_stat_current(path, &stat) != 0)
return -1;
RETURN_AND_SET_ERRNO(status); convert_to_stat_beos(&stat, beosStat);
return 0;
} }
int int
__be_lstat(const char *path, struct stat *stat) _fstat_beos(int fd, struct stat_beos* beosStat)
{ {
int status = _kern_read_stat(-1, path, false, stat, BEOS_STAT_SIZE); struct stat stat;
if (_fstat_current(fd, &stat) != 0)
return -1;
RETURN_AND_SET_ERRNO(status); convert_to_stat_beos(&stat, beosStat);
return 0;
} }
#endif // !_KERNEL_MODE
int
_lstat_beos(const char* path, struct stat_beos* beosStat)
{
struct stat stat;
if (_lstat_current(path, &stat) != 0)
return -1;
convert_to_stat_beos(&stat, beosStat);
return 0;
}
DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("_stat_beos", "stat@", "BASE");
DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("_fstat_beos", "fstat@", "BASE");
DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("_lstat_beos", "lstat@", "BASE");
DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("_stat_current", "stat@@", "1_ALPHA1");
DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("_fstat_current", "fstat@@", "1_ALPHA1");
DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("_lstat_current", "lstat@@", "1_ALPHA1");