* Renamed fs_attr.c to fs_attr.cpp and cleaned it up a bit.

* Always use _kern_create_attr() in fs_write_attr(), or otherwise it might not
  be created when it should.
* Stippi special: fixed typo "in another words" -> "in other words" ("a" is
  singular, not plural).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31312 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-06-29 09:56:22 +00:00
parent 8fb7098371
commit d1084ff757
2 changed files with 125 additions and 136 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ MergeObject os_main.o :
debug.c
driver_settings.c
find_directory.c
fs_attr.c
fs_attr.cpp
fs_index.c
fs_info.c
fs_query.cpp
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
@@ -27,131 +27,6 @@
}
ssize_t
fs_read_attr(int fd, const char *attribute, uint32 type,
off_t pos, void *buffer, size_t readBytes)
{
ssize_t bytes;
int attr = _kern_open_attr(fd, attribute, O_RDONLY);
if (attr < 0)
RETURN_AND_SET_ERRNO(attr);
// type is not used at all in this function
(void)type;
bytes = _kern_read(attr, pos, buffer, readBytes);
_kern_close(attr);
RETURN_AND_SET_ERRNO(bytes);
}
ssize_t
fs_write_attr(int fd, const char *attribute, uint32 type,
off_t pos, const void *buffer, size_t writeBytes)
{
// NOTE: This call is deprecated in Haiku and has a number of problems:
// On BeOS, it was documented that the "pos" argument is ignored.
// However, a number of programs tried to use this call to write large
// attributes in a loop anyways. These programs all relied on the broken
// or at least inconsistent behaviour to truncate/clobber an existing
// attribute. In another words, writing 5 bytes at position 0 into an
// attribute that was already 10 bytes long resulted in an attribute of
// only 5 bytes length.
// The implementation of this function tries to stay compatible with
// BeOS in that it clobbers the existing attribute when you write at offset
// 0, but it also tries to support programs which continue to write more
// chunks.
// The new Haiku way is to use fs_open_attr() to get a regular file handle
// and use that for writing, then use fs_close_attr() when done. As you
// see from this implementation, it saves 2 syscalls per writing a chunk
// of data.
ssize_t bytes;
int attr = -1;
// If pos is 0, we try to avoid one syscall that with good chances
// will fail anyways and take the shortcut to creating the attr directly.
if (pos > 0)
attr = _kern_open_attr(fd, attribute, O_WRONLY);
if (attr < 0) {
attr = _kern_create_attr(fd, attribute, type, O_WRONLY | O_TRUNC);
if (attr < 0)
RETURN_AND_SET_ERRNO(attr);
}
bytes = _kern_write(attr, pos, buffer, writeBytes);
_kern_close(attr);
RETURN_AND_SET_ERRNO(bytes);
}
int
fs_remove_attr(int fd, const char *attribute)
{
status_t status = _kern_remove_attr(fd, attribute);
RETURN_AND_SET_ERRNO(status);
}
int
fs_stat_attr(int fd, const char *attribute, struct attr_info *attrInfo)
{
struct stat stat;
status_t status;
int attr = _kern_open_attr(fd, attribute, O_RDONLY);
if (attr < 0)
RETURN_AND_SET_ERRNO(attr);
status = _kern_read_stat(attr, NULL, false, &stat, sizeof(struct stat));
if (status == B_OK) {
attrInfo->type = stat.st_type;
attrInfo->size = stat.st_size;
}
_kern_close(attr);
RETURN_AND_SET_ERRNO(status);
}
/*
int
fs_open_attr(const char *path, const char *attribute, uint32 type, int openMode)
{
// TODO: implement fs_open_attr() - or remove it completely
// if it will be implemented, rename the current fs_open_attr() to fs_fopen_attr()
return B_ERROR;
}
*/
int
fs_open_attr(int fd, const char *attribute, uint32 type, int openMode)
{
status_t status;
if (openMode & O_CREAT)
status = _kern_create_attr(fd, attribute, type, openMode);
else
status = _kern_open_attr(fd, attribute, openMode);
RETURN_AND_SET_ERRNO(status);
}
int
fs_close_attr(int fd)
{
status_t status = _kern_close(fd);
RETURN_AND_SET_ERRNO(status);
}
static DIR *
open_attr_dir(int file, const char *path)
{
@@ -177,22 +52,136 @@ open_attr_dir(int file, const char *path)
}
DIR *
fs_open_attr_dir(const char *path)
// #pragma mark -
extern "C" ssize_t
fs_read_attr(int fd, const char* attribute, uint32 /*type*/, off_t pos,
void* buffer, size_t readBytes)
{
int attr = _kern_open_attr(fd, attribute, O_RDONLY);
if (attr < 0)
RETURN_AND_SET_ERRNO(attr);
ssize_t bytes = _kern_read(attr, pos, buffer, readBytes);
_kern_close(attr);
RETURN_AND_SET_ERRNO(bytes);
}
extern "C" ssize_t
fs_write_attr(int fd, const char* attribute, uint32 type, off_t pos,
const void* buffer, size_t writeBytes)
{
// NOTE: This call is deprecated in Haiku and has a number of problems:
// On BeOS, it was documented that the "pos" argument is ignored.
// However, a number of programs tried to use this call to write large
// attributes in a loop anyways. These programs all relied on the broken
// or at least inconsistent behaviour to truncate/clobber an existing
// attribute. In other words, writing 5 bytes at position 0 into an
// attribute that was already 10 bytes long resulted in an attribute of
// only 5 bytes length.
// The implementation of this function tries to stay compatible with
// BeOS in that it clobbers the existing attribute when you write at offset
// 0, but it also tries to support programs which continue to write more
// chunks.
// The new Haiku way is to use fs_open_attr() to get a regular file handle
// and use that for writing, then use fs_close_attr() when done. As you
// see from this implementation, it saves 2 syscalls per writing a chunk
// of data.
int attr = _kern_create_attr(fd, attribute, type,
O_WRONLY | (pos != 0 ? 0 : O_TRUNC));
if (attr < 0)
RETURN_AND_SET_ERRNO(attr);
ssize_t bytes = _kern_write(attr, pos, buffer, writeBytes);
_kern_close(attr);
RETURN_AND_SET_ERRNO(bytes);
}
extern "C" int
fs_remove_attr(int fd, const char* attribute)
{
status_t status = _kern_remove_attr(fd, attribute);
RETURN_AND_SET_ERRNO(status);
}
extern "C" int
fs_stat_attr(int fd, const char* attribute, struct attr_info* attrInfo)
{
int attr = _kern_open_attr(fd, attribute, O_RDONLY);
if (attr < 0)
RETURN_AND_SET_ERRNO(attr);
struct stat stat;
status_t status = _kern_read_stat(attr, NULL, false, &stat,
sizeof(struct stat));
if (status == B_OK) {
attrInfo->type = stat.st_type;
attrInfo->size = stat.st_size;
}
_kern_close(attr);
RETURN_AND_SET_ERRNO(status);
}
/*
int
fs_open_attr(const char *path, const char *attribute, uint32 type, int openMode)
{
// TODO: implement fs_open_attr() - or remove it completely
// if it will be implemented, rename the current fs_open_attr() to fs_fopen_attr()
return B_ERROR;
}
*/
extern "C" int
fs_open_attr(int fd, const char* attribute, uint32 type, int openMode)
{
status_t status;
if ((openMode & O_CREAT) != 0)
status = _kern_create_attr(fd, attribute, type, openMode);
else
status = _kern_open_attr(fd, attribute, openMode);
RETURN_AND_SET_ERRNO(status);
}
extern "C" int
fs_close_attr(int fd)
{
status_t status = _kern_close(fd);
RETURN_AND_SET_ERRNO(status);
}
extern "C" DIR*
fs_open_attr_dir(const char* path)
{
return open_attr_dir(-1, path);
}
DIR *
extern "C" DIR*
fs_fopen_attr_dir(int fd)
{
return open_attr_dir(fd, NULL);
}
int
fs_close_attr_dir(DIR *dir)
extern "C" int
fs_close_attr_dir(DIR* dir)
{
int status = _kern_close(dir->fd);
@@ -202,15 +191,15 @@ fs_close_attr_dir(DIR *dir)
}
struct dirent *
fs_read_attr_dir(DIR *dir)
extern "C" struct dirent*
fs_read_attr_dir(DIR* dir)
{
return readdir(dir);
}
void
fs_rewind_attr_dir(DIR *dir)
extern "C" void
fs_rewind_attr_dir(DIR* dir)
{
rewinddir(dir);
}