* 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 <StorageDefs.h>
class BFile;
class BSymLink;
struct stat_beos;
class BDirectory : public BNode, public BEntryList {
@ -64,6 +66,9 @@ class BDirectory : public BNode, public BEntryList {
friend class BEntry;
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 _ErectorDirectory2();
virtual void _ErectorDirectory3();

View File

@ -14,6 +14,7 @@ class BMessage;
class BMessenger;
class BWindow;
struct stat;
struct stat_beos;
class BRefFilter {
@ -22,7 +23,7 @@ class BRefFilter {
virtual ~BRefFilter() {};
#endif
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,7 +11,9 @@
#include <sys/types.h>
#include <sys/stat.h>
struct node_ref;
struct stat_beos;
class BVolume;
@ -21,6 +23,11 @@ class BStatable {
virtual ~BStatable();
#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;
bool IsFile() const;
@ -55,7 +62,6 @@ class BStatable {
friend class BEntry;
friend class BNode;
virtual void _OhSoStatable1();
virtual void _OhSoStatable2();
virtual void _OhSoStatable3();
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 <time.h>
struct stat {
@ -19,14 +20,21 @@ struct stat {
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 */
time_t st_atime; /* last access time */
time_t st_mtime; /* last modification time */
time_t st_ctime; /* last change time, not creation time */
time_t st_crtime; /* creation time */
struct timespec st_atim; /* last access time */
struct timespec st_mtim; /* last modification time */
struct timespec st_ctim; /* last change time, not creation time */
struct timespec st_crtim; /* creation time */
unsigned int st_type; /* attribute/index type */
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 */
#define S_ATTR_DIR 01000000000 /* attribute directory */
#define S_ATTR 02000000000 /* attribute */

View File

@ -10,6 +10,12 @@
#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
typedef struct beos_iovec {
@ -36,10 +42,10 @@ struct beos_stat {
off_t st_size;
dev_t st_rdev;
size_t st_blksize;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
time_t st_crtime;
stat_beos_time st_atim;
stat_beos_time st_mtim;
stat_beos_time st_ctim;
stat_beos_time st_crtim;
};
struct beos_fs_info {

View File

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

View File

@ -19,7 +19,7 @@ const uint32 MSG_DIRECTORY = 'mDIR';
class DirectoryRefFilter : public BRefFilter {
public:
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);
};

View File

@ -13,6 +13,8 @@
#include <stdio.h>
#include <unistd.h>
#include <compat/sys/stat.h>
ExpanderRule::ExpanderRule(BString mimetype, BString filenameExtension,
BString listingCmd, BString expandCmd)
@ -156,7 +158,7 @@ RuleRefFilter::RuleRefFilter(ExpanderRules &rules)
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)
{
if (node->IsDirectory() || node->IsSymLink())

View File

@ -46,7 +46,7 @@ class ExpanderRules {
class RuleRefFilter : public BRefFilter {
public:
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);
protected:
ExpanderRules &fRules;

View File

@ -66,8 +66,8 @@ enum {
class DirectoryRefFilter : public BRefFilter {
public:
virtual ~DirectoryRefFilter() {}
bool Filter(const entry_ref* ref, BNode* node, struct stat* stat,
const char* filetype)
bool Filter(const entry_ref* ref, BNode* node,
struct stat_beos* stat, const char* filetype)
{
return node->IsDirectory();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2008, Haiku Inc.
* Copyright 2002-2009, Haiku Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -11,7 +11,10 @@
#include "storage_support.h"
#include <syscalls.h>
#include <fcntl.h>
#include <string.h>
#include <compat/sys/stat.h>
#include <Directory.h>
#include <Entry.h>
@ -20,8 +23,7 @@
#include <Path.h>
#include <SymLink.h>
#include <fcntl.h>
#include <string.h>
#include <syscalls.h>
extern mode_t __gUmask;
@ -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.
\param path the entry's path name. May be relative to this directory or
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_NOT_A_DIRECTORY: \a path includes a non-directory.
*/
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);
}
// Implemented as BDirectory::_GetStatFor().
/*! \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
void BDirectory::_ErectorDirectory1() {}
void BDirectory::_ErectorDirectory2() {}
@ -969,3 +988,28 @@ create_directory(const char *path, mode_t mode)
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 <sys/stat.h>
#include <compat/sys/stat.h>
#include <Node.h>
#include <NodeMonitor.h>
#include <Volume.h>
#include <sys/stat.h>
#if __GNUC__ > 3
#if __GNUC__ > 2
BStatable::~BStatable()
{
}
@ -37,6 +40,22 @@ BStatable::~BStatable()
- \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.
\return \c true, if the BNode is properly initialized and is a file,
\c false otherwise.
@ -302,7 +321,18 @@ BStatable::GetVolume(BVolume *vol) const
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::_OhSoStatable3() {}

View File

@ -32,20 +32,22 @@ names are registered trademarks or trademarks of their respective holders.
All rights reserved.
*/
#include <ctype.h>
#include <errno.h>
#include <float.h>
#include <fs_attr.h>
#include <fs_info.h>
#include <ctype.h>
#include <stdlib.h>
#include <map>
#include <stdlib.h>
#include <string.h>
#include <compat/sys/stat.h>
#include <Alert.h>
#include <Application.h>
#include <Clipboard.h>
#include <Debug.h>
#include <Dragger.h>
#include <fs_attr.h>
#include <fs_info.h>
#include <Screen.h>
#include <Query.h>
#include <List.h>
@ -1820,8 +1822,14 @@ BPoseView::ShouldShowPose(const Model *model, const PoseInfo *poseInfo)
return false;
// check filter before adding item
return !fRefFilter || fRefFilter->Filter(model->EntryRef(), model->Node(),
const_cast<StatStruct *>(model->StatBuf()), model->MimeType());
if (!fRefFilter)
return true;
struct stat_beos statBeOS;
convert_to_stat_beos(model->StatBuf(), &statBeOS);
return fRefFilter->Filter(model->EntryRef(), model->Node(), &statBeOS,
model->MimeType());
}

View File

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

View File

@ -21,7 +21,7 @@ class CustomRefFilter : public BRefFilter {
CustomRefFilter(bool imageFiltering);
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);
protected:

View File

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

View File

@ -1,49 +1,51 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.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.
*/
#include <syscalls.h>
#include <sys/stat.h>
#include <errno.h>
#include <compat/sys/stat.h>
#define RETURN_AND_SET_ERRNO(err) \
if (err < 0) { \
errno = err; \
return -1; \
} \
return err;
#include <symbol_versioning.h>
#include <syscall_utils.h>
// BeOS compatibility
#define BEOS_STAT_SIZE 60
// prototypes for the compiler
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
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);
}
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);
}
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);
}
@ -52,37 +54,99 @@ lstat(const char *path, struct stat *stat)
// #pragma mark - BeOS compatibility
#ifndef _KERNEL_MODE
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)
void
convert_to_stat_beos(const struct stat* stat, struct stat_beos* beosStat)
{
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
__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
__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");