2002-10-16 20:14:14 +04:00
|
|
|
/*
|
|
|
|
** Copyright 2002, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
|
|
|
** Distributed under the terms of the OpenBeOS License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <fs_attr.h>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include "syscalls.h"
|
|
|
|
|
|
|
|
|
2002-10-17 23:22:04 +04:00
|
|
|
#define RETURN_AND_SET_ERRNO(status) \
|
|
|
|
{ \
|
|
|
|
if (status < 0) { \
|
|
|
|
errno = status; \
|
|
|
|
return -1; \
|
|
|
|
} \
|
|
|
|
return status; \
|
|
|
|
}
|
|
|
|
|
2002-10-16 20:14:14 +04:00
|
|
|
// for the DIR structure
|
|
|
|
#define BUFFER_SIZE 2048
|
|
|
|
|
|
|
|
|
|
|
|
ssize_t
|
|
|
|
fs_read_attr(int fd, const char *attribute, uint32 type, off_t pos, void *buffer, size_t readBytes)
|
|
|
|
{
|
|
|
|
ssize_t bytes;
|
|
|
|
|
2004-06-15 19:49:34 +04:00
|
|
|
int attr = _kern_open_attr(fd, attribute, O_RDONLY);
|
2002-10-16 20:14:14 +04:00
|
|
|
if (attr < 0)
|
2002-10-17 23:22:04 +04:00
|
|
|
RETURN_AND_SET_ERRNO(attr);
|
2002-10-16 20:14:14 +04:00
|
|
|
|
2002-10-17 23:22:04 +04:00
|
|
|
// type is not used at all in this function
|
2002-10-16 20:14:14 +04:00
|
|
|
(void)type;
|
|
|
|
|
2004-06-15 19:49:34 +04:00
|
|
|
bytes = _kern_read(fd, pos, buffer, readBytes);
|
|
|
|
_kern_close(attr);
|
2002-10-16 20:14:14 +04:00
|
|
|
|
2002-10-17 23:22:04 +04:00
|
|
|
RETURN_AND_SET_ERRNO(bytes);
|
2002-10-16 20:14:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ssize_t
|
|
|
|
fs_write_attr(int fd, const char *attribute, uint32 type, off_t pos, const void *buffer, size_t readBytes)
|
|
|
|
{
|
|
|
|
ssize_t bytes;
|
|
|
|
|
2004-06-15 19:49:34 +04:00
|
|
|
int attr = _kern_create_attr(fd, attribute, type, O_WRONLY);
|
2002-10-16 20:14:14 +04:00
|
|
|
if (attr < 0)
|
2002-10-17 23:22:04 +04:00
|
|
|
RETURN_AND_SET_ERRNO(attr);
|
2002-10-16 20:14:14 +04:00
|
|
|
|
2004-06-15 19:49:34 +04:00
|
|
|
bytes = _kern_write(fd, pos, buffer, readBytes);
|
|
|
|
_kern_close(attr);
|
2002-10-16 20:14:14 +04:00
|
|
|
|
2002-10-17 23:22:04 +04:00
|
|
|
RETURN_AND_SET_ERRNO(bytes);
|
2002-10-16 20:14:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
fs_remove_attr(int fd, const char *attribute)
|
|
|
|
{
|
2004-06-15 19:49:34 +04:00
|
|
|
status_t status = _kern_remove_attr(fd, attribute);
|
2002-10-17 23:22:04 +04:00
|
|
|
|
|
|
|
RETURN_AND_SET_ERRNO(status);
|
2002-10-16 20:14:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
fs_stat_attr(int fd, const char *attribute, struct attr_info *attrInfo)
|
|
|
|
{
|
|
|
|
struct stat stat;
|
|
|
|
status_t status;
|
|
|
|
|
2004-06-15 19:49:34 +04:00
|
|
|
int attr = _kern_open_attr(fd, attribute, O_RDONLY);
|
2002-10-16 20:14:14 +04:00
|
|
|
if (attr < 0)
|
2002-10-17 23:22:04 +04:00
|
|
|
RETURN_AND_SET_ERRNO(attr);
|
2002-10-16 20:14:14 +04:00
|
|
|
|
2004-08-29 00:45:00 +04:00
|
|
|
status = _kern_read_stat(attr, NULL, false, &stat, sizeof(struct stat));
|
2002-10-16 20:14:14 +04:00
|
|
|
if (status == B_OK) {
|
|
|
|
attrInfo->type = stat.st_type;
|
|
|
|
attrInfo->size = stat.st_size;
|
|
|
|
}
|
2004-06-15 19:49:34 +04:00
|
|
|
_kern_close(attr);
|
2002-10-16 20:14:14 +04:00
|
|
|
|
2002-10-17 23:22:04 +04:00
|
|
|
RETURN_AND_SET_ERRNO(status);
|
2002-10-16 20:14:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
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)
|
|
|
|
{
|
2002-10-17 23:22:04 +04:00
|
|
|
status_t status;
|
|
|
|
|
2002-10-16 20:14:14 +04:00
|
|
|
if (openMode & O_CREAT)
|
2004-06-15 19:49:34 +04:00
|
|
|
status = _kern_create_attr(fd, attribute, type, openMode);
|
2002-10-17 23:22:04 +04:00
|
|
|
else
|
2004-06-15 19:49:34 +04:00
|
|
|
status = _kern_open_attr(fd, attribute, openMode);
|
2002-10-16 20:14:14 +04:00
|
|
|
|
2002-10-17 23:22:04 +04:00
|
|
|
RETURN_AND_SET_ERRNO(status);
|
2002-10-16 20:14:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
fs_close_attr(int fd)
|
|
|
|
{
|
2004-06-15 19:49:34 +04:00
|
|
|
status_t status = _kern_close(fd);
|
2002-10-17 23:22:04 +04:00
|
|
|
|
|
|
|
RETURN_AND_SET_ERRNO(status);
|
2002-10-16 20:14:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static DIR *
|
|
|
|
open_attr_dir(int file, const char *path)
|
|
|
|
{
|
|
|
|
DIR *dir;
|
|
|
|
|
2004-06-15 19:49:34 +04:00
|
|
|
int fd = _kern_open_attr_dir(file, path);
|
2002-10-17 23:22:04 +04:00
|
|
|
if (fd < 0) {
|
|
|
|
errno = fd;
|
2002-10-16 20:14:14 +04:00
|
|
|
return NULL;
|
2002-10-17 23:22:04 +04:00
|
|
|
}
|
2002-10-16 20:14:14 +04:00
|
|
|
|
|
|
|
/* allocate the memory for the DIR structure */
|
2002-10-17 23:22:04 +04:00
|
|
|
if ((dir = (DIR *)malloc(sizeof(DIR) + BUFFER_SIZE)) == NULL) {
|
|
|
|
errno = B_NO_MEMORY;
|
2004-06-15 19:49:34 +04:00
|
|
|
_kern_close(fd);
|
2002-10-16 20:14:14 +04:00
|
|
|
return NULL;
|
2002-10-17 23:22:04 +04:00
|
|
|
}
|
2002-10-16 20:14:14 +04:00
|
|
|
|
|
|
|
dir->fd = fd;
|
|
|
|
|
|
|
|
return dir;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DIR *
|
|
|
|
fs_open_attr_dir(const char *path)
|
|
|
|
{
|
|
|
|
return open_attr_dir(-1, path);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DIR *
|
|
|
|
fs_fopen_attr_dir(int fd)
|
|
|
|
{
|
|
|
|
return open_attr_dir(fd, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
fs_close_attr_dir(DIR *dir)
|
|
|
|
{
|
2004-06-15 19:49:34 +04:00
|
|
|
int status = _kern_close(dir->fd);
|
2002-10-16 20:14:14 +04:00
|
|
|
|
|
|
|
free(dir);
|
|
|
|
|
2002-10-17 23:22:04 +04:00
|
|
|
RETURN_AND_SET_ERRNO(status);
|
2002-10-16 20:14:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct dirent *
|
|
|
|
fs_read_attr_dir(DIR *dir)
|
|
|
|
{
|
2004-06-15 19:49:34 +04:00
|
|
|
ssize_t count = _kern_read_dir(dir->fd, &dir->ent, BUFFER_SIZE, 1);
|
2002-10-17 23:22:04 +04:00
|
|
|
if (count <= 0) {
|
|
|
|
if (count < 0)
|
|
|
|
errno = count;
|
2002-10-16 20:14:14 +04:00
|
|
|
return NULL;
|
2002-10-17 23:22:04 +04:00
|
|
|
}
|
2002-10-16 20:14:14 +04:00
|
|
|
|
|
|
|
return &dir->ent;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
fs_rewind_attr_dir(DIR *dir)
|
|
|
|
{
|
2004-06-15 19:49:34 +04:00
|
|
|
int status = _kern_rewind_dir(dir->fd);
|
2002-10-16 20:14:14 +04:00
|
|
|
if (status < 0)
|
|
|
|
errno = status;
|
|
|
|
}
|
|
|
|
|