// NodeHandle.cpp
#include "NodeHandle.h"
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fs_attr.h>
#include "Compatibility.h"
#include "Directory.h"
#include "FDManager.h"
#include "Path.h"
// TODO: Do the FD creation via the FDManager.
// NodeHandle
// constructor
NodeHandle::NodeHandle()
: BReferenceable(),
Lockable(),
fCookie(-1),
fNodeRef()
{
}
// destructor
NodeHandle::~NodeHandle()
{
}
// GetStat
status_t
NodeHandle::GetStat(struct stat* st)
{
int fd = GetFD();
if (fd < 0)
return B_ENTRY_NOT_FOUND;
if (fstat(fd, st) < 0)
return errno;
return B_OK;
}
// SetCookie
void
NodeHandle::SetCookie(int32 cookie)
{
fCookie = cookie;
}
// GetCookie
int32
NodeHandle::GetCookie() const
{
return fCookie;
}
// GetNodeRef
const NodeRef&
NodeHandle::GetNodeRef() const
{
return fNodeRef;
}
// GetFD
int
NodeHandle::GetFD() const
{
return -1;
}
// #pragma mark -
// FileHandle
// constructor
FileHandle::FileHandle()
: fFD(-1)
{
}
// destructor
FileHandle::~FileHandle()
{
Close();
}
// Open
status_t
FileHandle::Open(Node* node, int openMode)
{
if (!node)
return B_BAD_VALUE;
openMode &= O_RWMASK | O_TRUNC | O_APPEND;
// get a path
Path path;
status_t error = node->GetPath(&path);
if (error != B_OK)
return error;
// open the file
error = FDManager::Open(path.GetPath(), openMode | O_NOTRAVERSE, 0, fFD);
if (error != B_OK)
return error;
fNodeRef = node->GetNodeRef();
return B_OK;
}
// Close
status_t
FileHandle::Close()
{
if (fFD < 0)
return B_BAD_VALUE;
status_t error = B_OK;
if (close(fFD) < 0)
error = errno;
fFD = -1;
return error;
}
// Read
status_t
FileHandle::Read(off_t pos, void* buffer, size_t size, size_t* _bytesRead)
{
if (fFD < 0)
return B_BAD_VALUE;
ssize_t bytesRead = read_pos(fFD, pos, buffer, size);
if (bytesRead < 0)
return errno;
*_bytesRead = bytesRead;
return B_OK;
}
// Write
status_t
FileHandle::Write(off_t pos, const void* buffer, size_t size,
size_t* _bytesWritten)
{
if (fFD < 0)
return B_BAD_VALUE;
ssize_t bytesWritten = write_pos(fFD, pos, buffer, size);
if (bytesWritten < 0)
return errno;
*_bytesWritten = bytesWritten;
return B_OK;
}
// ReadAttr
status_t
FileHandle::ReadAttr(const char* name, uint32 type, off_t pos, void* buffer,
size_t size, size_t* _bytesRead)
{
if (fFD < 0)
return B_BAD_VALUE;
ssize_t bytesRead = fs_read_attr(fFD, name, type, pos, buffer, size);
if (bytesRead < 0)
return errno;
*_bytesRead = bytesRead;
return B_OK;
}
// WriteAttr
status_t
FileHandle::WriteAttr(const char* name, uint32 type, off_t pos,
const void* buffer, size_t size, size_t* _bytesWritten)
{
if (fFD < 0)
return B_BAD_VALUE;
ssize_t bytesWritten = fs_write_attr(fFD, name, type, pos, buffer, size);
if (bytesWritten < 0)
return errno;
*_bytesWritten = bytesWritten;
return B_OK;
}
// RemoveAttr
status_t
FileHandle::RemoveAttr(const char* name)
{
if (fFD < 0)
return B_BAD_VALUE;
return (fs_remove_attr(fFD, name) == 0 ? B_OK : errno);
}
// StatAttr
status_t
FileHandle::StatAttr(const char* name, attr_info* info)
{
if (fFD < 0)
return B_BAD_VALUE;
return (fs_stat_attr(fFD, name, info) == 0 ? B_OK : errno);
}
// GetFD
int
FileHandle::GetFD() const
{
return fFD;
}
// #pragma mark -
// DirIterator
// constructor
DirIterator::DirIterator()
: fDirectory(NULL)
{
}
// destructor
DirIterator::~DirIterator()
{
if (fDirectory)
fDirectory->RemoveDirIterator(this);
}
// IsValid
bool
DirIterator::IsValid() const
{
return fDirectory;
}
// #pragma mark -
// AttrDirIterator
// constructor
AttrDirIterator::AttrDirIterator()
: NodeHandle(),
fDir(NULL)
{
}
// destructor
AttrDirIterator::~AttrDirIterator()
{
Close();
}
// Open
status_t
AttrDirIterator::Open(Node* node)
{
if (!node)
return B_BAD_VALUE;
// get a path
Path path;
status_t error = node->GetPath(&path);
if (error != B_OK)
return error;
// open the attribute directory
error = FDManager::OpenAttrDir(path.GetPath(), fDir);
if (error != B_OK)
return errno;
fNodeRef = node->GetNodeRef();
return B_OK;
}
// Close
status_t
AttrDirIterator::Close()
{
if (!fDir)
return B_BAD_VALUE;
status_t error = B_OK;
if (fs_close_attr_dir(fDir) < 0)
error = errno;
fDir = NULL;
return error;
}
// ReadDir
status_t
AttrDirIterator::ReadDir(dirent* _entry, int32 bufferSize,
int32 count, int32* countRead, bool* done)
{
// TODO: Burst read.
if (!fDir)
return B_ENTRY_NOT_FOUND;
*countRead = 0;
*done = false;
if (count == 0)
return B_OK;
if (struct dirent* entry = fs_read_attr_dir(fDir)) {
size_t entryLen = entry->d_name + strlen(entry->d_name) + 1
- (char*)entry;
memcpy(_entry, entry, entryLen);
*countRead = 1;
} else {
*countRead = 0;
*done = true;
}
return B_OK;
}
// RewindDir
status_t
AttrDirIterator::RewindDir()
{
if (!fDir)
return B_ENTRY_NOT_FOUND;
fs_rewind_attr_dir(fDir);
return B_OK;
}
// GetFD
int
AttrDirIterator::GetFD() const
{
return dirfd(fDir);
}
// #pragma mark -
// QueryListener
// constructor
QueryListener::QueryListener()
{
}
// destructor
QueryListener::~QueryListener()
{
}
// #pragma mark -
// QueryHandle
// constructor
QueryHandle::QueryHandle(port_id remotePort, int32 remoteToken)
: NodeHandle(),
fRemotePort(remotePort),
fRemoteToken(remoteToken),
fQueries(),
fCurrentQuery(NULL),
fListener(NULL),
fClosed(false)
{
}
// destructor
QueryHandle::~QueryHandle()
{
Close();
}
// SetQueryListener
void
QueryHandle::SetQueryListener(QueryListener* listener)
{
fListener = listener;
}
// GetQueryListener
QueryListener*
QueryHandle::GetQueryListener() const
{
return fListener;
}
// AddQuery
void
QueryHandle::AddQuery(Query* query)
{
if (query) {
fQueries.Insert(query);
if (!fCurrentQuery)
fCurrentQuery = query;
}
}
// RemoveQuery
void
QueryHandle::RemoveQuery(Query* query)
{
if (query) {
if (query == fCurrentQuery)
fCurrentQuery = fQueries.GetNext(query);
fQueries.Remove(query);
}
}
// GetRemotePort
port_id
QueryHandle::GetRemotePort() const
{
return fRemotePort;
}
// GetRemoteToken
int32
QueryHandle::GetRemoteToken() const
{
return fRemoteToken;
}
// Close
status_t
QueryHandle::Close()
{
if (fClosed)
return B_OK;
fCurrentQuery = NULL;
// delete all queries
for (DoublyLinkedList<Query>::Iterator it = fQueries.GetIterator();
it.HasNext();) {
Query* query = it.Next();
it.Remove();
delete query;
}
fClosed = true;
if (fListener)
fListener->QueryHandleClosed(this);
return B_OK;
}
// ReadDir
status_t
QueryHandle::ReadDir(dirent* entry, int32 count, int32* countRead)
{
if (count == 0) {
*countRead = 0;
return B_OK;
}
while (fCurrentQuery) {
int32 readEntries = fCurrentQuery->GetNextDirents(entry,
sizeof(struct dirent) + B_FILE_NAME_LENGTH, 1);
if (readEntries < 0)
return readEntries;
if (readEntries > 0) {
*countRead = 1;
return B_OK;
}
fCurrentQuery = fQueries.GetNext(fCurrentQuery);
}
*countRead = 0;
return B_OK;
}
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: fValid.