Refactored the BeOS attribute emulation using xattr a bit:
* Renamed fs_attr_xattr.cpp to libroot/fs_attr_untyped.cpp. * Pulled the xattr specifics into a separate fs_attr_xattr.h. * Added fs_attr_extattr.h, interfacing with FreeBSD's extattr support. Totally untested yet. Might not even compile. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27350 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
#ifdef HAIKU_HOST_USE_XATTR
|
#ifdef HAIKU_HOST_USE_XATTR
|
||||||
# include "fs_attr_xattr.cpp"
|
# include "fs_attr_untyped.cpp"
|
||||||
#else
|
#else
|
||||||
# include "fs_attr_generic.cpp"
|
# include "fs_attr_generic.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef FS_ATTR_EXTATTR_H
|
||||||
|
#define FS_ATTR_EXTATTR_H
|
||||||
|
|
||||||
|
/*! Included by fs_attr_untyped.cpp. Interfaces with FreeBSD extattr support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/extattr.h>
|
||||||
|
|
||||||
|
|
||||||
|
// the namespace all attributes live in
|
||||||
|
static const char* kAttributeNamespace = "haiku.";
|
||||||
|
static const int kAttributeNamespaceLen = 6;
|
||||||
|
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
list_attributes(int fd, const char* path, char* buffer, size_t bufferSize)
|
||||||
|
{
|
||||||
|
ssize_t bytesRead;
|
||||||
|
if (fd >= 0) {
|
||||||
|
bytesRead = extattr_list_fd(fd, EXTATTR_NAMESPACE_USER, buffer,
|
||||||
|
bufferSize);
|
||||||
|
} else {
|
||||||
|
bytesRead = extattr_list_link(path, EXTATTR_NAMESPACE_USER, buffer,
|
||||||
|
bufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytesRead <= 0)
|
||||||
|
return bytesRead;
|
||||||
|
|
||||||
|
// The listing is in a different format than expected by the caller. Here
|
||||||
|
// we get a sequence of (<namelen>, <unterminated name>) pairs, but expected
|
||||||
|
// is a sequence of null-terminated names. Let's convert it.
|
||||||
|
int index = *buffer;
|
||||||
|
memmove(buffer, buffer + 1, bytesRead - 1);
|
||||||
|
|
||||||
|
while (index < bytesRead - 1) {
|
||||||
|
int len = buffer[index];
|
||||||
|
buffer[index] = '\0';
|
||||||
|
index += len + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[bytesRead - 1] = '\0';
|
||||||
|
|
||||||
|
return bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
get_attribute(int fd, const char* path, const char* attribute, void* buffer,
|
||||||
|
size_t bufferSize)
|
||||||
|
{
|
||||||
|
if (fd >= 0) {
|
||||||
|
return extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, attribute, buffer,
|
||||||
|
bufferSize);
|
||||||
|
}
|
||||||
|
return extattr_get_link(path, EXTATTR_NAMESPACE_USER, attribute, buffer,
|
||||||
|
bufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
set_attribute(int fd, const char* path, const char* attribute,
|
||||||
|
const void* buffer, size_t bufferSize)
|
||||||
|
{
|
||||||
|
if (fd >= 0) {
|
||||||
|
return extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, attribute, buffer,
|
||||||
|
bufferSize);
|
||||||
|
}
|
||||||
|
return extattr_set_link(path, EXTATTR_NAMESPACE_USER, attribute, buffer,
|
||||||
|
bufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
remove_attribute(int fd, const char* path, const char* attribute)
|
||||||
|
{
|
||||||
|
if (fd >= 0)
|
||||||
|
return extattr_delete_fd(fd, EXTATTR_NAMESPACE_USER, attribute);
|
||||||
|
return extattr_delete_link(path, EXTATTR_NAMESPACE_USER, attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // FS_ATTR_EXTATTR_H
|
||||||
@@ -1,3 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2005-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! Emulation BeOS-style attributes by mapping them to untyped attributes of
|
||||||
|
the host platform (xattr on Linux, extattr on FreeBSD).
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifdef BUILDING_FS_SHELL
|
#ifdef BUILDING_FS_SHELL
|
||||||
# include "compat.h"
|
# include "compat.h"
|
||||||
@@ -23,22 +32,27 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <attr/xattr.h>
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <fs_attr.h>
|
#include <fs_attr.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Include the interface to the host platform attributes support.
|
||||||
|
#if defined(HAIKU_HOST_PLATFORM_LINUX)
|
||||||
|
# include "fs_attr_xattr.h"
|
||||||
|
#elif defined(HAIKU_HOST_PLATFORM_FREEBSD)
|
||||||
|
# include "fs_attr_extattr.h"
|
||||||
|
#else
|
||||||
|
# error No attribute support for this host platform!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {}
|
namespace BPrivate {}
|
||||||
using namespace BPrivate;
|
using namespace BPrivate;
|
||||||
using std::map;
|
using std::map;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
// the namespace all attributes live in
|
|
||||||
static const char* kAttributeNamespace = "user.haiku.";
|
|
||||||
static const int kAttributeNamespaceLen = 11;
|
|
||||||
|
|
||||||
// the maximum length of an attribute listing we support
|
// the maximum length of an attribute listing we support
|
||||||
static const int kMaxAttributeListingLength = 10240;
|
static const int kMaxAttributeListingLength = 10240;
|
||||||
|
|
||||||
@@ -270,13 +284,8 @@ private:
|
|||||||
char listing[kMaxAttributeListingLength];
|
char listing[kMaxAttributeListingLength];
|
||||||
|
|
||||||
// get the listing
|
// get the listing
|
||||||
ssize_t length;
|
ssize_t length = list_attributes(fFileFD, fPath.c_str(), listing,
|
||||||
if (fFileFD >= 0) {
|
kMaxAttributeListingLength);
|
||||||
length = flistxattr(fFileFD, listing, kMaxAttributeListingLength);
|
|
||||||
} else {
|
|
||||||
length = llistxattr(fPath.c_str(), listing,
|
|
||||||
kMaxAttributeListingLength);
|
|
||||||
}
|
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
@@ -487,11 +496,11 @@ fs_read_attr(int fd, const char *_attribute, uint32 type, off_t pos,
|
|||||||
ssize_t bytesRead = min_c((size_t)kMaxAttributeLength, readBytes)
|
ssize_t bytesRead = min_c((size_t)kMaxAttributeLength, readBytes)
|
||||||
+ sizeof(AttributeHeader);
|
+ sizeof(AttributeHeader);
|
||||||
if (localFD.Path()) {
|
if (localFD.Path()) {
|
||||||
bytesRead = lgetxattr(localFD.Path(), attribute.c_str(),
|
bytesRead = get_attribute(-1, localFD.Path(), attribute.c_str(),
|
||||||
attributeBuffer, bytesRead);
|
attributeBuffer, bytesRead);
|
||||||
} else {
|
} else {
|
||||||
bytesRead = fgetxattr(localFD.FD(), attribute.c_str(), attributeBuffer,
|
bytesRead = get_attribute(localFD.FD(), NULL, attribute.c_str(),
|
||||||
bytesRead);
|
attributeBuffer, bytesRead);
|
||||||
}
|
}
|
||||||
if (bytesRead < 0) {
|
if (bytesRead < 0) {
|
||||||
// Make sure, the error code is B_ENTRY_NOT_FOUND, if the attribute
|
// Make sure, the error code is B_ENTRY_NOT_FOUND, if the attribute
|
||||||
@@ -554,16 +563,16 @@ fs_write_attr(int fd, const char *_attribute, uint32 type, off_t pos,
|
|||||||
ssize_t toWrite = sizeof(AttributeHeader) + pos + writeBytes;
|
ssize_t toWrite = sizeof(AttributeHeader) + pos + writeBytes;
|
||||||
int result;
|
int result;
|
||||||
if (localFD.Path()) {
|
if (localFD.Path()) {
|
||||||
result = lsetxattr(localFD.Path(), attribute.c_str(), attributeBuffer,
|
result = set_attribute(-1, localFD.Path(), attribute.c_str(),
|
||||||
toWrite, 0);
|
attributeBuffer, toWrite);
|
||||||
} else {
|
} else {
|
||||||
result = fsetxattr(localFD.FD(), attribute.c_str(), attributeBuffer,
|
result = set_attribute(localFD.FD(), NULL, attribute.c_str(),
|
||||||
toWrite, 0);
|
attributeBuffer, toWrite);
|
||||||
}
|
}
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
// Setting user attributes on symlinks is not allowed. So, if this is
|
// Setting user attributes on symlinks is not allowed (xattr). So, if
|
||||||
// a symlink and we're only supposed to write a "BEOS:TYPE" attribute
|
// this is a symlink and we're only supposed to write a "BEOS:TYPE"
|
||||||
// we silently pretend to have succeeded.
|
// attribute we silently pretend to have succeeded.
|
||||||
if (localFD.IsSymlink() && strcmp(_attribute, "BEOS:TYPE") == 0)
|
if (localFD.IsSymlink() && strcmp(_attribute, "BEOS:TYPE") == 0)
|
||||||
return writeBytes;
|
return writeBytes;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -596,9 +605,9 @@ fs_remove_attr(int fd, const char *_attribute)
|
|||||||
// remove attribute
|
// remove attribute
|
||||||
int result;
|
int result;
|
||||||
if (localFD.Path())
|
if (localFD.Path())
|
||||||
result = lremovexattr(localFD.Path(), attribute.c_str());
|
result = remove_attribute(-1, localFD.Path(), attribute.c_str());
|
||||||
else
|
else
|
||||||
result = fremovexattr(localFD.FD(), attribute.c_str());
|
result = remove_attribute(localFD.FD(), NULL, attribute.c_str());
|
||||||
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
// Make sure, the error code is B_ENTRY_NOT_FOUND, if the attribute
|
// Make sure, the error code is B_ENTRY_NOT_FOUND, if the attribute
|
||||||
@@ -634,11 +643,11 @@ fs_stat_attr(int fd, const char *_attribute, struct attr_info *attrInfo)
|
|||||||
char attributeBuffer[sizeof(AttributeHeader) + kMaxAttributeLength];
|
char attributeBuffer[sizeof(AttributeHeader) + kMaxAttributeLength];
|
||||||
ssize_t bytesRead = sizeof(AttributeHeader) + kMaxAttributeLength;
|
ssize_t bytesRead = sizeof(AttributeHeader) + kMaxAttributeLength;
|
||||||
if (localFD.Path()) {
|
if (localFD.Path()) {
|
||||||
bytesRead = lgetxattr(localFD.Path(), attribute.c_str(),
|
bytesRead = get_attribute(-1, localFD.Path(), attribute.c_str(),
|
||||||
attributeBuffer, bytesRead);
|
attributeBuffer, bytesRead);
|
||||||
} else {
|
} else {
|
||||||
bytesRead = fgetxattr(localFD.FD(), attribute.c_str(), attributeBuffer,
|
bytesRead = get_attribute(localFD.FD(), NULL, attribute.c_str(),
|
||||||
bytesRead);
|
attributeBuffer, bytesRead);
|
||||||
}
|
}
|
||||||
if (bytesRead < 0) {
|
if (bytesRead < 0) {
|
||||||
// Make sure, the error code is B_ENTRY_NOT_FOUND, if the attribute
|
// Make sure, the error code is B_ENTRY_NOT_FOUND, if the attribute
|
||||||
@@ -696,8 +705,8 @@ _kern_open_attr_dir(int fd, const char *path)
|
|||||||
|
|
||||||
if (!dir)
|
if (!dir)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
// create descriptor
|
// create descriptor
|
||||||
AttrDirDescriptor *descriptor = new AttrDirDescriptor(dir, ref);
|
AttrDirDescriptor *descriptor = new AttrDirDescriptor(dir, ref);
|
||||||
return add_descriptor(descriptor);
|
return add_descriptor(descriptor);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef FS_ATTR_XATTR_H
|
||||||
|
#define FS_ATTR_XATTR_H
|
||||||
|
|
||||||
|
/*! Included by fs_attr_untyped.cpp. Interfaces with Linux xattr support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <attr/xattr.h>
|
||||||
|
|
||||||
|
|
||||||
|
// the namespace all attributes live in
|
||||||
|
static const char* kAttributeNamespace = "user.haiku.";
|
||||||
|
static const int kAttributeNamespaceLen = 11;
|
||||||
|
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
list_attributes(int fd, const char* path, char* buffer, size_t bufferSize)
|
||||||
|
{
|
||||||
|
if (fd >= 0)
|
||||||
|
return flistxattr(fd, buffer, bufferSize);
|
||||||
|
return llistxattr(path, buffer, bufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
get_attribute(int fd, const char* path, const char* attribute, void* buffer,
|
||||||
|
size_t bufferSize)
|
||||||
|
{
|
||||||
|
if (fd >= 0)
|
||||||
|
return fgetxattr(fd, attribute, buffer, bufferSize);
|
||||||
|
return lgetxattr(path, attribute, buffer, bufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
set_attribute(int fd, const char* path, const char* attribute,
|
||||||
|
const void* buffer, size_t bufferSize)
|
||||||
|
{
|
||||||
|
if (fd >= 0)
|
||||||
|
return fsetxattr(fd, attribute, buffer, bufferSize, 0);
|
||||||
|
return lsetxattr(path, attribute, buffer, bufferSize, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
remove_attribute(int fd, const char* path, const char* attribute)
|
||||||
|
{
|
||||||
|
if (fd >= 0)
|
||||||
|
return fremovexattr(fd, attribute);
|
||||||
|
return lremovexattr(path, attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // FS_ATTR_XATTR_H
|
||||||
Reference in New Issue
Block a user