Beginnings of a new, better portable FS shell with Haiku FS interface.

Doesn't do anything ATM, but already provides the required system
interface (VFS, caches, POSIX functions).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20859 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2007-04-27 12:17:22 +00:00
parent f38eff6aa2
commit a38a92c955
68 changed files with 17504 additions and 0 deletions
+584
View File
@@ -0,0 +1,584 @@
/*
* Copyright 2005-2006, Ingo Weinhold, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef KERNEL_UTIL_DOUBLY_LINKED_LIST_H
#define KERNEL_UTIL_DOUBLY_LINKED_LIST_H
#include "fssh_types.h"
#ifdef __cplusplus
namespace FSShell {
// DoublyLinkedListLink
template<typename Element>
class DoublyLinkedListLink {
public:
DoublyLinkedListLink() : previous(NULL), next(NULL) {}
~DoublyLinkedListLink() {}
Element *previous;
Element *next;
};
// DoublyLinkedListLinkImpl
template<typename Element>
class DoublyLinkedListLinkImpl {
private:
typedef DoublyLinkedListLink<Element> DLL_Link;
public:
DoublyLinkedListLinkImpl() : fDoublyLinkedListLink() {}
~DoublyLinkedListLinkImpl() {}
DLL_Link *GetDoublyLinkedListLink()
{ return &fDoublyLinkedListLink; }
const DLL_Link *GetDoublyLinkedListLink() const
{ return &fDoublyLinkedListLink; }
private:
DLL_Link fDoublyLinkedListLink;
};
// DoublyLinkedListStandardGetLink
template<typename Element>
class DoublyLinkedListStandardGetLink {
private:
typedef DoublyLinkedListLink<Element> Link;
public:
inline Link *operator()(Element *element) const
{
return element->GetDoublyLinkedListLink();
}
inline const Link *operator()(const Element *element) const
{
return element->GetDoublyLinkedListLink();
}
};
// DoublyLinkedListMemberGetLink
template<typename Element,
DoublyLinkedListLink<Element> Element::* LinkMember = &Element::fLink>
class DoublyLinkedListMemberGetLink {
private:
typedef DoublyLinkedListLink<Element> Link;
public:
inline Link *operator()(Element *element) const
{
return &(element->*LinkMember);
}
inline const Link *operator()(const Element *element) const
{
return &(element->*LinkMember);
}
};
// DoublyLinkedListCLink - interface to struct list
template<typename Element>
class DoublyLinkedListCLink {
private:
typedef DoublyLinkedListLink<Element> Link;
public:
inline Link *operator()(Element *element) const
{
return (Link *)&element->link;
}
inline const Link *operator()(const Element *element) const
{
return (const Link *)&element->link;
}
};
// for convenience
#define DOUBLY_LINKED_LIST_TEMPLATE_LIST \
template<typename Element, typename GetLink>
#define DOUBLY_LINKED_LIST_CLASS_NAME DoublyLinkedList<Element, GetLink>
// DoublyLinkedList
template<typename Element,
typename GetLink = DoublyLinkedListStandardGetLink<Element> >
class DoublyLinkedList {
private:
typedef DoublyLinkedList<Element, GetLink> List;
typedef DoublyLinkedListLink<Element> Link;
public:
class Iterator {
public:
Iterator(List *list)
:
fList(list)
{
Rewind();
}
Iterator(const Iterator &other)
{
*this = other;
}
bool HasNext() const
{
return fNext;
}
Element *Next()
{
fCurrent = fNext;
if (fNext)
fNext = fList->GetNext(fNext);
return fCurrent;
}
Element *Remove()
{
Element *element = fCurrent;
if (fCurrent) {
fList->Remove(fCurrent);
fCurrent = NULL;
}
return element;
}
Iterator &operator=(const Iterator &other)
{
fList = other.fList;
fCurrent = other.fCurrent;
fNext = other.fNext;
return *this;
}
void Rewind()
{
fCurrent = NULL;
fNext = fList->First();
}
private:
List *fList;
Element *fCurrent;
Element *fNext;
};
class ConstIterator {
public:
ConstIterator(const List *list)
:
fList(list)
{
Rewind();
}
ConstIterator(const ConstIterator &other)
{
*this = other;
}
bool HasNext() const
{
return fNext;
}
Element *Next()
{
Element *element = fNext;
if (fNext)
fNext = fList->GetNext(fNext);
return element;
}
ConstIterator &operator=(const ConstIterator &other)
{
fList = other.fList;
fNext = other.fNext;
return *this;
}
void Rewind()
{
fNext = fList->First();
}
private:
const List *fList;
Element *fNext;
};
class ReverseIterator {
public:
ReverseIterator(List *list)
:
fList(list)
{
Rewind();
}
ReverseIterator(const ReverseIterator &other)
{
*this = other;
}
bool HasNext() const
{
return fNext;
}
Element *Next()
{
fCurrent = fNext;
if (fNext)
fNext = fList->GetPrevious(fNext);
return fCurrent;
}
Element *Remove()
{
Element *element = fCurrent;
if (fCurrent) {
fList->Remove(fCurrent);
fCurrent = NULL;
}
return element;
}
ReverseIterator &operator=(const ReverseIterator &other)
{
fList = other.fList;
fCurrent = other.fCurrent;
fNext = other.fNext;
return *this;
}
void Rewind()
{
fCurrent = NULL;
fNext = fList->Last();
}
private:
List *fList;
Element *fCurrent;
Element *fNext;
};
class ConstReverseIterator {
public:
ConstReverseIterator(const List *list)
:
fList(list)
{
Rewind();
}
ConstReverseIterator(const ConstReverseIterator &other)
{
*this = other;
}
bool HasNext() const
{
return fNext;
}
Element *Next()
{
Element *element = fNext;
if (fNext)
fNext = fList->GetPrevious(fNext);
return element;
}
ConstReverseIterator &operator=(const ConstReverseIterator &other)
{
fList = other.fList;
fNext = other.fNext;
return *this;
}
void Rewind()
{
fNext = fList->Last();
}
private:
const List *fList;
Element *fNext;
};
public:
DoublyLinkedList() : fFirst(NULL), fLast(NULL) {}
~DoublyLinkedList() {}
inline bool IsEmpty() const { return (fFirst == NULL); }
inline void Insert(Element *element, bool back = true);
inline void Insert(Element *before, Element *element);
inline void Add(Element *element, bool back = true);
inline void Remove(Element *element);
inline void Swap(Element *a, Element *b);
inline void MoveFrom(DOUBLY_LINKED_LIST_CLASS_NAME *fromList);
inline void RemoveAll();
inline void MakeEmpty() { RemoveAll(); }
inline Element *First() const { return fFirst; }
inline Element *Last() const { return fLast; }
inline Element *Head() const { return fFirst; }
inline Element *Tail() const { return fLast; }
inline Element *RemoveHead();
inline Element *GetPrevious(Element *element) const;
inline Element *GetNext(Element *element) const;
inline int32_t Size() const;
// O(n)!
inline Iterator GetIterator() { return Iterator(this); }
inline ConstIterator GetIterator() const { return ConstIterator(this); }
inline ReverseIterator GetReverseIterator()
{ return ReverseIterator(this); }
inline ConstReverseIterator GetReverseIterator() const
{ return ConstReverseIterator(this); }
private:
Element *fFirst;
Element *fLast;
static GetLink sGetLink;
};
// inline methods
// Insert
DOUBLY_LINKED_LIST_TEMPLATE_LIST
void
DOUBLY_LINKED_LIST_CLASS_NAME::Insert(Element *element, bool back)
{
if (element) {
if (back) {
// append
Link *elLink = sGetLink(element);
elLink->previous = fLast;
elLink->next = NULL;
if (fLast)
sGetLink(fLast)->next = element;
else
fFirst = element;
fLast = element;
} else {
// prepend
Link *elLink = sGetLink(element);
elLink->previous = NULL;
elLink->next = fFirst;
if (fFirst)
sGetLink(fFirst)->previous = element;
else
fLast = element;
fFirst = element;
}
}
}
// Insert
DOUBLY_LINKED_LIST_TEMPLATE_LIST
void
DOUBLY_LINKED_LIST_CLASS_NAME::Insert(Element *before, Element *element)
{
if (before == NULL) {
Insert(element);
return;
}
if (element == NULL)
return;
Link *beforeLink = sGetLink(before);
Link *link = sGetLink(element);
link->next = before;
link->previous = beforeLink->previous;
if (link->previous != NULL)
sGetLink(link->previous)->next = element;
beforeLink->previous = element;
if (fFirst == before)
fFirst = element;
}
// Add
DOUBLY_LINKED_LIST_TEMPLATE_LIST
void
DOUBLY_LINKED_LIST_CLASS_NAME::Add(Element *element, bool back)
{
Insert(element, back);
}
// Remove
DOUBLY_LINKED_LIST_TEMPLATE_LIST
void
DOUBLY_LINKED_LIST_CLASS_NAME::Remove(Element *element)
{
if (element) {
Link *elLink = sGetLink(element);
if (elLink->previous)
sGetLink(elLink->previous)->next = elLink->next;
else
fFirst = elLink->next;
if (elLink->next)
sGetLink(elLink->next)->previous = elLink->previous;
else
fLast = elLink->previous;
elLink->previous = NULL;
elLink->next = NULL;
}
}
// Swap
DOUBLY_LINKED_LIST_TEMPLATE_LIST
void
DOUBLY_LINKED_LIST_CLASS_NAME::Swap(Element *a, Element *b)
{
if (a && b && a != b) {
Link *aLink = sGetLink(a);
Link *bLink = sGetLink(b);
Element *aPrev = aLink->previous;
Element *bPrev = bLink->previous;
Element *aNext = aLink->next;
Element *bNext = bLink->next;
// place a
if (bPrev)
sGetLink(bPrev)->next = a;
else
fFirst = a;
if (bNext)
sGetLink(bNext)->previous = a;
else
fLast = a;
aLink->previous = bPrev;
aLink->next = bNext;
// place b
if (aPrev)
sGetLink(aPrev)->next = b;
else
fFirst = b;
if (aNext)
sGetLink(aNext)->previous = b;
else
fLast = b;
bLink->previous = aPrev;
bLink->next = aNext;
}
}
// MoveFrom
DOUBLY_LINKED_LIST_TEMPLATE_LIST
void
DOUBLY_LINKED_LIST_CLASS_NAME::MoveFrom(DOUBLY_LINKED_LIST_CLASS_NAME *fromList)
{
if (fromList && fromList->fFirst) {
if (fFirst) {
sGetLink(fLast)->next = fromList->fFirst;
sGetLink(fFirst)->previous = fLast;
fLast = fromList->fLast;
} else {
fFirst = fromList->fFirst;
fLast = fromList->fLast;
}
fromList->fFirst = NULL;
fromList->fLast = NULL;
}
}
// RemoveAll
DOUBLY_LINKED_LIST_TEMPLATE_LIST
void
DOUBLY_LINKED_LIST_CLASS_NAME::RemoveAll()
{
Element *element = fFirst;
while (element) {
Link *elLink = sGetLink(element);
element = elLink->next;
elLink->previous = NULL;
elLink->next = NULL;
}
fFirst = NULL;
fLast = NULL;
}
// RemoveHead
DOUBLY_LINKED_LIST_TEMPLATE_LIST
Element *
DOUBLY_LINKED_LIST_CLASS_NAME::RemoveHead()
{
Element *element = Head();
Remove(element);
return element;
}
// GetPrevious
DOUBLY_LINKED_LIST_TEMPLATE_LIST
Element *
DOUBLY_LINKED_LIST_CLASS_NAME::GetPrevious(Element *element) const
{
Element *result = NULL;
if (element)
result = sGetLink(element)->previous;
return result;
}
// GetNext
DOUBLY_LINKED_LIST_TEMPLATE_LIST
Element *
DOUBLY_LINKED_LIST_CLASS_NAME::GetNext(Element *element) const
{
Element *result = NULL;
if (element)
result = sGetLink(element)->next;
return result;
}
// Size
DOUBLY_LINKED_LIST_TEMPLATE_LIST
int32_t
DOUBLY_LINKED_LIST_CLASS_NAME::Size() const
{
int32_t count = 0;
for (Element* element = First(); element; element = GetNext(element))
count++;
return count;
}
// sGetLink
DOUBLY_LINKED_LIST_TEMPLATE_LIST
GetLink DOUBLY_LINKED_LIST_CLASS_NAME::sGetLink;
} // namespace FSShell
using FSShell::DoublyLinkedListLink;
using FSShell::DoublyLinkedListLinkImpl;
using FSShell::DoublyLinkedListStandardGetLink;
using FSShell::DoublyLinkedListMemberGetLink;
using FSShell::DoublyLinkedListCLink;
using FSShell::DoublyLinkedList;
#endif /* __cplusplus */
#endif // _KERNEL_UTIL_DOUBLY_LINKED_LIST_H
+62
View File
@@ -0,0 +1,62 @@
/*
* Copyright 2004-2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _K_PATH_H
#define _K_PATH_H
#include "fssh_defs.h"
#include "fssh_kernel_export.h"
namespace FSShell {
class KPath {
public:
KPath(fssh_size_t bufferSize = FSSH_B_PATH_NAME_LENGTH);
KPath(const char* path, bool normalize = false,
fssh_size_t bufferSize = FSSH_B_PATH_NAME_LENGTH);
KPath(const KPath& other);
~KPath();
fssh_status_t SetTo(const char *path, bool normalize = false,
fssh_size_t bufferSize = FSSH_B_PATH_NAME_LENGTH);
fssh_status_t InitCheck() const;
fssh_status_t SetPath(const char *path, bool normalize = false);
const char *Path() const;
fssh_size_t Length() const { return fPathLength; }
fssh_size_t BufferSize() const { return fBufferSize; }
char *LockBuffer();
void UnlockBuffer();
const char *Leaf() const;
fssh_status_t ReplaceLeaf(const char *newLeaf);
fssh_status_t Append(const char *toAppend, bool isComponent = true);
KPath& operator=(const KPath& other);
KPath& operator=(const char* path);
bool operator==(const KPath& other) const;
bool operator==(const char* path) const;
bool operator!=(const KPath& other) const;
bool operator!=(const char* path) const;
private:
void _ChopTrailingSlashes();
char* fBuffer;
fssh_size_t fBufferSize;
fssh_size_t fPathLength;
bool fLocked;
};
} // namespace FSShell
using FSShell::KPath;
#endif /* _K_PATH_H */
+87
View File
@@ -0,0 +1,87 @@
/* Stack - a template stack class (plus some handy methods)
*
* Copyright 2001-2005, Axel Dörfler, [email protected].
* This file may be used under the terms of the MIT License.
*/
#ifndef _FSSH_STACK_H
#define _FSSH_STACK_H
#include "fssh_defs.h"
#include "fssh_errors.h"
namespace FSShell {
template<class T> class Stack {
public:
Stack()
:
fArray(NULL),
fUsed(0),
fMax(0)
{
}
~Stack()
{
free(fArray);
}
bool IsEmpty() const
{
return fUsed == 0;
}
void MakeEmpty()
{
// could also free the memory
fUsed = 0;
}
fssh_status_t Push(T value)
{
if (fUsed >= fMax) {
fMax += 16;
T *newArray = (T *)realloc(fArray, fMax * sizeof(T));
if (newArray == NULL)
return FSSH_B_NO_MEMORY;
fArray = newArray;
}
fArray[fUsed++] = value;
return FSSH_B_OK;
}
bool Pop(T *value)
{
if (fUsed == 0)
return false;
*value = fArray[--fUsed];
return true;
}
T *Array()
{
return fArray;
}
int32_t CountItems() const
{
return fUsed;
}
private:
T *fArray;
int32_t fUsed;
int32_t fMax;
};
} // namespace FSShell
using FSShell::Stack;
#endif /* _FSSH_STACK_H */
File diff suppressed because it is too large Load Diff
+32
View File
@@ -0,0 +1,32 @@
/* Modules Definitions
**
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef _FSSH_ATOMIC_H
#define _FSSH_ATOMIC_H
#include "fssh_types.h"
#ifdef __cplusplus
extern "C" {
#endif
int32_t fssh_atomic_set(vint32_t *value, int32_t newValue);
int32_t fssh_atomic_test_and_set(vint32_t *value, int32_t newValue,
int32_t testAgainst);
int32_t fssh_atomic_add(vint32_t *value, int32_t addValue);
int32_t fssh_atomic_and(vint32_t *value, int32_t andValue);
int32_t fssh_atomic_or(vint32_t *value, int32_t orValue);
int32_t fssh_atomic_get(vint32_t *value);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_ATOMIC_H */
+162
View File
@@ -0,0 +1,162 @@
/*
* Copyright 2005-2007, Ingo Weinhold, [email protected].
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_AUTO_LOCKER_H
#define _FSSH_AUTO_LOCKER_H
namespace FSShell {
// AutoLockerStandardLocking
template<typename Lockable>
class AutoLockerStandardLocking {
public:
inline bool Lock(Lockable *lockable)
{
return lockable->Lock();
}
inline void Unlock(Lockable *lockable)
{
lockable->Unlock();
}
};
// AutoLockerReadLocking
template<typename Lockable>
class AutoLockerReadLocking {
public:
inline bool Lock(Lockable *lockable)
{
return lockable->ReadLock();
}
inline void Unlock(Lockable *lockable)
{
lockable->ReadUnlock();
}
};
// AutoLockerWriteLocking
template<typename Lockable>
class AutoLockerWriteLocking {
public:
inline bool Lock(Lockable *lockable)
{
return lockable->WriteLock();
}
inline void Unlock(Lockable *lockable)
{
lockable->WriteUnlock();
}
};
// AutoLocker
template<typename Lockable,
typename Locking = AutoLockerStandardLocking<Lockable> >
class AutoLocker {
private:
typedef AutoLocker<Lockable, Locking> ThisClass;
public:
inline AutoLocker()
: fLockable(NULL),
fLocked(false)
{
}
inline AutoLocker(Lockable *lockable, bool alreadyLocked = false,
bool lockIfNotLocked = true)
: fLockable(lockable),
fLocked(fLockable && alreadyLocked)
{
if (!alreadyLocked && lockIfNotLocked)
Lock();
}
inline AutoLocker(Lockable &lockable, bool alreadyLocked = false,
bool lockIfNotLocked = true)
: fLockable(&lockable),
fLocked(fLockable && alreadyLocked)
{
if (!alreadyLocked && lockIfNotLocked)
Lock();
}
inline ~AutoLocker()
{
Unlock();
}
inline void SetTo(Lockable *lockable, bool alreadyLocked,
bool lockIfNotLocked = true)
{
Unlock();
fLockable = lockable;
fLocked = alreadyLocked;
if (!alreadyLocked && lockIfNotLocked)
Lock();
}
inline void SetTo(Lockable &lockable, bool alreadyLocked,
bool lockIfNotLocked = true)
{
SetTo(&lockable, alreadyLocked, lockIfNotLocked);
}
inline void Unset()
{
Unlock();
Detach();
}
inline bool Lock()
{
if (fLockable && !fLocked)
fLocked = fLocking.Lock(fLockable);
return fLocked;
}
inline void Unlock()
{
if (fLockable && fLocked) {
fLocking.Unlock(fLockable);
fLocked = false;
}
}
inline void Detach()
{
fLockable = NULL;
fLocked = false;
}
inline AutoLocker<Lockable, Locking> &operator=(Lockable *lockable)
{
SetTo(lockable);
return *this;
}
inline AutoLocker<Lockable, Locking> &operator=(Lockable &lockable)
{
SetTo(&lockable);
return *this;
}
inline bool IsLocked() const { return fLocked; }
inline operator bool() const { return fLocked; }
private:
Lockable *fLockable;
bool fLocked;
Locking fLocking;
};
} // namespace FSShell
using FSShell::AutoLocker;
#endif // _FSSH_AUTO_LOCKER_H
+131
View File
@@ -0,0 +1,131 @@
/*
* Copyright 2007, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_BYTEORDER_H
#define _FSSH_BYTEORDER_H
#include <endian.h>
// platform endian.h
#include "fssh_defs.h"
// swap directions
typedef enum {
FSSH_B_SWAP_HOST_TO_LENDIAN,
FSSH_B_SWAP_HOST_TO_BENDIAN,
FSSH_B_SWAP_LENDIAN_TO_HOST,
FSSH_B_SWAP_BENDIAN_TO_HOST,
FSSH_B_SWAP_ALWAYS
} fssh_swap_action;
// BSD/networking macros
#ifndef fssh_htonl
# define fssh_htonl(x) FSSH_B_HOST_TO_BENDIAN_INT32(x)
# define fssh_ntohl(x) FSSH_B_BENDIAN_TO_HOST_INT32(x)
# define fssh_htons(x) FSSH_B_HOST_TO_BENDIAN_INT16(x)
# define fssh_ntohs(x) FSSH_B_BENDIAN_TO_HOST_INT16(x)
#endif
// always swap macros
#define FSSH_B_SWAP_DOUBLE(arg) __fssh_swap_double(arg)
#define FSSH_B_SWAP_FLOAT(arg) __fssh_swap_float(arg)
#define FSSH_B_SWAP_INT64(arg) __fssh_swap_int64(arg)
#define FSSH_B_SWAP_INT32(arg) __fssh_swap_int32(arg)
#define FSSH_B_SWAP_INT16(arg) __fssh_swap_int16(arg)
#if BYTE_ORDER == __LITTLE_ENDIAN
// Host is little endian
#define FSSH_B_HOST_IS_LENDIAN 1
#define FSSH_B_HOST_IS_BENDIAN 0
// Host native to little endian
#define FSSH_B_HOST_TO_LENDIAN_DOUBLE(arg) (double)(arg)
#define FSSH_B_HOST_TO_LENDIAN_FLOAT(arg) (float)(arg)
#define FSSH_B_HOST_TO_LENDIAN_INT64(arg) (uint64_t)(arg)
#define FSSH_B_HOST_TO_LENDIAN_INT32(arg) (uint32_t)(arg)
#define FSSH_B_HOST_TO_LENDIAN_INT16(arg) (uint16_t)(arg)
// Little endian to host native
#define FSSH_B_LENDIAN_TO_HOST_DOUBLE(arg) (double)(arg)
#define FSSH_B_LENDIAN_TO_HOST_FLOAT(arg) (float)(arg)
#define FSSH_B_LENDIAN_TO_HOST_INT64(arg) (uint64_t)(arg)
#define FSSH_B_LENDIAN_TO_HOST_INT32(arg) (uint32_t)(arg)
#define FSSH_B_LENDIAN_TO_HOST_INT16(arg) (uint16_t)(arg)
// Host native to big endian
#define FSSH_B_HOST_TO_BENDIAN_DOUBLE(arg) __fssh_swap_double(arg)
#define FSSH_B_HOST_TO_BENDIAN_FLOAT(arg) __fssh_swap_float(arg)
#define FSSH_B_HOST_TO_BENDIAN_INT64(arg) __fssh_swap_int64(arg)
#define FSSH_B_HOST_TO_BENDIAN_INT32(arg) __fssh_swap_int32(arg)
#define FSSH_B_HOST_TO_BENDIAN_INT16(arg) __fssh_swap_int16(arg)
// Big endian to host native
#define FSSH_B_BENDIAN_TO_HOST_DOUBLE(arg) __fssh_swap_double(arg)
#define FSSH_B_BENDIAN_TO_HOST_FLOAT(arg) __fssh_swap_float(arg)
#define FSSH_B_BENDIAN_TO_HOST_INT64(arg) __fssh_swap_int64(arg)
#define FSSH_B_BENDIAN_TO_HOST_INT32(arg) __fssh_swap_int32(arg)
#define FSSH_B_BENDIAN_TO_HOST_INT16(arg) __fssh_swap_int16(arg)
#else // BYTE_ORDER
// Host is big endian
#define FSSH_B_HOST_IS_LENDIAN 0
#define FSSH_B_HOST_IS_BENDIAN 1
// Host native to little endian
#define FSSH_B_HOST_TO_LENDIAN_DOUBLE(arg) __fssh_swap_double(arg)
#define FSSH_B_HOST_TO_LENDIAN_FLOAT(arg) __fssh_swap_float(arg)
#define FSSH_B_HOST_TO_LENDIAN_INT64(arg) __fssh_swap_int64(arg)
#define FSSH_B_HOST_TO_LENDIAN_INT32(arg) __fssh_swap_int32(arg)
#define FSSH_B_HOST_TO_LENDIAN_INT16(arg) __fssh_swap_int16(arg)
// Little endian to host native
#define FSSH_B_LENDIAN_TO_HOST_DOUBLE(arg) __fssh_swap_double(arg)
#define FSSH_B_LENDIAN_TO_HOST_FLOAT(arg) __fssh_swap_float(arg)
#define FSSH_B_LENDIAN_TO_HOST_INT64(arg) __fssh_swap_int64(arg)
#define FSSH_B_LENDIAN_TO_HOST_INT32(arg) __fssh_swap_int32(arg)
#define FSSH_B_LENDIAN_TO_HOST_INT16(arg) __fssh_swap_int16(arg)
// Host native to big endian
#define FSSH_B_HOST_TO_BENDIAN_DOUBLE(arg) (double)(arg)
#define FSSH_B_HOST_TO_BENDIAN_FLOAT(arg) (float)(arg)
#define FSSH_B_HOST_TO_BENDIAN_INT64(arg) (uint64_t)(arg)
#define FSSH_B_HOST_TO_BENDIAN_INT32(arg) (uint32_t)(arg)
#define FSSH_B_HOST_TO_BENDIAN_INT16(arg) (uint16_t)(arg)
// Big endian to host native
#define FSSH_B_BENDIAN_TO_HOST_DOUBLE(arg) (double)(arg)
#define FSSH_B_BENDIAN_TO_HOST_FLOAT(arg) (float)(arg)
#define FSSH_B_BENDIAN_TO_HOST_INT64(arg) (uint64_t)(arg)
#define FSSH_B_BENDIAN_TO_HOST_INT32(arg) (uint32_t)(arg)
#define FSSH_B_BENDIAN_TO_HOST_INT16(arg) (uint16_t)(arg)
#endif // BYTE_ORDER
#ifdef __cplusplus
extern "C" {
#endif
extern fssh_status_t fssh_swap_data(fssh_type_code type, void *data,
fssh_size_t length, fssh_swap_action action);
extern bool is_type_swapped(fssh_type_code type);
// Private implementations
extern double __fssh_swap_double(double arg);
extern float __fssh_swap_float(float arg);
extern uint64_t __fssh_swap_int64(uint64_t arg);
extern uint32_t __fssh_swap_int32(uint32_t arg);
extern uint16_t __fssh_swap_int16(uint16_t arg);
#ifdef __cplusplus
}
#endif
#endif // _FSSH_BYTEORDER_H
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_DEFS_H
#define _FSSH_DEFS_H
#include "fssh_types.h"
// Limits
#define FSSH_B_DEV_NAME_LENGTH 128
#define FSSH_B_FILE_NAME_LENGTH 256
#define FSSH_B_PATH_NAME_LENGTH 1024
#define FSSH_B_ATTR_NAME_LENGTH (FSSH_B_FILE_NAME_LENGTH-1)
#define FSSH_B_MIME_TYPE_LENGTH (FSSH_B_ATTR_NAME_LENGTH - 15)
#define FSSH_B_MAX_SYMLINKS 16
// Open Modes
#define FSSH_B_READ_ONLY FSSH_O_RDONLY // read only
#define FSSH_B_WRITE_ONLY FSSH_O_WRONLY // write only
#define FSSH_B_READ_WRITE FSSH_O_RDWR // read and write
#define FSSH_B_FAIL_IF_EXISTS FSSH_O_EXCL // exclusive create
#define FSSH_B_CREATE_FILE FSSH_O_CREAT // create the file
#define FSSH_B_ERASE_FILE FSSH_O_TRUNC // erase the file's data
#define FSSH_B_OPEN_AT_END FSSH_O_APPEND // point to the end of the data
// Node Flavors
enum fssh_node_flavor {
FSSH_B_FILE_NODE = 0x01,
FSSH_B_SYMLINK_NODE = 0x02,
FSSH_B_DIRECTORY_NODE = 0x04,
FSSH_B_ANY_NODE = 0x07
};
#if defined(__GNUC__) && __GNUC__ > 3
#define fssh_offsetof(type,member) __builtin_offsetof(type, member)
#else
#define fssh_offsetof(type,member) ((size_t)&((type*)0)->member)
#endif
#define fssh_min_c(a,b) ((a)>(b)?(b):(a))
#define fssh_max_c(a,b) ((a)>(b)?(a):(b))
#define _FSSH_PACKED __attribute__((packed))
#endif // _FSSH_DEFS_H
+42
View File
@@ -0,0 +1,42 @@
/*
** Distributed under the terms of the Haiku License.
*/
#ifndef _FSSH_DIRENT_H
#define _FSSH_DIRENT_H
#include "fssh_defs.h"
typedef struct fssh_dirent {
fssh_dev_t d_dev; /* device */
fssh_dev_t d_pdev; /* parent device (only for queries) */
fssh_ino_t d_ino; /* inode number */
fssh_ino_t d_pino; /* parent inode (only for queries) */
unsigned short d_reclen; /* length of this record, not the name */
char d_name[1]; /* name of the entry (null byte terminated) */
} fssh_dirent_t;
typedef struct {
int fd;
struct fssh_dirent ent;
} fssh_DIR;
#ifdef __cplusplus
extern "C" {
#endif
fssh_DIR *fssh_opendir(const char *dirname);
struct fssh_dirent *fssh_readdir(fssh_DIR *dir);
int fssh_readdir_r(fssh_DIR *dir, struct fssh_dirent *entry,
struct fssh_dirent **_result);
int fssh_closedir(fssh_DIR *dir);
void fssh_rewinddir(fssh_DIR *dir);
void fssh_seekdir(fssh_DIR *dir, long int loc);
long int fssh_telldir(fssh_DIR *);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_DIRENT_H */
@@ -0,0 +1,156 @@
/*
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_DISK_DEVICE_DEFS_H
#define _FSSH_DISK_DEVICE_DEFS_H
#include "fssh_defs.h"
typedef int32_t fssh_partition_id;
typedef int32_t fssh_disk_system_id;
typedef int32_t fssh_disk_job_id;
// partition flags
enum {
FSSH_B_PARTITION_IS_DEVICE = 0x01,
FSSH_B_PARTITION_FILE_SYSTEM = 0x02,
FSSH_B_PARTITION_PARTITIONING_SYSTEM = 0x04,
FSSH_B_PARTITION_READ_ONLY = 0x08,
FSSH_B_PARTITION_MOUNTED = 0x10, // needed?
FSSH_B_PARTITION_BUSY = 0x20,
FSSH_B_PARTITION_DESCENDANT_BUSY = 0x40,
};
// partition statuses
enum {
FSSH_B_PARTITION_VALID,
FSSH_B_PARTITION_CORRUPT,
FSSH_B_PARTITION_UNRECOGNIZED,
FSSH_B_PARTITION_UNINITIALIZED, // Only when uninitialized manually.
// When not recognized while scanning it's
// B_PARTITION_UNRECOGNIZED.
};
// partition change flags
enum {
FSSH_B_PARTITION_CHANGED_OFFSET = 0x000001,
FSSH_B_PARTITION_CHANGED_SIZE = 0x000002,
FSSH_B_PARTITION_CHANGED_CONTENT_SIZE = 0x000004,
FSSH_B_PARTITION_CHANGED_BLOCK_SIZE = 0x000008,
FSSH_B_PARTITION_CHANGED_STATUS = 0x000010,
FSSH_B_PARTITION_CHANGED_FLAGS = 0x000020,
FSSH_B_PARTITION_CHANGED_VOLUME = 0x000040,
FSSH_B_PARTITION_CHANGED_NAME = 0x000080,
FSSH_B_PARTITION_CHANGED_CONTENT_NAME = 0x000100,
FSSH_B_PARTITION_CHANGED_TYPE = 0x000200,
FSSH_B_PARTITION_CHANGED_CONTENT_TYPE = 0x000400,
FSSH_B_PARTITION_CHANGED_PARAMETERS = 0x000800,
FSSH_B_PARTITION_CHANGED_CONTENT_PARAMETERS = 0x001000,
FSSH_B_PARTITION_CHANGED_CHILDREN = 0x002000,
FSSH_B_PARTITION_CHANGED_DESCENDANTS = 0x004000,
FSSH_B_PARTITION_CHANGED_DEFRAGMENTATION = 0x008000,
FSSH_B_PARTITION_CHANGED_CHECK = 0x010000,
FSSH_B_PARTITION_CHANGED_REPAIR = 0x020000,
FSSH_B_PARTITION_CHANGED_INITIALIZATION = 0x040000,
};
// disk device flags
enum {
FSSH_B_DISK_DEVICE_REMOVABLE = 0x01,
FSSH_B_DISK_DEVICE_HAS_MEDIA = 0x02,
FSSH_B_DISK_DEVICE_READ_ONLY = 0x04,
FSSH_B_DISK_DEVICE_WRITE_ONCE = 0x08,
};
// disk system flags
enum {
FSSH_B_DISK_SYSTEM_IS_FILE_SYSTEM = 0x0001,
// flags common for both file and partitioning systems
FSSH_B_DISK_SYSTEM_SUPPORTS_CHECKING = 0x0002,
FSSH_B_DISK_SYSTEM_SUPPORTS_REPAIRING = 0x0004,
FSSH_B_DISK_SYSTEM_SUPPORTS_RESIZING = 0x0008,
FSSH_B_DISK_SYSTEM_SUPPORTS_MOVING = 0x0010,
FSSH_B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME = 0x0020,
FSSH_B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS = 0x0040,
// file system specific flags
FSSH_B_DISK_SYSTEM_SUPPORTS_DEFRAGMENTING = 0x0100,
FSSH_B_DISK_SYSTEM_SUPPORTS_DEFRAGMENTING_WHILE_MOUNTED = 0x0200,
FSSH_B_DISK_SYSTEM_SUPPORTS_CHECKING_WHILE_MOUNTED = 0x0400,
FSSH_B_DISK_SYSTEM_SUPPORTS_REPAIRING_WHILE_MOUNTED = 0x0800,
FSSH_B_DISK_SYSTEM_SUPPORTS_RESIZING_WHILE_MOUNTED = 0x1000,
FSSH_B_DISK_SYSTEM_SUPPORTS_MOVING_WHILE_MOUNTED = 0x2000,
FSSH_B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME_WHILE_MOUNTED = 0x4000,
FSSH_B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS_WHILE_MOUNTED = 0x8000,
// partitioning system specific flags
FSSH_B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD = 0x0100,
FSSH_B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD = 0x0200,
FSSH_B_DISK_SYSTEM_SUPPORTS_SETTING_NAME = 0x0400,
FSSH_B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE = 0x0800,
FSSH_B_DISK_SYSTEM_SUPPORTS_SETTING_PARAMETERS = 0x1000,
FSSH_B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD = 0x2000,
FSSH_B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD = 0x4000,
FSSH_B_DISK_SYSTEM_SUPPORTS_INITIALIZING = 0x8000,
};
// disk device job types
enum {
FSSH_B_DISK_DEVICE_JOB_BAD_TYPE,
FSSH_B_DISK_DEVICE_JOB_DEFRAGMENT,
FSSH_B_DISK_DEVICE_JOB_REPAIR,
FSSH_B_DISK_DEVICE_JOB_RESIZE,
FSSH_B_DISK_DEVICE_JOB_MOVE,
FSSH_B_DISK_DEVICE_JOB_SET_NAME,
FSSH_B_DISK_DEVICE_JOB_SET_CONTENT_NAME,
FSSH_B_DISK_DEVICE_JOB_SET_TYPE,
FSSH_B_DISK_DEVICE_JOB_SET_PARMETERS,
FSSH_B_DISK_DEVICE_JOB_SET_CONTENT_PARMETERS,
FSSH_B_DISK_DEVICE_JOB_INITIALIZE,
FSSH_B_DISK_DEVICE_JOB_UNINITIALIZE,
FSSH_B_DISK_DEVICE_JOB_CREATE,
FSSH_B_DISK_DEVICE_JOB_DELETE,
FSSH_B_DISK_DEVICE_JOB_SCAN,
};
// disk device job statuses
enum {
FSSH_B_DISK_DEVICE_JOB_UNINITIALIZED,
FSSH_B_DISK_DEVICE_JOB_SCHEDULED,
FSSH_B_DISK_DEVICE_JOB_IN_PROGRESS,
FSSH_B_DISK_DEVICE_JOB_SUCCEEDED,
FSSH_B_DISK_DEVICE_JOB_FAILED,
FSSH_B_DISK_DEVICE_JOB_CANCELED,
};
// disk device job progress info
typedef struct fssh_disk_device_job_progress_info {
uint32_t status;
uint32_t interrupt_properties;
int32_t task_count;
int32_t completed_tasks;
float current_task_progress;
char current_task_description[256];
} fssh_disk_device_job_progress_info;
// disk device job interrupt properties
enum {
FSSH_B_DISK_DEVICE_JOB_CAN_CANCEL = 0x01,
FSSH_B_DISK_DEVICE_JOB_STOP_ON_CANCEL = 0x02,
FSSH_B_DISK_DEVICE_JOB_REVERSE_ON_CANCEL = 0x04,
FSSH_B_DISK_DEVICE_JOB_CAN_PAUSE = 0x08,
};
// string length constants, all of which include the NULL terminator
#define FSSH_B_DISK_DEVICE_TYPE_LENGTH FSSH_B_FILE_NAME_LENGTH
#define FSSH_B_DISK_DEVICE_NAME_LENGTH FSSH_B_FILE_NAME_LENGTH
#define FSSH_B_DISK_SYSTEM_NAME_LENGTH FSSH_B_PATH_NAME_LENGTH
// max size of parameter string buffers, including NULL terminator
#define FSSH_B_DISK_DEVICE_MAX_PARAMETER_SIZE (32 * 1024)
#endif // _FSSH_DISK_DEVICE_DEFS_H
@@ -0,0 +1,134 @@
/*
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_DISK_DEVICE_MANAGER_H
#define _FSSH_DISK_DEVICE_MANAGER_H
#include "fssh_disk_device_defs.h"
#include "fssh_drivers.h"
#ifdef __cplusplus
extern "C" {
#endif
// C API partition representation
// Fields marked [sys] are set by the system and are not to be changed by
// the disk system modules.
typedef struct fssh_partition_data {
fssh_partition_id id; // [sys]
fssh_off_t offset;
fssh_off_t size;
fssh_off_t content_size;
uint32_t block_size;
int32_t child_count;
int32_t index; // [sys]
uint32_t status;
uint32_t flags;
fssh_dev_t volume; // [sys]
void *mount_cookie; // [sys]
char *name; // max: B_OS_NAME_LENGTH
char *content_name; //
char *type; //
const char *content_type; // [sys]
char *parameters;
char *content_parameters;
void *cookie;
void *content_cookie;
} fssh_partition_data;
// C API disk device representation
typedef struct fssh_disk_device_data {
fssh_partition_id id; // equal to that of the root partition
uint32_t flags;
char *path;
fssh_device_geometry geometry;
} fssh_disk_device_data;
// C API partitionable space representation
typedef struct fssh_partitionable_space_data {
fssh_off_t offset;
fssh_off_t size;
} fssh_partitionable_space_data;
// operations on partitions
enum {
FSSH_B_PARTITION_DEFRAGMENT,
FSSH_B_PARTITION_REPAIR,
FSSH_B_PARTITION_RESIZE,
FSSH_B_PARTITION_RESIZE_CHILD,
FSSH_B_PARTITION_MOVE,
FSSH_B_PARTITION_MOVE_CHILD,
FSSH_B_PARTITION_SET_NAME,
FSSH_B_PARTITION_SET_CONTENT_NAME,
FSSH_B_PARTITION_SET_TYPE,
FSSH_B_PARTITION_SET_PARAMETERS,
FSSH_B_PARTITION_SET_CONTENT_PARAMETERS,
FSSH_B_PARTITION_INITIALIZE,
FSSH_B_PARTITION_CREATE_CHILD,
FSSH_B_PARTITION_DELETE_CHILD,
};
// disk device job cancel status
enum {
FSSH_B_DISK_DEVICE_JOB_CONTINUE,
FSSH_B_DISK_DEVICE_JOB_CANCEL,
FSSH_B_DISK_DEVICE_JOB_REVERSE,
};
// disk device locking
fssh_disk_device_data* fssh_write_lock_disk_device(
fssh_partition_id partitionID);
void fssh_write_unlock_disk_device(
fssh_partition_id partitionID);
fssh_disk_device_data* fssh_read_lock_disk_device(
fssh_partition_id partitionID);
void fssh_read_unlock_disk_device(
fssh_partition_id partitionID);
// parameter is the ID of any partition on the device
// getting disk devices/partitions by path
// (no locking required)
int32_t fssh_find_disk_device(const char *path);
int32_t fssh_find_partition(const char *path);
// disk device/partition read access
// (read lock required)
fssh_disk_device_data* fssh_get_disk_device(fssh_partition_id partitionID);
fssh_partition_data* fssh_get_partition(fssh_partition_id partitionID);
fssh_partition_data* fssh_get_parent_partition(
fssh_partition_id partitionID);
fssh_partition_data* fssh_get_child_partition(fssh_partition_id partitionID,
int32_t index);
// partition write access
// (write lock required)
fssh_partition_data* fssh_create_child_partition(
fssh_partition_id partitionID, int32_t index,
fssh_partition_id childID);
// childID is an optional input parameter -- -1 to be ignored
bool fssh_delete_partition(fssh_partition_id partitionID);
void fssh_partition_modified(fssh_partition_id partitionID);
// tells the disk device manager, that the parition has been modified
// disk systems
fssh_disk_system_id fssh_find_disk_system(const char *name);
// jobs
bool fssh_update_disk_device_job_progress(fssh_disk_job_id jobID,
float progress);
bool fssh_update_disk_device_job_extra_progress(fssh_disk_job_id jobID,
const char *info);
bool fssh_set_disk_device_job_error_message(fssh_disk_job_id jobID,
const char *message);
uint32_t fssh_update_disk_device_job_interrupt_properties(
fssh_disk_job_id jobID, uint32_t interruptProperties);
// returns one of B_DISK_DEVICE_JOB_{CONTINUE,CANCEL,REVERSE}
#ifdef __cplusplus
}
#endif
#endif // _FSSH_DISK_DEVICE_MANAGER_H
+217
View File
@@ -0,0 +1,217 @@
#ifndef _FSSH_DRIVERS_DRIVERS_H
#define _FSSH_DRIVERS_DRIVERS_H
#include "fssh_defs.h"
#include "fssh_fs_interface.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ---
these hooks are how the kernel accesses the device
--- */
typedef fssh_status_t (*fssh_device_open_hook) (const char *name,
uint32_t flags, void **cookie);
typedef fssh_status_t (*fssh_device_close_hook) (void *cookie);
typedef fssh_status_t (*fssh_device_free_hook) (void *cookie);
typedef fssh_status_t (*fssh_device_control_hook) (void *cookie, uint32_t op,
void *data, fssh_size_t len);
typedef fssh_status_t (*fssh_device_read_hook) (void *cookie,
fssh_off_t position, void *data,
fssh_size_t *numBytes);
typedef fssh_status_t (*fssh_device_write_hook) (void *cookie,
fssh_off_t position, const void *data,
fssh_size_t *numBytes);
typedef fssh_status_t (*fssh_device_select_hook) (void *cookie, uint8_t event,
uint32_t ref, fssh_selectsync *sync);
typedef fssh_status_t (*fssh_device_deselect_hook) (void *cookie, uint8_t event,
fssh_selectsync *sync);
typedef fssh_status_t (*fssh_device_read_pages_hook)(void *cookie,
fssh_off_t position, const fssh_iovec *vec,
fssh_size_t count, fssh_size_t *_numBytes);
typedef fssh_status_t (*fssh_device_write_pages_hook) (void *cookie,
fssh_off_t position, const fssh_iovec *vec,
fssh_size_t count, fssh_size_t *_numBytes);
#define FSSH_B_CUR_DRIVER_API_VERSION 2
/* ---
the device_hooks structure is a descriptor for the device, giving its
entry points.
--- */
typedef struct {
fssh_device_open_hook open; /* called to open the device */
fssh_device_close_hook close; /* called to close the device */
fssh_device_free_hook free; /* called to free the cookie */
fssh_device_control_hook control; /* called to control the device */
fssh_device_read_hook read; /* reads from the device */
fssh_device_write_hook write; /* writes to the device */
fssh_device_select_hook select; /* start select */
fssh_device_deselect_hook deselect; /* stop select */
fssh_device_read_pages_hook read_pages; /* scatter-gather physical read from the device */
fssh_device_write_pages_hook write_pages; /* scatter-gather physical write to the device */
} fssh_device_hooks;
fssh_status_t fssh_init_hardware(void);
const char **fssh_publish_devices(void);
fssh_device_hooks *fssh_find_device(const char *name);
fssh_status_t fssh_init_driver(void);
void fssh_uninit_driver(void);
extern int32_t fssh_api_version;
enum {
FSSH_B_GET_DEVICE_SIZE = 1, /* get # bytes */
/* returns size_t in *data */
FSSH_B_SET_DEVICE_SIZE, /* set # bytes */
/* passed size_t in *data */
FSSH_B_SET_NONBLOCKING_IO, /* set to non-blocking i/o */
FSSH_B_SET_BLOCKING_IO, /* set to blocking i/o */
FSSH_B_GET_READ_STATUS, /* check if can read w/o blocking */
/* returns bool in *data */
FSSH_B_GET_WRITE_STATUS, /* check if can write w/o blocking */
/* returns bool in *data */
FSSH_B_GET_GEOMETRY, /* get info about device geometry */
/* returns struct geometry in *data */
FSSH_B_GET_DRIVER_FOR_DEVICE, /* get the path of the executable serving that device */
FSSH_B_GET_PARTITION_INFO, /* get info about a device partition */
/* returns struct partition_info in *data */
FSSH_B_SET_PARTITION, /* create a user-defined partition */
FSSH_B_FORMAT_DEVICE, /* low-level device format */
FSSH_B_EJECT_DEVICE, /* eject the media if supported */
FSSH_B_GET_ICON, /* return device icon (see struct below) */
FSSH_B_GET_BIOS_GEOMETRY, /* get info about device geometry */
/* as reported by the bios */
/* returns struct geometry in *data */
FSSH_B_GET_MEDIA_STATUS, /* get status of media. */
/* return fssh_status_t in *data: */
/* B_NO_ERROR: media ready */
/* B_DEV_NO_MEDIA: no media */
/* B_DEV_NOT_READY: device not ready */
/* B_DEV_MEDIA_CHANGED: media changed */
/* since open or last B_GET_MEDIA_STATUS */
/* B_DEV_MEDIA_CHANGE_REQUESTED: user */
/* pressed button on drive */
/* B_DEV_DOOR_OPEN: door open */
FSSH_B_LOAD_MEDIA, /* load the media if supported */
FSSH_B_GET_BIOS_DRIVE_ID, /* get bios id for this device */
FSSH_B_SET_UNINTERRUPTABLE_IO, /* prevent cntl-C from interrupting i/o */
FSSH_B_SET_INTERRUPTABLE_IO, /* allow cntl-C to interrupt i/o */
FSSH_B_FLUSH_DRIVE_CACHE, /* flush drive cache */
FSSH_B_GET_PATH_FOR_DEVICE, /* get the absolute path of the device */
FSSH_B_GET_NEXT_OPEN_DEVICE = 1000, /* iterate through open devices */
FSSH_B_ADD_FIXED_DRIVER, /* private */
FSSH_B_REMOVE_FIXED_DRIVER, /* private */
FSSH_B_AUDIO_DRIVER_BASE = 8000, /* base for codes in audio_driver.h */
FSSH_B_MIDI_DRIVER_BASE = 8100, /* base for codes in midi_driver.h */
FSSH_B_JOYSTICK_DRIVER_BASE = 8200, /* base for codes in joystick.h */
FSSH_B_GRAPHIC_DRIVER_BASE = 8300, /* base for codes in graphic_driver.h */
FSSH_B_DEVICE_OP_CODES_END = 9999 /* end of Be-defined contol id's */
};
/* ---
geometry structure for the B_GET_GEOMETRY opcode
--- */
typedef struct {
uint32_t bytes_per_sector; /* sector size in bytes */
uint32_t sectors_per_track; /* # sectors per track */
uint32_t cylinder_count; /* # cylinders */
uint32_t head_count; /* # heads */
uint8_t device_type; /* type */
bool removable; /* non-zero if removable */
bool read_only; /* non-zero if read only */
bool write_once; /* non-zero if write-once */
} fssh_device_geometry;
/* ---
Be-defined device types returned by B_GET_GEOMETRY. Use these if it makes
sense for your device.
--- */
enum {
FSSH_B_DISK = 0, /* Hard disks, floppy disks, etc. */
FSSH_B_TAPE, /* Tape drives */
FSSH_B_PRINTER, /* Printers */
FSSH_B_CPU, /* CPU devices */
FSSH_B_WORM, /* Write-once, read-many devices */
FSSH_B_CD, /* CD ROMS */
FSSH_B_SCANNER, /* Scanners */
FSSH_B_OPTICAL, /* Optical devices */
FSSH_B_JUKEBOX, /* Jukeboxes */
FSSH_B_NETWORK /* Network devices */
};
/* ---
partition_info structure used by B_GET_PARTITION_INFO and B_SET_PARTITION
--- */
typedef struct {
fssh_off_t offset; /* offset (in bytes) */
fssh_off_t size; /* size (in bytes) */
int32_t logical_block_size; /* logical block size of partition */
int32_t session; /* id of session */
int32_t partition; /* id of partition */
char device[256]; /* path to the physical device */
} fssh_partition_info;
/* ---
driver_path structure returned by the B_GET_DRIVER_FOR_DEVICE
--- */
typedef char fssh_driver_path[256];
/* ---
open_device_iterator structure used by the B_GET_NEXT_OPEN_DEVICE opcode
--- */
typedef struct {
uint32_t cookie; /* must be set to 0 before iterating */
char device[256]; /* device path */
} fssh_open_device_iterator;
/* ---
icon structure for the B_GET_ICON opcode
--- */
typedef struct {
int32_t icon_size; /* icon size requested */
void *icon_data; /* where to put 'em (usually BBitmap->Bits()) */
} fssh_device_icon;
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_DRIVERS_DRIVERS_H */
+25
View File
@@ -0,0 +1,25 @@
#ifndef _FSSH_ERRNO_H
#define _FSSH_ERRNO_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "fssh_errors.h"
#define FSSH_ENOERR 0
#define FSSH_EOK FSSH_ENOERR /* some code assumes EOK exists */
extern int *_fssh_errnop(void);
#define fssh_errno (*(_fssh_errnop()))
extern int fssh_get_errno(void);
extern void fssh_set_errno(int error);
#ifdef __cplusplus
} /* "C" */
#endif
#endif /* _FSSH_ERRNO_H */
+283
View File
@@ -0,0 +1,283 @@
/*
* Copyright 2007, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_ERRORS_H
#define _FSSH_ERRORS_H
#include <limits.h>
/* Error baselines */
#define FSSH_B_GENERAL_ERROR_BASE LONG_MIN
#define FSSH_B_OS_ERROR_BASE FSSH_B_GENERAL_ERROR_BASE + 0x1000
#define FSSH_B_APP_ERROR_BASE FSSH_B_GENERAL_ERROR_BASE + 0x2000
#define FSSH_B_INTERFACE_ERROR_BASE FSSH_B_GENERAL_ERROR_BASE + 0x3000
#define FSSH_B_MEDIA_ERROR_BASE FSSH_B_GENERAL_ERROR_BASE + 0x4000 /* - 0x41ff */
#define FSSH_B_TRANSLATION_ERROR_BASE FSSH_B_GENERAL_ERROR_BASE + 0x4800 /* - 0x48ff */
#define FSSH_B_MIDI_ERROR_BASE FSSH_B_GENERAL_ERROR_BASE + 0x5000
#define FSSH_B_STORAGE_ERROR_BASE FSSH_B_GENERAL_ERROR_BASE + 0x6000
#define FSSH_B_POSIX_ERROR_BASE FSSH_B_GENERAL_ERROR_BASE + 0x7000
#define FSSH_B_MAIL_ERROR_BASE FSSH_B_GENERAL_ERROR_BASE + 0x8000
#define FSSH_B_PRINT_ERROR_BASE FSSH_B_GENERAL_ERROR_BASE + 0x9000
#define FSSH_B_DEVICE_ERROR_BASE FSSH_B_GENERAL_ERROR_BASE + 0xa000
/* Developer-defined errors start at (B_ERRORS_END+1) */
#define FSSH_B_ERRORS_END (FSSH_B_GENERAL_ERROR_BASE + 0xffff)
/* General Errors */
enum {
FSSH_B_NO_MEMORY = FSSH_B_GENERAL_ERROR_BASE,
FSSH_B_IO_ERROR,
FSSH_B_PERMISSION_DENIED,
FSSH_B_BAD_INDEX,
FSSH_B_BAD_TYPE,
FSSH_B_BAD_VALUE,
FSSH_B_MISMATCHED_VALUES,
FSSH_B_NAME_NOT_FOUND,
FSSH_B_NAME_IN_USE,
FSSH_B_TIMED_OUT,
FSSH_B_INTERRUPTED,
FSSH_B_WOULD_BLOCK,
FSSH_B_CANCELED,
FSSH_B_NO_INIT,
FSSH_B_BUSY,
FSSH_B_NOT_ALLOWED,
FSSH_B_BAD_DATA,
FSSH_B_DONT_DO_THAT,
FSSH_B_ERROR = -1,
FSSH_B_OK = 0,
FSSH_B_NO_ERROR = 0
};
/* Kernel Kit Errors */
enum {
FSSH_B_BAD_SEM_ID = FSSH_B_OS_ERROR_BASE,
FSSH_B_NO_MORE_SEMS,
FSSH_B_BAD_THREAD_ID = FSSH_B_OS_ERROR_BASE + 0x100,
FSSH_B_NO_MORE_THREADS,
FSSH_B_BAD_THREAD_STATE,
FSSH_B_BAD_TEAM_ID,
FSSH_B_NO_MORE_TEAMS,
FSSH_B_BAD_PORT_ID = FSSH_B_OS_ERROR_BASE + 0x200,
FSSH_B_NO_MORE_PORTS,
FSSH_B_BAD_IMAGE_ID = FSSH_B_OS_ERROR_BASE + 0x300,
FSSH_B_BAD_ADDRESS,
FSSH_B_NOT_AN_EXECUTABLE,
FSSH_B_MISSING_LIBRARY,
FSSH_B_MISSING_SYMBOL,
FSSH_B_DEBUGGER_ALREADY_INSTALLED = FSSH_B_OS_ERROR_BASE + 0x400
};
/* Application Kit Errors */
enum {
FSSH_B_BAD_REPLY = FSSH_B_APP_ERROR_BASE,
FSSH_B_DUPLICATE_REPLY,
FSSH_B_MESSAGE_TO_SELF,
FSSH_B_BAD_HANDLER,
FSSH_B_ALREADY_RUNNING,
FSSH_B_LAUNCH_FAILED,
FSSH_B_AMBIGUOUS_APP_LAUNCH,
FSSH_B_UNKNOWN_MIME_TYPE,
FSSH_B_BAD_SCRIPT_SYNTAX,
FSSH_B_LAUNCH_FAILED_NO_RESOLVE_LINK,
FSSH_B_LAUNCH_FAILED_EXECUTABLE,
FSSH_B_LAUNCH_FAILED_APP_NOT_FOUND,
FSSH_B_LAUNCH_FAILED_APP_IN_TRASH,
FSSH_B_LAUNCH_FAILED_NO_PREFERRED_APP,
FSSH_B_LAUNCH_FAILED_FILES_APP_NOT_FOUND,
FSSH_B_BAD_MIME_SNIFFER_RULE,
FSSH_B_NOT_A_MESSAGE,
FSSH_B_SHUTDOWN_CANCELLED,
FSSH_B_SHUTTING_DOWN
};
/* Storage Kit/File System Errors */
enum {
FSSH_B_FILE_ERROR = FSSH_B_STORAGE_ERROR_BASE,
FSSH_B_FILE_NOT_FOUND, /* deprecated: use FSSH_B_ENTRY_NOT_FOUND instead */
FSSH_B_FILE_EXISTS,
FSSH_B_ENTRY_NOT_FOUND,
FSSH_B_NAME_TOO_LONG,
FSSH_B_NOT_A_DIRECTORY,
FSSH_B_DIRECTORY_NOT_EMPTY,
FSSH_B_DEVICE_FULL,
FSSH_B_READ_ONLY_DEVICE,
FSSH_B_IS_A_DIRECTORY,
FSSH_B_NO_MORE_FDS,
FSSH_B_CROSS_DEVICE_LINK,
FSSH_B_LINK_LIMIT,
FSSH_B_BUSTED_PIPE,
FSSH_B_UNSUPPORTED,
FSSH_B_PARTITION_TOO_SMALL
};
/* POSIX Errors */
#define FSSH_E2BIG (FSSH_B_POSIX_ERROR_BASE + 1)
#define FSSH_ECHILD (FSSH_B_POSIX_ERROR_BASE + 2)
#define FSSH_EDEADLK (FSSH_B_POSIX_ERROR_BASE + 3)
#define FSSH_EFBIG (FSSH_B_POSIX_ERROR_BASE + 4)
#define FSSH_EMLINK (FSSH_B_POSIX_ERROR_BASE + 5)
#define FSSH_ENFILE (FSSH_B_POSIX_ERROR_BASE + 6)
#define FSSH_ENODEV (FSSH_B_POSIX_ERROR_BASE + 7)
#define FSSH_ENOLCK (FSSH_B_POSIX_ERROR_BASE + 8)
#define FSSH_ENOSYS (FSSH_B_POSIX_ERROR_BASE + 9)
#define FSSH_ENOTTY (FSSH_B_POSIX_ERROR_BASE + 10)
#define FSSH_ENXIO (FSSH_B_POSIX_ERROR_BASE + 11)
#define FSSH_ESPIPE (FSSH_B_POSIX_ERROR_BASE + 12)
#define FSSH_ESRCH (FSSH_B_POSIX_ERROR_BASE + 13)
#define FSSH_EFPOS (FSSH_B_POSIX_ERROR_BASE + 14)
#define FSSH_ESIGPARM (FSSH_B_POSIX_ERROR_BASE + 15)
#define FSSH_EDOM (FSSH_B_POSIX_ERROR_BASE + 16)
#define FSSH_ERANGE (FSSH_B_POSIX_ERROR_BASE + 17)
#define FSSH_EPROTOTYPE (FSSH_B_POSIX_ERROR_BASE + 18)
#define FSSH_EPROTONOSUPPORT (FSSH_B_POSIX_ERROR_BASE + 19)
#define FSSH_EPFNOSUPPORT (FSSH_B_POSIX_ERROR_BASE + 20)
#define FSSH_EAFNOSUPPORT (FSSH_B_POSIX_ERROR_BASE + 21)
#define FSSH_EADDRINUSE (FSSH_B_POSIX_ERROR_BASE + 22)
#define FSSH_EADDRNOTAVAIL (FSSH_B_POSIX_ERROR_BASE + 23)
#define FSSH_ENETDOWN (FSSH_B_POSIX_ERROR_BASE + 24)
#define FSSH_ENETUNREACH (FSSH_B_POSIX_ERROR_BASE + 25)
#define FSSH_ENETRESET (FSSH_B_POSIX_ERROR_BASE + 26)
#define FSSH_ECONNABORTED (FSSH_B_POSIX_ERROR_BASE + 27)
#define FSSH_ECONNRESET (FSSH_B_POSIX_ERROR_BASE + 28)
#define FSSH_EISCONN (FSSH_B_POSIX_ERROR_BASE + 29)
#define FSSH_ENOTCONN (FSSH_B_POSIX_ERROR_BASE + 30)
#define FSSH_ESHUTDOWN (FSSH_B_POSIX_ERROR_BASE + 31)
#define FSSH_ECONNREFUSED (FSSH_B_POSIX_ERROR_BASE + 32)
#define FSSH_EHOSTUNREACH (FSSH_B_POSIX_ERROR_BASE + 33)
#define FSSH_ENOPROTOOPT (FSSH_B_POSIX_ERROR_BASE + 34)
#define FSSH_ENOBUFS (FSSH_B_POSIX_ERROR_BASE + 35)
#define FSSH_EINPROGRESS (FSSH_B_POSIX_ERROR_BASE + 36)
#define FSSH_EALREADY (FSSH_B_POSIX_ERROR_BASE + 37)
#define FSSH_EILSEQ (FSSH_B_POSIX_ERROR_BASE + 38)
#define FSSH_ENOMSG (FSSH_B_POSIX_ERROR_BASE + 39)
#define FSSH_ESTALE (FSSH_B_POSIX_ERROR_BASE + 40)
#define FSSH_EOVERFLOW (FSSH_B_POSIX_ERROR_BASE + 41)
#define FSSH_EMSGSIZE (FSSH_B_POSIX_ERROR_BASE + 42)
#define FSSH_EOPNOTSUPP (FSSH_B_POSIX_ERROR_BASE + 43)
#define FSSH_ENOTSOCK (FSSH_B_POSIX_ERROR_BASE + 44)
#define FSSH_EHOSTDOWN (FSSH_B_POSIX_ERROR_BASE + 45)
#define FSSH_EBADMSG (FSSH_B_POSIX_ERROR_BASE + 46)
#define FSSH_ECANCELED (FSSH_B_POSIX_ERROR_BASE + 47)
#define FSSH_EDESTADDRREQ (FSSH_B_POSIX_ERROR_BASE + 48)
#define FSSH_EDQUOT (FSSH_B_POSIX_ERROR_BASE + 49)
#define FSSH_EIDRM (FSSH_B_POSIX_ERROR_BASE + 50)
#define FSSH_EMULTIHOP (FSSH_B_POSIX_ERROR_BASE + 51)
#define FSSH_ENODATA (FSSH_B_POSIX_ERROR_BASE + 52)
#define FSSH_ENOLINK (FSSH_B_POSIX_ERROR_BASE + 53)
#define FSSH_ENOSR (FSSH_B_POSIX_ERROR_BASE + 54)
#define FSSH_ENOSTR (FSSH_B_POSIX_ERROR_BASE + 55)
#define FSSH_ENOTSUP (FSSH_B_POSIX_ERROR_BASE + 56)
#define FSSH_EPROTO (FSSH_B_POSIX_ERROR_BASE + 57)
#define FSSH_ETIME (FSSH_B_POSIX_ERROR_BASE + 58)
#define FSSH_ETXTBSY (FSSH_B_POSIX_ERROR_BASE + 59)
/* POSIX errors that can be mapped to BeOS error codes */
#define FSSH_ENOMEM FSSH_B_NO_MEMORY
#define FSSH_EACCES FSSH_B_PERMISSION_DENIED
#define FSSH_EINTR FSSH_B_INTERRUPTED
#define FSSH_EIO FSSH_B_IO_ERROR
#define FSSH_EBUSY FSSH_B_BUSY
#define FSSH_EFAULT FSSH_B_BAD_ADDRESS
#define FSSH_ETIMEDOUT FSSH_B_TIMED_OUT
#define FSSH_EAGAIN FSSH_B_WOULD_BLOCK /* SysV compatibility */
#define FSSH_EWOULDBLOCK FSSH_B_WOULD_BLOCK /* BSD compatibility */
#define FSSH_EBADF FSSH_B_FILE_ERROR
#define FSSH_EEXIST FSSH_B_FILE_EXISTS
#define FSSH_EINVAL FSSH_B_BAD_VALUE
#define FSSH_ENAMETOOLONG FSSH_B_NAME_TOO_LONG
#define FSSH_ENOENT FSSH_B_ENTRY_NOT_FOUND
#define FSSH_EPERM FSSH_B_NOT_ALLOWED
#define FSSH_ENOTDIR FSSH_B_NOT_A_DIRECTORY
#define FSSH_EISDIR FSSH_B_IS_A_DIRECTORY
#define FSSH_ENOTEMPTY FSSH_B_DIRECTORY_NOT_EMPTY
#define FSSH_ENOSPC FSSH_B_DEVICE_FULL
#define FSSH_EROFS FSSH_B_READ_ONLY_DEVICE
#define FSSH_EMFILE FSSH_B_NO_MORE_FDS
#define FSSH_EXDEV FSSH_B_CROSS_DEVICE_LINK
#define FSSH_ELOOP FSSH_B_LINK_LIMIT
#define FSSH_ENOEXEC FSSH_B_NOT_AN_EXECUTABLE
#define FSSH_EPIPE FSSH_B_BUSTED_PIPE
/* new error codes that can be mapped to POSIX errors */
#define FSSH_B_BUFFER_OVERFLOW FSSH_EOVERFLOW
#define FSSH_B_TOO_MANY_ARGS FSSH_E2BIG
#define FSSH_B_FILE_TOO_LARGE FSSH_EFBIG
#define FSSH_B_RESULT_NOT_REPRESENTABLE FSSH_ERANGE
#define FSSH_B_DEVICE_NOT_FOUND FSSH_ENODEV
#define FSSH_B_NOT_SUPPORTED FSSH_EOPNOTSUPP
/* Media Kit Errors */
enum {
FSSH_B_STREAM_NOT_FOUND = FSSH_B_MEDIA_ERROR_BASE,
FSSH_B_SERVER_NOT_FOUND,
FSSH_B_RESOURCE_NOT_FOUND,
FSSH_B_RESOURCE_UNAVAILABLE,
FSSH_B_BAD_SUBSCRIBER,
FSSH_B_SUBSCRIBER_NOT_ENTERED,
FSSH_B_BUFFER_NOT_AVAILABLE,
FSSH_B_LAST_BUFFER_ERROR
};
/* Mail Kit Errors */
enum {
FSSH_B_MAIL_NO_DAEMON = FSSH_B_MAIL_ERROR_BASE,
FSSH_B_MAIL_UNKNOWN_USER,
FSSH_B_MAIL_WRONG_PASSWORD,
FSSH_B_MAIL_UNKNOWN_HOST,
FSSH_B_MAIL_ACCESS_ERROR,
FSSH_B_MAIL_UNKNOWN_FIELD,
FSSH_B_MAIL_NO_RECIPIENT,
FSSH_B_MAIL_INVALID_MAIL
};
/* Printing Errors */
enum {
FSSH_B_NO_PRINT_SERVER = FSSH_B_PRINT_ERROR_BASE
};
/* Device Kit Errors */
enum {
FSSH_B_DEV_INVALID_IOCTL = FSSH_B_DEVICE_ERROR_BASE,
FSSH_B_DEV_NO_MEMORY,
FSSH_B_DEV_BAD_DRIVE_NUM,
FSSH_B_DEV_NO_MEDIA,
FSSH_B_DEV_UNREADABLE,
FSSH_B_DEV_FORMAT_ERROR,
FSSH_B_DEV_TIMEOUT,
FSSH_B_DEV_RECALIBRATE_ERROR,
FSSH_B_DEV_SEEK_ERROR,
FSSH_B_DEV_ID_ERROR,
FSSH_B_DEV_READ_ERROR,
FSSH_B_DEV_WRITE_ERROR,
FSSH_B_DEV_NOT_READY,
FSSH_B_DEV_MEDIA_CHANGED,
FSSH_B_DEV_MEDIA_CHANGE_REQUESTED,
FSSH_B_DEV_RESOURCE_CONFLICT,
FSSH_B_DEV_CONFIGURATION_ERROR,
FSSH_B_DEV_DISABLED_BY_USER,
FSSH_B_DEV_DOOR_OPEN,
FSSH_B_DEV_INVALID_PIPE,
FSSH_B_DEV_CRC_ERROR,
FSSH_B_DEV_STALLED,
FSSH_B_DEV_BAD_PID,
FSSH_B_DEV_UNEXPECTED_PID,
FSSH_B_DEV_DATA_OVERRUN,
FSSH_B_DEV_DATA_UNDERRUN,
FSSH_B_DEV_FIFO_OVERRUN,
FSSH_B_DEV_FIFO_UNDERRUN,
FSSH_B_DEV_PENDING,
FSSH_B_DEV_MULTIPLE_ERRORS,
FSSH_B_DEV_TOO_LATE
};
#endif /* _FSSH_ERRORS_H */
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright 2002-2007, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_FCNTL_H
#define _FSSH_FCNTL_H
#include "fssh_types.h"
/* commands that can be passed to fcntl() */
#define FSSH_F_DUPFD 0x0001 /* duplicate fd */
#define FSSH_F_GETFD 0x0002 /* get fd flags */
#define FSSH_F_SETFD 0x0004 /* set fd flags */
#define FSSH_F_GETFL 0x0008 /* get file status flags and access mode */
#define FSSH_F_SETFL 0x0010 /* set file status flags */
#define FSSH_F_GETLK 0x0020 /* get locking information */
#define FSSH_F_SETLK 0x0080 /* set locking information */
#define FSSH_F_SETLKW 0x0100 /* as above, but waits if blocked */
/* advisory locking types */
#define FSSH_F_RDLCK 0x0040 /* read or shared lock */
#define FSSH_F_UNLCK 0x0200 /* unlock */
#define FSSH_F_WRLCK 0x0400 /* write or exclusive lock */
/* file descriptor flags for fcntl() */
#define FSSH_FD_CLOEXEC 1 /* close on exec */
/* file access modes for open() */
#define FSSH_O_RDONLY 0x0000 /* read only */
#define FSSH_O_WRONLY 0x0001 /* write only */
#define FSSH_O_RDWR 0x0002 /* read and write */
#define FSSH_O_ACCMODE 0x0003 /* mask to get the access modes above */
#define FSSH_O_RWMASK FSSH_O_ACCMODE
/* flags for open() */
#define FSSH_O_EXCL 0x0100 /* exclusive creat */
#define FSSH_O_CREAT 0x0200 /* create and open file */
#define FSSH_O_TRUNC 0x0400 /* open with truncation */
#define FSSH_O_NOCTTY 0x1000 /* currently unsupported */
#define FSSH_O_NOTRAVERSE 0x2000 /* do not traverse leaf link */
/* flags for open() and fcntl() */
#define FSSH_O_CLOEXEC 0x00000040 /* close on exec */
#define FSSH_O_NONBLOCK 0x00000080 /* non blocking io */
#define FSSH_O_APPEND 0x00000800 /* to end of file */
#define FSSH_O_TEXT 0x00004000 /* CR-LF translation */
#define FSSH_O_BINARY 0x00008000 /* no translation */
#define FSSH_O_SYNC 0x00010000 /* write synchronized I/O file integrity */
#define FSSH_O_RSYNC 0x00020000 /* read synchronized I/O file integrity */
#define FSSH_O_DSYNC 0x00040000 /* write synchronized I/O data integrity */
// TODO: currently not implemented additions:
#define FSSH_O_NOFOLLOW 0x00080000
/* should we implement this? it's similar to O_NOTRAVERSE but will fail on symlinks */
#define FSSH_O_NOCACHE 0x00100000 /* doesn't use the file system cache if possible */
#define FSSH_O_DIRECT FSSH_O_NOCACHE
#define FSSH_O_MOUNT 0x00200000 /* for file systems */
#define FSSH_O_TEMPORARY 0x00400000 /* used to avoid writing temporary files to disk */
#define FSSH_O_SHLOCK 0x01000000 /* obtain shared lock */
#define FSSH_O_EXLOCK 0x02000000 /* obtain exclusive lock */
#define FSSH_S_IREAD 0x0100 /* owner may read */
#define FSSH_S_IWRITE 0x0080 /* owner may write */
#ifdef __cplusplus
extern "C" {
#endif
extern int fssh_creat(const char *path, fssh_mode_t mode);
extern int fssh_open(const char *pathname, int oflags, ...);
/* the third argument is the permissions of the created file when O_CREAT
is passed in oflags */
extern int fssh_fcntl(int fd, int op, ...);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_FCNTL_H */
+50
View File
@@ -0,0 +1,50 @@
/* File System attributes
**
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef _FSSH_FS_ATTR_H
#define _FSSH_FS_ATTR_H
#include "fssh_defs.h"
#include "fssh_dirent.h"
typedef struct fssh_attr_info {
uint32_t type;
fssh_off_t size;
} fssh_attr_info;
#ifdef __cplusplus
extern "C" {
#endif
extern fssh_ssize_t fssh_fs_read_attr(int fd, const char *attribute,
uint32_t type, fssh_off_t pos, void *buffer,
fssh_size_t readBytes);
extern fssh_ssize_t fssh_fs_write_attr(int fd, const char *attribute,
uint32_t type, fssh_off_t pos, const void *buffer,
fssh_size_t readBytes);
extern int fssh_fs_remove_attr(int fd, const char *attribute);
extern int fssh_fs_stat_attr(int fd, const char *attribute,
struct fssh_attr_info *attrInfo);
// ToDo: the following three functions are not part of the R5 API, and
// are only preliminary - they may change or be removed at any point
//extern int fssh_fs_open_attr(const char *path, const char *attribute, uint32_t type, int openMode);
extern int fssh_fs_open_attr(int fd, const char *attribute,
uint32_t type, int openMode);
extern int fssh_fs_close_attr(int fd);
extern fssh_DIR *fssh_fs_open_attr_dir(const char *path);
extern fssh_DIR *fssh_fs_fopen_attr_dir(int fd);
extern int fssh_fs_close_attr_dir(fssh_DIR *dir);
extern struct fssh_dirent *fssh_fs_read_attr_dir(fssh_DIR *dir);
extern void fssh_fs_rewind_attr_dir(fssh_DIR *dir);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_FS_ATTR_H */
+96
View File
@@ -0,0 +1,96 @@
/*
* Copyright 2004-2007, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_FS_CACHE_H
#define _FSSH_FS_CACHE_H
//! File System File and Block Caches
#include "fssh_fs_interface.h"
typedef void (*fssh_transaction_notification_hook)(int32_t id, void *data);
#ifdef __cplusplus
extern "C" {
#endif
/* transactions */
extern int32_t fssh_cache_start_transaction(void *_cache);
extern fssh_status_t fssh_cache_sync_transaction(void *_cache, int32_t id);
extern fssh_status_t fssh_cache_end_transaction(void *_cache, int32_t id,
fssh_transaction_notification_hook hook,
void *data);
extern fssh_status_t fssh_cache_abort_transaction(void *_cache, int32_t id);
extern int32_t fssh_cache_detach_sub_transaction(void *_cache,
int32_t id, fssh_transaction_notification_hook hook,
void *data);
extern fssh_status_t fssh_cache_abort_sub_transaction(void *_cache,
int32_t id);
extern fssh_status_t fssh_cache_start_sub_transaction(void *_cache,
int32_t id);
extern fssh_status_t fssh_cache_next_block_in_transaction(void *_cache,
int32_t id, uint32_t *_cookie,
fssh_off_t *_blockNumber, void **_data,
void **_unchangedData);
extern int32_t fssh_cache_blocks_in_transaction(void *_cache,
int32_t id);
extern int32_t fssh_cache_blocks_in_sub_transaction(void *_cache,
int32_t id);
/* block cache */
extern void fssh_block_cache_delete(void *_cache, bool allowWrites);
extern void * fssh_block_cache_create(int fd, fssh_off_t numBlocks,
fssh_size_t blockSize, bool readOnly);
extern fssh_status_t fssh_block_cache_sync(void *_cache);
extern fssh_status_t fssh_block_cache_sync_etc(void *_cache,
fssh_off_t blockNumber, fssh_size_t numBlocks);
extern fssh_status_t fssh_block_cache_make_writable(void *_cache,
fssh_off_t blockNumber, int32_t transaction);
extern void * fssh_block_cache_get_writable_etc(void *_cache,
fssh_off_t blockNumber, fssh_off_t base,
fssh_off_t length, int32_t transaction);
extern void * fssh_block_cache_get_writable(void *_cache,
fssh_off_t blockNumber, int32_t transaction);
extern void * fssh_block_cache_get_empty(void *_cache,
fssh_off_t blockNumber, int32_t transaction);
extern const void * fssh_block_cache_get_etc(void *_cache,
fssh_off_t blockNumber, fssh_off_t base,
fssh_off_t length);
extern const void * fssh_block_cache_get(void *_cache,
fssh_off_t blockNumber);
extern fssh_status_t fssh_block_cache_set_dirty(void *_cache,
fssh_off_t blockNumber, bool isDirty,
int32_t transaction);
extern void fssh_block_cache_put(void *_cache,
fssh_off_t blockNumber);
/* file cache */
extern void * fssh_file_cache_create(fssh_mount_id mountID,
fssh_vnode_id vnodeID, fssh_off_t size, int fd);
extern void fssh_file_cache_delete(void *_cacheRef);
extern fssh_status_t fssh_file_cache_set_size(void *_cacheRef,
fssh_off_t size);
extern fssh_status_t fssh_file_cache_sync(void *_cache);
extern fssh_status_t fssh_file_cache_invalidate_file_map(void *_cacheRef,
fssh_off_t offset, fssh_off_t size);
extern fssh_status_t fssh_file_cache_read_pages(void *_cacheRef,
fssh_off_t offset, const fssh_iovec *vecs,
fssh_size_t count, fssh_size_t *_numBytes);
extern fssh_status_t fssh_file_cache_write_pages(void *_cacheRef,
fssh_off_t offset, const fssh_iovec *vecs,
fssh_size_t count, fssh_size_t *_numBytes);
extern fssh_status_t fssh_file_cache_read(void *_cacheRef, fssh_off_t offset,
void *bufferBase, fssh_size_t *_size);
extern fssh_status_t fssh_file_cache_write(void *_cacheRef,
fssh_off_t offset, const void *buffer,
fssh_size_t *_size);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_FS_CACHE_H */
+42
View File
@@ -0,0 +1,42 @@
/* File System indices
**
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef _FSSH_FS_INDEX_H
#define _FSSH_FS_INDEX_H
#include "fssh_defs.h"
#include "fssh_dirent.h"
typedef struct fssh_index_info {
uint32_t type;
fssh_off_t size;
fssh_time_t modification_time;
fssh_time_t creation_time;
fssh_uid_t uid;
fssh_gid_t gid;
} fssh_index_info;
#ifdef __cplusplus
extern "C" {
#endif
extern int fssh_fs_create_index(fssh_dev_t device, const char *name,
uint32_t type, uint32_t flags);
extern int fssh_fs_remove_index(fssh_dev_t device, const char *name);
extern int fssh_fs_stat_index(fssh_dev_t device, const char *name,
struct fssh_index_info *indexInfo);
extern fssh_DIR *fssh_fs_open_index_dir(fssh_dev_t device);
extern int fssh_fs_close_index_dir(fssh_DIR *indexDirectory);
extern struct fssh_dirent *fssh_fs_read_index_dir(fssh_DIR *indexDirectory);
extern void fssh_fs_rewind_index_dir(fssh_DIR *indexDirectory);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_FS_INDEX_H */
+53
View File
@@ -0,0 +1,53 @@
/* General File System informations/capabilities
**
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef _FSSH_FS_INFO_H
#define _FSSH_FS_INFO_H
#include "fssh_defs.h"
#include "fssh_os.h"
/* fs_info.flags */
#define FSSH_B_FS_IS_READONLY 0x00000001
#define FSSH_B_FS_IS_REMOVABLE 0x00000002
#define FSSH_B_FS_IS_PERSISTENT 0x00000004
#define FSSH_B_FS_IS_SHARED 0x00000008
#define FSSH_B_FS_HAS_MIME 0x00010000
#define FSSH_B_FS_HAS_ATTR 0x00020000
#define FSSH_B_FS_HAS_QUERY 0x00040000
// those additions are preliminary and may be removed
#define FSSH_B_FS_HAS_SELF_HEALING_LINKS 0x00080000
#define FSSH_B_FS_HAS_ALIASES 0x00100000
#define FSSH_B_FS_SUPPORTS_NODE_MONITORING 0x00200000
typedef struct fssh_fs_info {
fssh_dev_t dev; /* volume dev_t */
fssh_ino_t root; /* root ino_t */
uint32_t flags; /* flags (see above) */
fssh_off_t block_size; /* fundamental block size */
fssh_off_t io_size; /* optimal i/o size */
fssh_off_t total_blocks; /* total number of blocks */
fssh_off_t free_blocks; /* number of free blocks */
fssh_off_t total_nodes; /* total number of nodes */
fssh_off_t free_nodes; /* number of free nodes */
char device_name[128]; /* device holding fs */
char volume_name[FSSH_B_FILE_NAME_LENGTH]; /* volume name */
char fsh_name[FSSH_B_OS_NAME_LENGTH]; /* name of fs handler */
} fssh_fs_info;
#ifdef __cplusplus
extern "C" {
#endif
extern fssh_dev_t dev_for_path(const char *path);
extern fssh_dev_t next_dev(int32_t *pos);
extern int fs_stat_dev(fssh_dev_t dev, fssh_fs_info *info);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_FS_INFO_H */
@@ -0,0 +1,284 @@
/* File System Interface Layer Definition
*
* Copyright 2004-2006, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_FS_INTERFACE_H
#define _FSSH_FS_INTERFACE_H
#include "fssh_module.h"
#include "fssh_os.h"
struct fssh_dirent;
struct fssh_fs_info;
struct fssh_iovec;
struct fssh_partition_data;
struct fssh_selectsync;
struct fssh_stat;
typedef fssh_dev_t fssh_mount_id;
typedef fssh_ino_t fssh_vnode_id;
/* the file system's private data structures */
typedef void *fssh_fs_volume;
typedef void *fssh_fs_cookie;
typedef void *fssh_fs_vnode;
/* passed to write_stat() */
enum fssh_write_stat_mask {
FSSH_FS_WRITE_STAT_MODE = 0x0001,
FSSH_FS_WRITE_STAT_UID = 0x0002,
FSSH_FS_WRITE_STAT_GID = 0x0004,
FSSH_FS_WRITE_STAT_SIZE = 0x0008,
FSSH_FS_WRITE_STAT_ATIME = 0x0010,
FSSH_FS_WRITE_STAT_MTIME = 0x0020,
FSSH_FS_WRITE_STAT_CRTIME = 0x0040
};
/* passed to write_fs_info() */
#define FSSH_FS_WRITE_FSINFO_NAME 0x0001
struct fssh_file_io_vec {
fssh_off_t offset;
fssh_off_t length;
};
#define FSSH_B_CURRENT_FS_API_VERSION "/v1"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct fssh_file_system_module_info {
struct fssh_module_info info;
const char *pretty_name;
/* scanning (the device is write locked) */
float (*identify_partition)(int fd, fssh_partition_data *partition,
void **cookie);
fssh_status_t (*scan_partition)(int fd, fssh_partition_data *partition,
void *cookie);
void (*free_identify_partition_cookie)(fssh_partition_data *partition,
void *cookie);
void (*free_partition_content_cookie)(fssh_partition_data *partition);
/* general operations */
fssh_status_t (*mount)(fssh_mount_id id, const char *device, uint32_t flags,
const char *args, fssh_fs_volume *_fs,
fssh_vnode_id *_rootVnodeID);
fssh_status_t (*unmount)(fssh_fs_volume fs);
fssh_status_t (*read_fs_info)(fssh_fs_volume fs, struct fssh_fs_info *info);
fssh_status_t (*write_fs_info)(fssh_fs_volume fs,
const struct fssh_fs_info *info, uint32_t mask);
fssh_status_t (*sync)(fssh_fs_volume fs);
/* vnode operations */
fssh_status_t (*lookup)(fssh_fs_volume fs, fssh_fs_vnode dir,
const char *name, fssh_vnode_id *_id, int *_type);
fssh_status_t (*get_vnode_name)(fssh_fs_volume fs, fssh_fs_vnode vnode,
char *buffer, fssh_size_t bufferSize);
fssh_status_t (*get_vnode)(fssh_fs_volume fs, fssh_vnode_id id,
fssh_fs_vnode *_vnode, bool reenter);
fssh_status_t (*put_vnode)(fssh_fs_volume fs, fssh_fs_vnode vnode,
bool reenter);
fssh_status_t (*remove_vnode)(fssh_fs_volume fs, fssh_fs_vnode vnode,
bool reenter);
/* VM file access */
bool (*can_page)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie);
fssh_status_t (*read_pages)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, fssh_off_t pos, const fssh_iovec *vecs,
fssh_size_t count, fssh_size_t *_numBytes, bool reenter);
fssh_status_t (*write_pages)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, fssh_off_t pos, const fssh_iovec *vecs,
fssh_size_t count, fssh_size_t *_numBytes, bool reenter);
/* cache file access */
fssh_status_t (*get_file_map)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_off_t offset, fssh_size_t size,
struct fssh_file_io_vec *vecs, fssh_size_t *_count);
/* common operations */
fssh_status_t (*ioctl)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, fssh_ulong op, void *buffer,
fssh_size_t length);
fssh_status_t (*set_flags)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, int flags);
fssh_status_t (*select)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, uint8_t event, uint32_t ref,
fssh_selectsync *sync);
fssh_status_t (*deselect)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, uint8_t event, fssh_selectsync *sync);
fssh_status_t (*fsync)(fssh_fs_volume fs, fssh_fs_vnode vnode);
fssh_status_t (*read_symlink)(fssh_fs_volume fs, fssh_fs_vnode link,
char *buffer, fssh_size_t *_bufferSize);
fssh_status_t (*create_symlink)(fssh_fs_volume fs, fssh_fs_vnode dir,
const char *name, const char *path, int mode);
fssh_status_t (*link)(fssh_fs_volume fs, fssh_fs_vnode dir,
const char *name, fssh_fs_vnode vnode);
fssh_status_t (*unlink)(fssh_fs_volume fs, fssh_fs_vnode dir,
const char *name);
fssh_status_t (*rename)(fssh_fs_volume fs, fssh_fs_vnode fromDir,
const char *fromName, fssh_fs_vnode toDir, const char *toName);
fssh_status_t (*access)(fssh_fs_volume fs, fssh_fs_vnode vnode, int mode);
fssh_status_t (*read_stat)(fssh_fs_volume fs, fssh_fs_vnode vnode,
struct fssh_stat *stat);
fssh_status_t (*write_stat)(fssh_fs_volume fs, fssh_fs_vnode vnode,
const struct fssh_stat *stat, uint32_t statMask);
/* file operations */
fssh_status_t (*create)(fssh_fs_volume fs, fssh_fs_vnode dir,
const char *name, int openMode, int perms,
fssh_fs_cookie *_cookie, fssh_vnode_id *_newVnodeID);
fssh_status_t (*open)(fssh_fs_volume fs, fssh_fs_vnode vnode, int openMode,
fssh_fs_cookie *_cookie);
fssh_status_t (*close)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie);
fssh_status_t (*free_cookie)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie);
fssh_status_t (*read)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, fssh_off_t pos, void *buffer,
fssh_size_t *length);
fssh_status_t (*write)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, fssh_off_t pos, const void *buffer,
fssh_size_t *length);
/* directory operations */
fssh_status_t (*create_dir)(fssh_fs_volume fs, fssh_fs_vnode parent,
const char *name, int perms, fssh_vnode_id *_newVnodeID);
fssh_status_t (*remove_dir)(fssh_fs_volume fs, fssh_fs_vnode parent,
const char *name);
fssh_status_t (*open_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie *_cookie);
fssh_status_t (*close_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie);
fssh_status_t (*free_dir_cookie)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie);
fssh_status_t (*read_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, struct fssh_dirent *buffer,
fssh_size_t bufferSize, uint32_t *_num);
fssh_status_t (*rewind_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie);
/* attribute directory operations */
fssh_status_t (*open_attr_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie *_cookie);
fssh_status_t (*close_attr_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie);
fssh_status_t (*free_attr_dir_cookie)(fssh_fs_volume fs,
fssh_fs_vnode vnode, fssh_fs_cookie cookie);
fssh_status_t (*read_attr_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, struct fssh_dirent *buffer,
fssh_size_t bufferSize, uint32_t *_num);
fssh_status_t (*rewind_attr_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie);
/* attribute operations */
fssh_status_t (*create_attr)(fssh_fs_volume fs, fssh_fs_vnode vnode,
const char *name, uint32_t type, int openMode,
fssh_fs_cookie *_cookie);
fssh_status_t (*open_attr)(fssh_fs_volume fs, fssh_fs_vnode vnode,
const char *name, int openMode, fssh_fs_cookie *_cookie);
fssh_status_t (*close_attr)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie);
fssh_status_t (*free_attr_cookie)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie);
fssh_status_t (*read_attr)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, fssh_off_t pos, void *buffer,
fssh_size_t *length);
fssh_status_t (*write_attr)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, fssh_off_t pos, const void *buffer,
fssh_size_t *length);
fssh_status_t (*read_attr_stat)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, struct fssh_stat *stat);
fssh_status_t (*write_attr_stat)(fssh_fs_volume fs, fssh_fs_vnode vnode,
fssh_fs_cookie cookie, const struct fssh_stat *stat,
int statMask);
fssh_status_t (*rename_attr)(fssh_fs_volume fs, fssh_fs_vnode fromVnode,
const char *fromName, fssh_fs_vnode toVnode,
const char *toName);
fssh_status_t (*remove_attr)(fssh_fs_volume fs, fssh_fs_vnode vnode,
const char *name);
/* index directory & index operations */
fssh_status_t (*open_index_dir)(fssh_fs_volume fs, fssh_fs_cookie *cookie);
fssh_status_t (*close_index_dir)(fssh_fs_volume fs, fssh_fs_cookie cookie);
fssh_status_t (*free_index_dir_cookie)(fssh_fs_volume fs,
fssh_fs_cookie cookie);
fssh_status_t (*read_index_dir)(fssh_fs_volume fs, fssh_fs_cookie cookie,
struct fssh_dirent *buffer, fssh_size_t bufferSize,
uint32_t *_num);
fssh_status_t (*rewind_index_dir)(fssh_fs_volume fs, fssh_fs_cookie cookie);
fssh_status_t (*create_index)(fssh_fs_volume fs, const char *name,
uint32_t type, uint32_t flags);
fssh_status_t (*remove_index)(fssh_fs_volume fs, const char *name);
fssh_status_t (*read_index_stat)(fssh_fs_volume fs, const char *name,
struct fssh_stat *stat);
/* query operations */
fssh_status_t (*open_query)(fssh_fs_volume fs, const char *query,
uint32_t flags, fssh_port_id port, uint32_t token,
fssh_fs_cookie *_cookie);
fssh_status_t (*close_query)(fssh_fs_volume fs, fssh_fs_cookie cookie);
fssh_status_t (*free_query_cookie)(fssh_fs_volume fs,
fssh_fs_cookie cookie);
fssh_status_t (*read_query)(fssh_fs_volume fs, fssh_fs_cookie cookie,
struct fssh_dirent *buffer, fssh_size_t bufferSize,
uint32_t *_num);
fssh_status_t (*rewind_query)(fssh_fs_volume fs, fssh_fs_cookie cookie);
} fssh_file_system_module_info;
/* file system add-ons only prototypes */
extern fssh_status_t fssh_new_vnode(fssh_mount_id mountID,
fssh_vnode_id vnodeID, fssh_fs_vnode privateNode);
extern fssh_status_t fssh_publish_vnode(fssh_mount_id mountID,
fssh_vnode_id vnodeID, fssh_fs_vnode privateNode);
extern fssh_status_t fssh_get_vnode(fssh_mount_id mountID,
fssh_vnode_id vnodeID, fssh_fs_vnode *_privateNode);
extern fssh_status_t fssh_put_vnode(fssh_mount_id mountID,
fssh_vnode_id vnodeID);
extern fssh_status_t fssh_remove_vnode(fssh_mount_id mountID,
fssh_vnode_id vnodeID);
extern fssh_status_t fssh_unremove_vnode(fssh_mount_id mountID,
fssh_vnode_id vnodeID);
extern fssh_status_t fssh_get_vnode_removed(fssh_mount_id mountID,
fssh_vnode_id vnodeID, bool* removed);
extern fssh_status_t fssh_notify_entry_created(fssh_mount_id device,
fssh_vnode_id directory, const char *name, fssh_vnode_id node);
extern fssh_status_t fssh_notify_entry_removed(fssh_mount_id device,
fssh_vnode_id directory, const char *name, fssh_vnode_id node);
extern fssh_status_t fssh_notify_entry_moved(fssh_mount_id device,
fssh_vnode_id fromDirectory, const char *fromName,
fssh_vnode_id toDirectory, const char *toName,
fssh_vnode_id node);
extern fssh_status_t fssh_notify_stat_changed(fssh_mount_id device,
fssh_vnode_id node, uint32_t statFields);
extern fssh_status_t fssh_notify_attribute_changed(fssh_mount_id device,
fssh_vnode_id node, const char *attribute, int32_t cause);
extern fssh_status_t fssh_notify_query_entry_created(fssh_port_id port,
int32_t token, fssh_mount_id device,
fssh_vnode_id directory, const char *name,
fssh_vnode_id node);
extern fssh_status_t fssh_notify_query_entry_removed(fssh_port_id port,
int32_t token, fssh_mount_id device,
fssh_vnode_id directory, const char *name,
fssh_vnode_id node);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_FS_INTERFACE_H */
+43
View File
@@ -0,0 +1,43 @@
/* File System attribute queries
**
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef _FSSH_FS_QUERY_H
#define _FSSH_FS_QUERY_H
#include "fssh_os.h"
#include "fssh_dirent.h"
/* Flags for fs_open_[live_]query() */
#define FSSH_B_LIVE_QUERY 0x00000001
// Note, if you specify B_LIVE_QUERY, you have to use fs_open_live_query();
// it will be ignored in fs_open_query().
#define FSSH_B_QUERY_NON_INDEXED 0x00000002
// Only enable this feature for non time-critical things, it might
// take a long time to proceed.
// Also, not every file system might support this feature.
#ifdef __cplusplus
extern "C" {
#endif
extern fssh_DIR* fssh_fs_open_query(fssh_dev_t device,
const char *query, uint32_t flags);
extern fssh_DIR* fssh_fs_open_live_query(fssh_dev_t device,
const char *query, uint32_t flags,
fssh_port_id port, int32_t token);
extern int fssh_fs_close_query(fssh_DIR *d);
extern struct fssh_dirent* fssh_fs_read_query(fssh_DIR *d);
extern fssh_status_t fssh_get_path_for_dirent(struct fssh_dirent *dent,
char *buf, fssh_size_t len);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_FS_QUERY_H */
+34
View File
@@ -0,0 +1,34 @@
/* File System volume functions
*
* Copyright 2004-2005, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_FS_VOLUME_H
#define _FSSH_FS_VOLUME_H
#include "fssh_os.h"
/* mount flags */
#define FSSH_B_MOUNT_READ_ONLY 1
#define FSSH_B_MOUNT_VIRTUAL_DEVICE 2
/* unmount flags */
#define FSSH_B_FORCE_UNMOUNT 1
#ifdef __cplusplus
extern "C" {
#endif
extern fssh_dev_t fssh_fs_mount_volume(const char *where,
const char *device, const char *filesystem,
uint32_t flags, const char *parameters);
extern fssh_status_t fssh_fs_unmount_volume(const char *path,
uint32_t flags);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_FS_VOLUME_H */
@@ -0,0 +1,51 @@
#ifndef _FSSH_KERNEL_EXPORT_H
#define _FSSH_KERNEL_EXPORT_H
#include "fssh_defs.h"
#include "fssh_os.h"
#ifdef __cplusplus
extern "C" {
#endif
/*-------------------------------------------------------------*/
/* kernel threads */
extern fssh_thread_id fssh_spawn_kernel_thread(fssh_thread_func function,
const char *threadName, int32_t priority,
void *arg);
/*-------------------------------------------------------------*/
/* primitive kernel debugging facilities */
extern void fssh_dprintf(const char *format, ...) /* just like printf */
__attribute__ ((format (__printf__, 1, 2)));
extern void fssh_kprintf(const char *fmt, ...) /* only for debugger cmds */
__attribute__ ((format (__printf__, 1, 2)));
extern void fssh_dump_block(const char *buffer, int size,
const char *prefix);
extern void fssh_panic(const char *format, ...)
__attribute__ ((format (__printf__, 1, 2)));
extern void fssh_kernel_debugger(const char *message); /* enter kernel debugger */
extern uint32_t fssh_parse_expression(const char *string); /* utility for debugger cmds */
typedef int (*fssh_debugger_command_hook)(int argc, char **argv);
extern int fssh_add_debugger_command(char *name,
fssh_debugger_command_hook hook, char *help);
extern int fssh_remove_debugger_command(char *name,
fssh_debugger_command_hook hook);
#ifdef __cplusplus
}
#endif
#endif // _FSSH_KERNEL_EXPORT_H
@@ -0,0 +1,56 @@
/*
* Copyright 2002-2005, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#ifndef _FSSH_KERNEL_H
#define _FSSH_KERNEL_H
#include "fssh_os.h"
/* Passed in buffers from user-space shouldn't point into the kernel */
#if 0
#define IS_USER_ADDRESS(x) \
((addr_t)(x) < KERNEL_BASE || (addr_t)(x) > KERNEL_TOP)
#define IS_KERNEL_ADDRESS(x) \
((addr_t)(x) >= KERNEL_BASE && (addr_t)(x) <= KERNEL_TOP)
#endif // 0
#define DEBUG_KERNEL_STACKS
// Note, debugging kernel stacks doesn't really work yet. Since the
// interrupt will also try to use the stack on a page fault, all
// you get is a double fault.
// At least, you then know that the stack overflows in this case :)
/** Size of the kernel stack */
#ifndef DEBUG_KERNEL_STACKS
# define KERNEL_STACK_SIZE (B_PAGE_SIZE * 2) // 8 kB
#else
# define KERNEL_STACK_SIZE (B_PAGE_SIZE * 3) // 8 kB + one guard page
#endif
#define KERNEL_STACK_GUARD_PAGES 1
/** Size of the stack given to teams in user space */
#define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024) // 16 MB
#define USER_STACK_SIZE (256 * 1024) // 256 kB
#define USER_STACK_GUARD_PAGES 4 // 16 kB
/** Size of the environmental variables space for a process */
#define ENV_SIZE (B_PAGE_SIZE * 8)
#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
#define ROUNDOWN(a, b) (((a) / (b)) * (b))
#define CHECK_BIT(a, b) ((a) & (1 << (b)))
#define SET_BIT(a, b) ((a) | (1 << (b)))
#define CLEAR_BIT(a, b) ((a) & (~(1 << (b))))
#endif /* _FSSH_KERNEL_H */
+62
View File
@@ -0,0 +1,62 @@
/* Modules Definitions
**
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef _FSSH_MODULE_H
#define _FSSH_MODULE_H
#include "fssh_os.h"
/* Every module exports a list of module_info structures.
* It defines the interface of the module and the name
* that is used to access the interface.
*/
typedef struct fssh_module_info {
const char *name;
uint32_t flags;
fssh_status_t (*std_ops)(int32_t, ...);
} fssh_module_info;
/* module standard operations */
#define FSSH_B_MODULE_INIT 1
#define FSSH_B_MODULE_UNINIT 2
/* module flags */
#define FSSH_B_KEEP_LOADED 0x00000001
/* Use the module_dependency structure to let the
* kernel automatically load modules yet depend on
* before B_MODULE_INIT is called.
*/
typedef struct fssh_module_dependency {
const char *name;
fssh_module_info **info;
} fssh_module_dependency;
#if 0
#ifdef __cplusplus
extern "C" {
#endif
extern status_t get_module(const char *path, module_info **_info);
extern status_t put_module(const char *path);
extern status_t get_next_loaded_module_name(uint32 *cookie, char *buffer, size_t *_bufferSize);
extern void *open_module_list(const char *prefix);
extern status_t close_module_list(void *cookie);
extern status_t read_next_module_name(void *cookie, char *buffer, size_t *_bufferSize);
#ifdef __cplusplus
}
#endif
#endif // 0
#endif /* _FSSH_MODULE_H */
@@ -0,0 +1,67 @@
#ifndef _FSSH_NODE_MONITOR_H
#define _FSSH_NODE_MONITOR_H
/* Node monitor calls for kernel add-ons
**
** Distributed under the terms of the OpenBeOS License.
*/
#include "fssh_defs.h"
/* Flags for the watch_node() call.
*
* Note that B_WATCH_MOUNT is NOT included in B_WATCH_ALL.
* You may prefer to use BVolumeRoster for volume watching.
*/
enum {
FSSH_B_STOP_WATCHING = 0x0000,
FSSH_B_WATCH_NAME = 0x0001,
FSSH_B_WATCH_STAT = 0x0002,
FSSH_B_WATCH_ATTR = 0x0004,
FSSH_B_WATCH_DIRECTORY = 0x0008,
FSSH_B_WATCH_ALL = 0x000f,
FSSH_B_WATCH_MOUNT = 0x0010
};
/* The "opcode" field of the B_NODE_MONITOR notification message you get.
*
* The presence and meaning of the other fields in that message specifying what
* exactly caused the notification depend on this value.
*/
#define FSSH_B_ENTRY_CREATED 1
#define FSSH_B_ENTRY_REMOVED 2
#define FSSH_B_ENTRY_MOVED 3
#define FSSH_B_STAT_CHANGED 4
#define FSSH_B_ATTR_CHANGED 5
#define FSSH_B_DEVICE_MOUNTED 6
#define FSSH_B_DEVICE_UNMOUNTED 7
// More specific info in the "cause" field of B_ATTR_CHANGED notification
// messages. (Haiku only)
#define FSSH_B_ATTR_CREATED 1
#define FSSH_B_ATTR_REMOVED 2
// FSSH_B_ATTR_CHANGED is reused
// More specific info in the "fields" field of B_STAT_CHANGED notification
// messages, specifying what parts of the stat data have actually been
// changed. (Haiku only)
enum {
FSSH_B_STAT_MODE = 0x01,
FSSH_B_STAT_UID = 0x02,
FSSH_B_STAT_GID = 0x04,
FSSH_B_STAT_SIZE = 0x08,
FSSH_B_STAT_ACCESS_TIME = 0x10,
FSSH_B_STAT_MODIFICATION_TIME = 0x20,
FSSH_B_STAT_CREATION_TIME = 0x40,
FSSH_B_STAT_CHANGE_TIME = 0x80,
};
#endif /* _FSSH_NODE_MONITOR_H */
+211
View File
@@ -0,0 +1,211 @@
/* Kernel specific structures and functions
*
* Copyright 2004-2006, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_SEM_H
#define _FSSH_SEM_H
#include "fssh_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*-------------------------------------------------------------*/
/* System constants */
#define FSSH_B_OS_NAME_LENGTH 32
#define FSSH_B_PAGE_SIZE 4096
#define FSSH_B_INFINITE_TIMEOUT (9223372036854775807LL)
/*-------------------------------------------------------------*/
/* Types */
typedef int32_t fssh_area_id;
typedef int32_t fssh_port_id;
typedef int32_t fssh_sem_id;
typedef int32_t fssh_team_id;
typedef int32_t fssh_thread_id;
/*-------------------------------------------------------------*/
/* Semaphores */
typedef struct fssh_sem_info {
fssh_sem_id sem;
fssh_team_id team;
char name[FSSH_B_OS_NAME_LENGTH];
int32_t count;
fssh_thread_id latest_holder;
} fssh_sem_info;
/* semaphore flags */
enum {
FSSH_B_CAN_INTERRUPT = 0x01, // acquisition of the semaphore can be
// interrupted (system use only)
FSSH_B_CHECK_PERMISSION = 0x04, // ownership will be checked (system use
// only)
FSSH_B_KILL_CAN_INTERRUPT = 0x20, // acquisition of the semaphore can be
// interrupted by SIGKILL[THR], even
// if not B_CAN_INTERRUPT (system use
// only)
/* release_sem_etc() only flags */
FSSH_B_DO_NOT_RESCHEDULE = 0x02, // thread is not rescheduled
FSSH_B_RELEASE_ALL = 0x08, // all waiting threads will be woken up,
// count will be zeroed
FSSH_B_RELEASE_IF_WAITING_ONLY = 0x10 // release count only if there are any
// threads waiting
};
extern fssh_sem_id fssh_create_sem(int32_t count, const char *name);
extern fssh_status_t fssh_delete_sem(fssh_sem_id id);
extern fssh_status_t fssh_acquire_sem(fssh_sem_id id);
extern fssh_status_t fssh_acquire_sem_etc(fssh_sem_id id, int32_t count,
uint32_t flags, fssh_bigtime_t timeout);
extern fssh_status_t fssh_release_sem(fssh_sem_id id);
extern fssh_status_t fssh_release_sem_etc(fssh_sem_id id, int32_t count,
uint32_t flags);
extern fssh_status_t fssh_get_sem_count(fssh_sem_id id,
int32_t *threadCount);
extern fssh_status_t fssh_set_sem_owner(fssh_sem_id id, fssh_team_id team);
/* system private, use the macros instead */
extern fssh_status_t _fssh_get_sem_info(fssh_sem_id id,
struct fssh_sem_info *info, fssh_size_t infoSize);
extern fssh_status_t _fssh_get_next_sem_info(fssh_team_id team,
int32_t *cookie, struct fssh_sem_info *info,
fssh_size_t infoSize);
#define fssh_get_sem_info(sem, info) \
_fssh_get_sem_info((sem), (info), sizeof(*(info)))
#define fssh_get_next_sem_info(team, cookie, info) \
_fssh_get_next_sem_info((team), (cookie), (info), sizeof(*(info)))
enum {
FSSH_B_TIMEOUT = 8, /* relative timeout */
FSSH_B_RELATIVE_TIMEOUT = 8, /* fails after a relative timeout with B_WOULD_BLOCK */
FSSH_B_ABSOLUTE_TIMEOUT = 16 /* fails after an absolute timeout with B_WOULD BLOCK */
};
/*-------------------------------------------------------------*/
/* Teams */
#define FSSH_B_CURRENT_TEAM 0
#define FSSH_B_SYSTEM_TEAM 1
/*-------------------------------------------------------------*/
/* Threads */
typedef enum {
FSSH_B_THREAD_RUNNING = 1,
FSSH_B_THREAD_READY,
FSSH_B_THREAD_RECEIVING,
FSSH_B_THREAD_ASLEEP,
FSSH_B_THREAD_SUSPENDED,
FSSH_B_THREAD_WAITING
} fssh_thread_state;
typedef struct {
fssh_thread_id thread;
fssh_team_id team;
char name[FSSH_B_OS_NAME_LENGTH];
fssh_thread_state state;
int32_t priority;
fssh_sem_id sem;
fssh_bigtime_t user_time;
fssh_bigtime_t kernel_time;
void *stack_base;
void *stack_end;
} fssh_thread_info;
#define FSSH_B_IDLE_PRIORITY 0
#define FSSH_B_LOWEST_ACTIVE_PRIORITY 1
#define FSSH_B_LOW_PRIORITY 5
#define FSSH_B_NORMAL_PRIORITY 10
#define FSSH_B_DISPLAY_PRIORITY 15
#define FSSH_B_URGENT_DISPLAY_PRIORITY 20
#define FSSH_B_REAL_TIME_DISPLAY_PRIORITY 100
#define FSSH_B_URGENT_PRIORITY 110
#define FSSH_B_REAL_TIME_PRIORITY 120
#define FSSH_B_FIRST_REAL_TIME_PRIORITY B_REAL_TIME_DISPLAY_PRIORITY
#define FSSH_B_MIN_PRIORITY B_IDLE_PRIORITY
#define FSSH_B_MAX_PRIORITY B_REAL_TIME_PRIORITY
#define FSSH_B_SYSTEM_TIMEBASE 0
typedef fssh_status_t (*fssh_thread_func)(void *);
#define fssh_thread_entry fssh_thread_func
/* thread_entry is for backward compatibility only! Use thread_func */
extern fssh_thread_id fssh_spawn_thread(fssh_thread_func, const char *name,
int32_t priority, void *data);
extern fssh_status_t fssh_kill_thread(fssh_thread_id thread);
extern fssh_status_t fssh_resume_thread(fssh_thread_id thread);
extern fssh_status_t fssh_suspend_thread(fssh_thread_id thread);
extern fssh_status_t fssh_rename_thread(fssh_thread_id thread,
const char *newName);
extern fssh_status_t fssh_set_thread_priority (fssh_thread_id thread,
int32_t newPriority);
extern void fssh_exit_thread(fssh_status_t status);
extern fssh_status_t fssh_wait_for_thread (fssh_thread_id thread,
fssh_status_t *threadReturnValue);
extern fssh_status_t fssh_on_exit_thread(void (*callback)(void *),
void *data);
extern fssh_thread_id fssh_find_thread(const char *name);
extern fssh_status_t fssh_send_data(fssh_thread_id thread, int32_t code,
const void *buffer,
fssh_size_t bufferSize);
extern int32_t fssh_receive_data(fssh_thread_id *sender, void *buffer,
fssh_size_t bufferSize);
extern bool fssh_has_data(fssh_thread_id thread);
extern fssh_status_t fssh_snooze(fssh_bigtime_t amount);
extern fssh_status_t fssh_snooze_etc(fssh_bigtime_t amount, int timeBase,
uint32_t flags);
extern fssh_status_t fssh_snooze_until(fssh_bigtime_t time, int timeBase);
/* system private, use macros instead */
extern fssh_status_t _fssh_get_thread_info(fssh_thread_id id,
fssh_thread_info *info, fssh_size_t size);
extern fssh_status_t _fssh_get_next_thread_info(fssh_team_id team,
int32_t *cookie, fssh_thread_info *info,
fssh_size_t size);
#define fssh_get_thread_info(id, info) \
_fssh_get_thread_info((id), (info), sizeof(*(info)))
#define fssh_get_next_thread_info(team, cookie, info) \
_fssh_get_next_thread_info((team), (cookie), (info), sizeof(*(info)))
/*-------------------------------------------------------------*/
/* Time */
extern uint32_t fssh_real_time_clock(void);
extern void fssh_set_real_time_clock(uint32_t secs_since_jan1_1970);
extern fssh_bigtime_t fssh_real_time_clock_usecs(void);
extern fssh_status_t fssh_set_timezone(char *timezone);
extern fssh_bigtime_t fssh_system_time(void); /* time since booting in microseconds */
#ifdef __cplusplus
}
#endif
#endif // _FSSH_TYPES_H
+114
View File
@@ -0,0 +1,114 @@
/*
* Copyright 2002-2007, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_SYS_STAT_H_
#define _FSSH_SYS_STAT_H_
#include "fssh_defs.h"
#include "fssh_time.h"
struct fssh_stat {
fssh_dev_t fssh_st_dev; /* "device" that this file resides on */
fssh_ino_t fssh_st_ino; /* this file's inode #, unique per device */
fssh_mode_t fssh_st_mode; /* mode bits (rwx for user, group, etc) */
fssh_nlink_t fssh_st_nlink; /* number of hard links to this file */
fssh_uid_t fssh_st_uid; /* user id of the owner of this file */
fssh_gid_t fssh_st_gid; /* group id of the owner of this file */
fssh_off_t fssh_st_size; /* size in bytes of this file */
fssh_dev_t fssh_st_rdev; /* device type (not used) */
fssh_size_t fssh_st_blksize; /* preferred block size for i/o */
fssh_time_t fssh_st_atime; /* last access time */
fssh_time_t fssh_st_mtime; /* last modification time */
fssh_time_t fssh_st_ctime; /* last change time, not creation time */
fssh_time_t fssh_st_crtime; /* creation time */
// Haiku extensions:
// TODO: we might also define special types for files and TTYs
// TODO: we should find another solution for this, as BStatable::GetStat()
// can only retrieve the R5 stat structure
unsigned int fssh_st_type; /* attribute/index type */
};
/* extended file types */
#define FSSH_S_ATTR_DIR 01000000000 /* attribute directory */
#define FSSH_S_ATTR 02000000000 /* attribute */
#define FSSH_S_INDEX_DIR 04000000000 /* index (or index directory) */
#define FSSH_S_STR_INDEX 00100000000 /* string index */
#define FSSH_S_INT_INDEX 00200000000 /* int32 index */
#define FSSH_S_UINT_INDEX 00400000000 /* uint32 index */
#define FSSH_S_LONG_LONG_INDEX 00010000000 /* int64 index */
#define FSSH_S_ULONG_LONG_INDEX 00020000000 /* uint64 index */
#define FSSH_S_FLOAT_INDEX 00040000000 /* float index */
#define FSSH_S_DOUBLE_INDEX 00001000000 /* double index */
#define FSSH_S_ALLOW_DUPS 00002000000 /* allow duplicate entries (currently unused) */
/* link types */
#define FSSH_S_LINK_SELF_HEALING 00001000000 /* link will be updated if you move its target */
#define FSSH_S_LINK_AUTO_DELETE 00002000000 /* link will be deleted if you delete its target */
/* standard file types */
#define FSSH_S_IFMT 00000170000 /* type of file */
#define FSSH_S_IFLNK 00000120000 /* symbolic link */
#define FSSH_S_IFREG 00000100000 /* regular */
#define FSSH_S_IFBLK 00000060000 /* block special */
#define FSSH_S_IFDIR 00000040000 /* directory */
#define FSSH_S_IFCHR 00000020000 /* character special */
#define FSSH_S_IFIFO 00000010000 /* fifo */
#define FSSH_S_ISREG(mode) (((mode) & FSSH_S_IFMT) == FSSH_S_IFREG)
#define FSSH_S_ISLNK(mode) (((mode) & FSSH_S_IFMT) == FSSH_S_IFLNK)
#define FSSH_S_ISBLK(mode) (((mode) & FSSH_S_IFMT) == FSSH_S_IFBLK)
#define FSSH_S_ISDIR(mode) (((mode) & FSSH_S_IFMT) == FSSH_S_IFDIR)
#define FSSH_S_ISCHR(mode) (((mode) & FSSH_S_IFMT) == FSSH_S_IFCHR)
#define FSSH_S_ISFIFO(mode) (((mode) & FSSH_S_IFMT) == FSSH_S_IFIFO)
#define FSSH_S_ISINDEX(mode) (((mode) & FSSH_S_INDEX_DIR) == FSSH_S_INDEX_DIR)
#define FSSH_S_IUMSK 07777 /* user settable bits */
#define FSSH_S_ISUID 04000 /* set user id on execution */
#define FSSH_S_ISGID 02000 /* set group id on execution */
#define FSSH_S_ISVTX 01000 /* save swapped text even after use */
#define FSSH_S_IRWXU 00700 /* read, write, execute: owner */
#define FSSH_S_IRUSR 00400 /* read permission: owner */
#define FSSH_S_IWUSR 00200 /* write permission: owner */
#define FSSH_S_IXUSR 00100 /* execute permission: owner */
#define FSSH_S_IRWXG 00070 /* read, write, execute: group */
#define FSSH_S_IRGRP 00040 /* read permission: group */
#define FSSH_S_IWGRP 00020 /* write permission: group */
#define FSSH_S_IXGRP 00010 /* execute permission: group */
#define FSSH_S_IRWXO 00007 /* read, write, execute: other */
#define FSSH_S_IROTH 00004 /* read permission: other */
#define FSSH_S_IWOTH 00002 /* write permission: other */
#define FSSH_S_IXOTH 00001 /* execute permission: other */
#define FSSH_ACCESSPERMS (FSSH_S_IRWXU | FSSH_S_IRWXG | FSSH_S_IRWXO)
#define FSSH_ALLPERMS (FSSH_S_ISUID | FSSH_S_ISGID | FSSH_S_ISTXT \
| FSSH_S_IRWXU | FSSH_S_IRWXG | FSSH_S_IRWXO)
#define FSSH_DEFFILEMODE (FSSH_S_IRUSR | FSSH_S_IWUSR | FSSH_S_IRGRP \
| FSSH_S_IWGRP | FSSH_S_IROTH | FSSH_S_IWOTH)
/* default file mode, everyone can read/write */
#ifdef __cplusplus
extern "C" {
#endif
extern int fssh_chmod(const char *path, fssh_mode_t mode);
extern int fssh_fchmod(int fd, fssh_mode_t mode);
extern int fssh_mkdir(const char *path, fssh_mode_t mode);
extern int fssh_mkfifo(const char *path, fssh_mode_t mode);
extern fssh_mode_t fssh_umask(fssh_mode_t cmask);
extern int fssh_stat(const char *path, struct fssh_stat *st);
extern int fssh_fstat(int fd, struct fssh_stat *st);
extern int fssh_lstat(const char *path, struct fssh_stat *st);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_SYS_STAT_H_ */
+40
View File
@@ -0,0 +1,40 @@
#ifndef _FSSH_STDIO_H_
#define _FSSH_STDIO_H_
#include <stdarg.h>
#include "fssh_defs.h"
#ifdef FSSH_EOF
# undef FSSH_EOF
#endif
#define FSSH_EOF -1
#ifdef __cplusplus
extern "C" {
#endif
/* file operations */
extern int fssh_remove(const char *name);
extern int fssh_rename(const char *from, const char *to);
/* formatted I/O */
extern int fssh_sprintf(char *string, char const *format, ...)
__attribute__ ((format (__printf__, 2, 3)));
extern int fssh_snprintf(char *string, fssh_size_t size,
char const *format, ...)
__attribute__ ((format (__printf__, 3, 4)));
extern int fssh_vsprintf(char *string, char const *format, va_list ap);
extern int fssh_vsnprintf(char *string, fssh_size_t size,
char const *format, va_list ap);
extern int fssh_sscanf(char const *str, char const *format, ...);
extern int fssh_vsscanf(char const *str, char const *format, va_list ap);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_STDIO_H_ */
+91
View File
@@ -0,0 +1,91 @@
/*
* Copyright 2004-2007, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_STRING_H
#define _FSSH_STRING_H
#include "fssh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/* memXXX() functions */
extern void *fssh_memchr(const void *source, int value, fssh_size_t length);
extern int fssh_memcmp(const void *buffer1, const void *buffer2,
fssh_size_t length);
extern void *fssh_memcpy(void *dest, const void *source,
fssh_size_t length);
extern void *fssh_memccpy(void *dest, const void *source, int stopByte,
fssh_size_t length);
extern void *fssh_memmove(void *dest, const void *source,
fssh_size_t length);
extern void *fssh_memset(void *dest, int value, fssh_size_t length);
/* string functions */
extern char *fssh_strcpy(char *dest, const char *source);
extern char *fssh_strncpy(char *dest, const char *source,
fssh_size_t length);
extern char *fssh_strcat(char *dest, const char *source);
extern char *fssh_strncat(char *dest, const char *source,
fssh_size_t length);
extern fssh_size_t fssh_strlen(const char *string);
extern int fssh_strcmp(const char *string1, const char *string2);
extern int fssh_strncmp(const char *string1, const char *string2,
fssh_size_t length);
extern char *fssh_strchr(const char *string, int character);
extern char *fssh_strrchr(const char *string, int character);
extern char *fssh_strstr(const char *string, const char *searchString);
extern char *fssh_strchrnul(const char *string, int character);
// this is a GNU extension
extern char *fssh_strpbrk(const char *string, const char *set);
extern char *fssh_strtok(char *string, const char *set);
extern char *fssh_strtok_r(char *string, const char *set,
char **savePointer);
extern fssh_size_t fssh_strspn(const char *string, const char *set);
extern fssh_size_t fssh_strcspn(const char *string, const char *set);
extern int fssh_strcoll(const char *string1, const char *string2);
extern fssh_size_t fssh_strxfrm(char *string1, const char *string2,
fssh_size_t length);
extern char *fssh_strerror(int errorCode);
extern int fssh_strerror_r(int errorCode, char *buffer,
fssh_size_t bufferSize);
/* non-standard string functions */
extern int fssh_strcasecmp(const char *string1, const char *string2);
extern int fssh_strncasecmp(const char *string1, const char *string2,
fssh_size_t length);
extern char *fssh_strcasestr(const char *string, const char *searchString);
extern char *fssh_strdup(const char *string);
extern char *fssh_stpcpy(char *dest, const char *source);
extern const char *fssh_strtcopy(char *dest, const char *source);
extern fssh_size_t fssh_strlcat(char *dest, const char *source,
fssh_size_t length);
extern fssh_size_t fssh_strlcpy(char *dest, const char *source,
fssh_size_t length);
extern fssh_size_t fssh_strnlen(const char *string, fssh_size_t count);
extern int fssh_ffs(int i);
extern char *fssh_index(const char *s, int c);
extern char *fssh_rindex(char const *s, int c);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_STRING_H */
+86
View File
@@ -0,0 +1,86 @@
/*
* Copyright 2005-2007, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_TIME_H_
#define _FSSH_TIME_H_
#include "fssh_defs.h"
typedef long fssh_clock_t;
typedef long fssh_time_t;
typedef long fssh_suseconds_t;
typedef unsigned long fssh_useconds_t;
#define FSSH_CLOCKS_PER_SEC 1000
#define FSSH_CLK_TCK FSSH_CLOCKS_PER_SEC
#define FSSH_MAX_TIMESTR 70
/* maximum length of a string returned by asctime(), and ctime() */
struct fssh_timespec {
fssh_time_t tv_sec; /* seconds */
long tv_nsec; /* and nanoseconds */
};
struct fssh_itimerspec {
struct fssh_timespec it_interval;
struct fssh_timespec it_value;
};
struct fssh_tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday; /* day of month (1 to 31) */
int tm_mon; /* months since January (0 to 11) */
int tm_year; /* years since 1900 */
int tm_wday; /* days since Sunday (0 to 6, Sunday = 0, ...) */
int tm_yday; /* days since January 1 (0 to 365) */
int tm_isdst; /* daylight savings time (0 == no, >0 == yes, <0 == has to be calculated */
int tm_gmtoff; /* timezone offset to GMT */
char *tm_zone; /* timezone name */
};
/* special timezone support */
extern char *fssh_tzname[2];
extern int fssh_daylight;
extern long fssh_timezone;
#ifdef __cplusplus
extern "C" {
#endif
extern fssh_clock_t fssh_clock(void);
extern double fssh_difftime(fssh_time_t time1, fssh_time_t time2);
extern fssh_time_t fssh_mktime(struct fssh_tm *tm);
extern fssh_time_t fssh_time(fssh_time_t *timer);
extern char *fssh_asctime(const struct fssh_tm *tm);
extern char *fssh_asctime_r(const struct fssh_tm *timep,
char *buffer);
extern char *fssh_ctime(const fssh_time_t *timer);
extern char *fssh_ctime_r(const fssh_time_t *timer, char *buffer);
extern struct fssh_tm *fssh_gmtime(const fssh_time_t *timer);
extern struct fssh_tm *fssh_gmtime_r(const fssh_time_t *timer,
struct fssh_tm *tm);
extern struct fssh_tm *fssh_localtime(const fssh_time_t *timer);
extern struct fssh_tm *fssh_localtime_r(const fssh_time_t *timer,
struct fssh_tm *tm);
extern fssh_size_t fssh_strftime(char *buffer, fssh_size_t maxSize,
const char *format, const struct fssh_tm *tm);
extern char *fssh_strptime(const char *buf, const char *format,
struct fssh_tm *tm);
/* special timezone support */
extern void fssh_tzset(void);
extern int fssh_stime(const fssh_time_t *t);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_TIME_H_ */
@@ -0,0 +1,78 @@
/*
* Copyright 2005-2007, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Author:
* Erik Jaesler ([email protected])
*/
#ifndef _FSSH_TYPE_CONSTANTS_H
#define _FSSH_TYPE_CONSTANTS_H
#include "fssh_defs.h"
enum {
FSSH_B_ANY_TYPE = 'ANYT',
FSSH_B_ATOM_TYPE = 'ATOM',
FSSH_B_ATOMREF_TYPE = 'ATMR',
FSSH_B_BOOL_TYPE = 'BOOL',
FSSH_B_CHAR_TYPE = 'CHAR',
FSSH_B_COLOR_8_BIT_TYPE = 'CLRB',
FSSH_B_DOUBLE_TYPE = 'DBLE',
FSSH_B_FLOAT_TYPE = 'FLOT',
FSSH_B_GRAYSCALE_8_BIT_TYPE = 'GRYB',
FSSH_B_INT16_TYPE = 'SHRT',
FSSH_B_INT32_TYPE = 'LONG',
FSSH_B_INT64_TYPE = 'LLNG',
FSSH_B_INT8_TYPE = 'BYTE',
FSSH_B_LARGE_ICON_TYPE = 'ICON',
FSSH_B_MEDIA_PARAMETER_GROUP_TYPE = 'BMCG',
FSSH_B_MEDIA_PARAMETER_TYPE = 'BMCT',
FSSH_B_MEDIA_PARAMETER_WEB_TYPE = 'BMCW',
FSSH_B_MESSAGE_TYPE = 'MSGG',
FSSH_B_MESSENGER_TYPE = 'MSNG',
FSSH_B_MIME_TYPE = 'MIME',
FSSH_B_MINI_ICON_TYPE = 'MICN',
FSSH_B_MONOCHROME_1_BIT_TYPE = 'MNOB',
FSSH_B_OBJECT_TYPE = 'OPTR',
FSSH_B_OFF_T_TYPE = 'OFFT',
FSSH_B_PATTERN_TYPE = 'PATN',
FSSH_B_POINTER_TYPE = 'PNTR',
FSSH_B_POINT_TYPE = 'BPNT',
FSSH_B_PROPERTY_INFO_TYPE = 'SCTD',
FSSH_B_RAW_TYPE = 'RAWT',
FSSH_B_RECT_TYPE = 'RECT',
FSSH_B_REF_TYPE = 'RREF',
FSSH_B_RGB_32_BIT_TYPE = 'RGBB',
FSSH_B_RGB_COLOR_TYPE = 'RGBC',
FSSH_B_SIZE_T_TYPE = 'SIZT',
FSSH_B_SSIZE_T_TYPE = 'SSZT',
FSSH_B_STRING_TYPE = 'CSTR',
FSSH_B_TIME_TYPE = 'TIME',
FSSH_B_UINT16_TYPE = 'USHT',
FSSH_B_UINT32_TYPE = 'ULNG',
FSSH_B_UINT64_TYPE = 'ULLG',
FSSH_B_UINT8_TYPE = 'UBYT',
FSSH_B_VECTOR_ICON_TYPE = 'VICN',
// deprecated, do not use
FSSH_B_ASCII_TYPE = 'TEXT' // use B_STRING_TYPE instead
};
//----- System-wide MIME types for handling URL's ------------------------------
extern const char *FSSH_B_URL_HTTP; // application/x-vnd.Be.URL.http
extern const char *FSSH_B_URL_HTTPS; // application/x-vnd.Be.URL.https
extern const char *FSSH_B_URL_FTP; // application/x-vnd.Be.URL.ftp
extern const char *FSSH_B_URL_GOPHER; // application/x-vnd.Be.URL.gopher
extern const char *FSSH_B_URL_MAILTO; // application/x-vnd.Be.URL.mailto
extern const char *FSSH_B_URL_NEWS; // application/x-vnd.Be.URL.news
extern const char *FSSH_B_URL_NNTP; // application/x-vnd.Be.URL.nntp
extern const char *FSSH_B_URL_TELNET; // application/x-vnd.Be.URL.telnet
extern const char *FSSH_B_URL_RLOGIN; // application/x-vnd.Be.URL.rlogin
extern const char *FSSH_B_URL_TN3270; // application/x-vnd.Be.URL.tn3270
extern const char *FSSH_B_URL_WAIS; // application/x-vnd.Be.URL.wais
extern const char *FSSH_B_URL_FILE; // application/x-vnd.Be.URL.file
#endif // _FSSH_TYPE_CONSTANTS_H
+33
View File
@@ -0,0 +1,33 @@
#ifndef _FSSH_TYPES_H
#define _FSSH_TYPES_H
#include <inttypes.h>
typedef uint32_t fssh_ulong;
typedef volatile int32_t vint32_t;
typedef uint32_t fssh_addr_t;
typedef int32_t fssh_dev_t;
typedef int64_t fssh_ino_t;
typedef uint32_t fssh_size_t;
typedef int32_t fssh_ssize_t;
typedef int64_t fssh_off_t;
typedef int64_t fssh_bigtime_t;
typedef int32_t fssh_status_t;
typedef uint32_t fssh_type_code;
typedef uint32_t fssh_mode_t;
typedef uint32_t fssh_nlink_t;
typedef uint32_t fssh_uid_t;
typedef uint32_t fssh_gid_t;
typedef int32_t fssh_pid_t;
#ifndef NULL
#define NULL (0)
#endif
#endif // _FSSH_TYPES_H
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright 2002-2007, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_SYS_UIO_H
#define _FSSH_SYS_UIO_H
#include "fssh_types.h"
typedef struct fssh_iovec {
void *iov_base;
fssh_size_t iov_len;
} fssh_iovec;
#ifdef __cplusplus
extern "C" {
#endif
fssh_ssize_t fssh_readv(int fd, const struct fssh_iovec *vector,
fssh_size_t count);
fssh_ssize_t fssh_readv_pos(int fd, fssh_off_t pos, const struct
fssh_iovec *vec, fssh_size_t count);
fssh_ssize_t fssh_writev(int fd, const struct fssh_iovec *vector,
fssh_size_t count);
fssh_ssize_t fssh_writev_pos(int fd, fssh_off_t pos,
const struct fssh_iovec *vec, fssh_size_t count);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_SYS_UIO_H */
+87
View File
@@ -0,0 +1,87 @@
/*
* Copyright 2004-2007, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_UNISTD_H
#define _FSSH_UNISTD_H
#include "fssh_defs.h"
/* access modes */
#define FSSH_R_OK 4
#define FSSH_W_OK 2
#define FSSH_X_OK 1
#define FSSH_F_OK 0
/* standard file descriptors */
#define FSSH_STDIN_FILENO 0
#define FSSH_STDOUT_FILENO 1
#define FSSH_STDERR_FILENO 2
/* lseek() constants */
#ifndef FSSH_SEEK_SET
# define FSSH_SEEK_SET 0
#endif
#ifndef FSSH_SEEK_CUR
# define FSSH_SEEK_CUR 1
#endif
#ifndef FSSH_SEEK_END
# define FSSH_SEEK_END 2
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* file functions */
extern int fssh_access(const char *path, int accessMode);
extern int fssh_chdir(const char *path);
extern int fssh_fchdir(int fd);
extern char *fssh_getcwd(char *buffer, fssh_size_t size);
extern int fssh_dup(int fd);
extern int fssh_dup2(int fd1, int fd2);
extern int fssh_close(int fd);
extern int fssh_link(const char *name, const char *new_name);
extern int fssh_unlink(const char *name);
extern int fssh_rmdir(const char *path);
extern fssh_ssize_t fssh_readlink(const char *path, char *buffer,
fssh_size_t bufferSize);
extern int fssh_symlink(const char *from, const char *to);
extern int fssh_ftruncate(int fd, fssh_off_t newSize);
extern int fssh_truncate(const char *path, fssh_off_t newSize);
extern int fssh_ioctl(int fd, unsigned long op, ...);
extern fssh_ssize_t fssh_read(int fd, void *buffer, fssh_size_t count);
extern fssh_ssize_t fssh_read_pos(int fd, fssh_off_t pos, void *buffer,
fssh_size_t count);
extern fssh_ssize_t fssh_pread(int fd, void *buffer, fssh_size_t count,
fssh_off_t pos);
extern fssh_ssize_t fssh_write(int fd, const void *buffer, fssh_size_t count);
extern fssh_ssize_t fssh_write_pos(int fd, fssh_off_t pos, const void *buffer,
fssh_size_t count);
extern fssh_ssize_t fssh_pwrite(int fd, const void *buffer, fssh_size_t count,
fssh_off_t pos);
extern fssh_off_t fssh_lseek(int fd, fssh_off_t offset, int whence);
extern int fssh_sync(void);
extern int fssh_fsync(int fd);
/* access permissions */
extern fssh_gid_t fssh_getegid(void);
extern fssh_uid_t fssh_geteuid(void);
extern fssh_gid_t fssh_getgid(void);
extern int fssh_getgroups(int groupSize, fssh_gid_t groupList[]);
extern fssh_uid_t fssh_getuid(void);
#ifdef __cplusplus
}
#endif
#endif /* _FSSH_UNISTD_H */
+1
View File
@@ -63,6 +63,7 @@ SubInclude HAIKU_TOP src tools copy_to_bfs_image ;
SubInclude HAIKU_TOP src tools cppunit ;
SubInclude HAIKU_TOP src tools docbook ;
SubInclude HAIKU_TOP src tools elfsymbolpatcher ;
SubInclude HAIKU_TOP src tools fs_shell ;
SubInclude HAIKU_TOP src tools gensyscalls ;
SubInclude HAIKU_TOP src tools keymap ;
SubInclude HAIKU_TOP src tools makebootable ;
+38
View File
@@ -0,0 +1,38 @@
SubDir HAIKU_TOP src tools fs_shell ;
UseHeaders [ FDirName $(HAIKU_TOP) headers build ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) headers build os ] : true ;
#UseHeaders [ FDirName $(HAIKU_TOP) headers build os app ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) headers build os kernel ] : true ;
#UseHeaders [ FDirName $(HAIKU_TOP) headers build os interface ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) headers build os storage ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) headers build os support ] : true ;
UsePrivateHeaders fs_shell ;
BuildPlatformStaticLibrary <build2>fs_shell.a :
atomic.cpp
block_cache.cpp
errno.cpp
fcntl.cpp
fd.cpp
file_cache.cpp
kernel_export.cpp
KPath.cpp
hash.cpp
list.cpp
lock.cpp
node_monitor.cpp
sem.cpp
stat.cpp
stat_util.cpp
stdio.cpp
string.cpp
thread.cpp
time.cpp
uio.cpp
unistd.cpp
vfs.cpp
fssh.cpp
;
+298
View File
@@ -0,0 +1,298 @@
/*
* Copyright 2004-2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
/** A simple class wrapping a path. Has a fixed-sized buffer. */
#include "KPath.h"
#include <stdlib.h>
#include "fssh_string.h"
#include "vfs.h"
// debugging
#define TRACE(x) ;
//#define TRACE(x) dprintf x
KPath::KPath(fssh_size_t bufferSize)
:
fBuffer(NULL),
fBufferSize(0),
fPathLength(0),
fLocked(false)
{
SetTo(NULL, bufferSize);
}
KPath::KPath(const char* path, bool normalize, fssh_size_t bufferSize)
:
fBuffer(NULL),
fBufferSize(0),
fPathLength(0),
fLocked(false)
{
SetTo(path, normalize, bufferSize);
}
KPath::KPath(const KPath& other)
:
fBuffer(NULL),
fBufferSize(0),
fPathLength(0),
fLocked(false)
{
*this = other;
}
KPath::~KPath()
{
free(fBuffer);
}
fssh_status_t
KPath::SetTo(const char* path, bool normalize, fssh_size_t bufferSize)
{
if (bufferSize == 0)
bufferSize = FSSH_B_PATH_NAME_LENGTH;
// free the previous buffer, if the buffer size differs
if (fBuffer && fBufferSize != bufferSize) {
free(fBuffer);
fBuffer = NULL;
fBufferSize = 0;
}
fPathLength = 0;
fLocked = false;
// allocate buffer
if (!fBuffer)
fBuffer = (char*)malloc(bufferSize);
if (!fBuffer)
return FSSH_B_NO_MEMORY;
if (fBuffer) {
fBufferSize = bufferSize;
fBuffer[0] = '\0';
}
return SetPath(path, normalize);
}
fssh_status_t
KPath::InitCheck() const
{
return fBuffer ? FSSH_B_OK : FSSH_B_NO_MEMORY;
}
fssh_status_t
KPath::SetPath(const char *path, bool normalize)
{
if (!fBuffer)
return FSSH_B_NO_INIT;
if (path) {
if (normalize) {
// normalize path
fssh_status_t error = vfs_normalize_path(path, fBuffer, fBufferSize,
true);
if (error != FSSH_B_OK) {
SetPath(NULL);
return error;
}
fPathLength = fssh_strlen(fBuffer);
} else {
// don't normalize path
fssh_size_t length = fssh_strlen(path);
if (length >= fBufferSize)
return FSSH_B_BUFFER_OVERFLOW;
fssh_memcpy(fBuffer, path, length + 1);
fPathLength = length;
_ChopTrailingSlashes();
}
} else {
fBuffer[0] = '\0';
fPathLength = 0;
}
return FSSH_B_OK;
}
const char*
KPath::Path() const
{
return fBuffer;
}
char *
KPath::LockBuffer()
{
if (!fBuffer || fLocked)
return NULL;
fLocked = true;
return fBuffer;
}
void
KPath::UnlockBuffer()
{
if (!fLocked) {
TRACE(("KPath::UnlockBuffer(): ERROR: Buffer not locked!\n"));
return;
}
fLocked = false;
fPathLength = fssh_strnlen(fBuffer, fBufferSize);
if (fPathLength == fBufferSize) {
TRACE(("KPath::UnlockBuffer(): WARNING: Unterminated buffer!\n"));
fPathLength--;
fBuffer[fPathLength] = '\0';
}
_ChopTrailingSlashes();
}
const char *
KPath::Leaf() const
{
if (!fBuffer)
return NULL;
// only "/" has trailing slashes -- then we have to return the complete
// buffer, as we have to do in case there are no slashes at all
if (fPathLength != 1 || fBuffer[0] != '/') {
for (int32_t i = fPathLength - 1; i >= 0; i--) {
if (fBuffer[i] == '/')
return fBuffer + i + 1;
}
}
return fBuffer;
}
fssh_status_t
KPath::ReplaceLeaf(const char *newLeaf)
{
const char *leaf = Leaf();
if (!leaf)
return FSSH_B_NO_INIT;
int32_t leafIndex = leaf - fBuffer;
// chop off the current leaf (don't replace "/", though)
if (leafIndex != 0 || fBuffer[leafIndex - 1]) {
fBuffer[leafIndex] = '\0';
fPathLength = leafIndex;
_ChopTrailingSlashes();
}
// if a leaf was given, append it
if (newLeaf)
return Append(newLeaf);
return FSSH_B_OK;
}
fssh_status_t
KPath::Append(const char *component, bool isComponent)
{
// check initialization and parameter
if (!fBuffer)
return FSSH_B_NO_INIT;
if (!component)
return FSSH_B_BAD_VALUE;
if (fPathLength == 0)
return SetPath(component);
// get component length
fssh_size_t componentLength = fssh_strlen(component);
if (componentLength < 1)
return FSSH_B_OK;
// if our current path is empty, we just copy the supplied one
// compute the result path len
bool insertSlash = isComponent && fBuffer[fPathLength - 1] != '/'
&& component[0] != '/';
fssh_size_t resultPathLength = fPathLength + componentLength + (insertSlash ? 1 : 0);
if (resultPathLength >= fBufferSize)
return FSSH_B_BUFFER_OVERFLOW;
// compose the result path
if (insertSlash)
fBuffer[fPathLength++] = '/';
fssh_memcpy(fBuffer + fPathLength, component, componentLength + 1);
fPathLength = resultPathLength;
return FSSH_B_OK;
}
KPath&
KPath::operator=(const KPath& other)
{
SetTo(other.fBuffer, other.fBufferSize);
return *this;
}
KPath&
KPath::operator=(const char* path)
{
SetTo(path);
return *this;
}
bool
KPath::operator==(const KPath& other) const
{
if (!fBuffer)
return !other.fBuffer;
return (other.fBuffer
&& fPathLength == other.fPathLength
&& fssh_strcmp(fBuffer, other.fBuffer) == 0);
}
bool
KPath::operator==(const char* path) const
{
if (!fBuffer)
return (!path);
return path && !fssh_strcmp(fBuffer, path);
}
bool
KPath::operator!=(const KPath& other) const
{
return !(*this == other);
}
bool
KPath::operator!=(const char* path) const
{
return !(*this == path);
}
void
KPath::_ChopTrailingSlashes()
{
if (fBuffer) {
while (fPathLength > 1 && fBuffer[fPathLength - 1] == '/')
fBuffer[--fPathLength] = '\0';
}
}
+52
View File
@@ -0,0 +1,52 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <BeOSBuildCompatibility.h>
#include <OS.h>
#include "fssh_atomic.h"
int32_t
fssh_atomic_set(vint32_t *value, int32_t newValue)
{
return atomic_set((vint32*)value, newValue);
}
int32_t
fssh_atomic_test_and_set(vint32_t *value, int32_t newValue, int32_t testAgainst)
{
return atomic_test_and_set((vint32*)value, newValue, testAgainst);
}
int32_t
fssh_atomic_add(vint32_t *value, int32_t addValue)
{
return atomic_add((vint32*)value, addValue);
}
int32_t
fssh_atomic_and(vint32_t *value, int32_t andValue)
{
return atomic_and((vint32*)value, andValue);
}
int32_t
fssh_atomic_or(vint32_t *value, int32_t orValue)
{
return atomic_or((vint32*)value, orValue);
}
int32_t
fssh_atomic_get(vint32_t *value)
{
return atomic_get((vint32*)value);
}
File diff suppressed because it is too large Load Diff
+91
View File
@@ -0,0 +1,91 @@
/*
* Copyright 2004-2006, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_BLOCK_CACHE_PRIVATE_H
#define _FSSH_BLOCK_CACHE_PRIVATE_H
#include "DoublyLinkedList.h"
#include "lock.h"
namespace FSShell {
struct hash_table;
struct vm_page;
//#define DEBUG_CHANGED
#undef DEBUG_CHANGED
struct cache_transaction;
struct cached_block;
struct block_cache;
typedef DoublyLinkedListLink<cached_block> block_link;
struct cached_block {
cached_block *next; // next in hash
cached_block *transaction_next;
block_link link;
fssh_off_t block_number;
void *current_data;
void *original_data;
void *parent_data;
#ifdef DEBUG_CHANGED
void *compare;
#endif
int32_t ref_count;
int32_t accessed;
bool busy : 1;
bool is_writing : 1;
bool is_dirty : 1;
bool unused : 1;
bool unmapped : 1;
cache_transaction *transaction;
cache_transaction *previous_transaction;
static int Compare(void *_cacheEntry, const void *_block);
static uint32_t Hash(void *_cacheEntry, const void *_block, uint32_t range);
};
typedef DoublyLinkedList<cached_block,
DoublyLinkedListMemberGetLink<cached_block,
&cached_block::link> > block_list;
struct block_cache {
hash_table *hash;
benaphore lock;
int fd;
fssh_off_t max_blocks;
fssh_size_t block_size;
int32_t allocated_block_count;
int32_t next_transaction_id;
cache_transaction *last_transaction;
hash_table *transaction_hash;
block_list unmapped_blocks;
block_list unused_blocks;
bool read_only;
block_cache(int fd, fssh_off_t numBlocks, fssh_size_t blockSize, bool readOnly);
~block_cache();
fssh_status_t InitCheck();
void RemoveUnusedBlocks(int32_t maxAccessed = LONG_MAX, int32_t count = LONG_MAX);
void FreeBlock(cached_block *block);
cached_block *NewBlock(fssh_off_t blockNumber);
void Free(void *address);
void *Allocate();
static void LowMemoryHandler(void *data, int32_t level);
};
} // namespace FSShell
#endif /* _FSSH_BLOCK_CACHE_PRIVATE_H */
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <BeOSBuildCompatibility.h>
#include "fssh_errno.h"
#include <errno.h>
int *
_fssh_errnop(void)
{
return &errno;
}
int
fssh_get_errno(void)
{
return errno;
}
void
fssh_set_errno(int error)
{
errno = error;
}
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "fssh_fcntl.h"
#include <fcntl.h>
#include <stdarg.h>
#include "stat_util.h"
using namespace FSShell;
int
fssh_open(const char *pathname, int oflags, ...)
{
va_list args;
va_start(args, oflags);
// get the mode, if O_CREAT was specified
fssh_mode_t mode = 0;
if (oflags & FSSH_O_CREAT)
mode = va_arg(args, fssh_mode_t);
va_end(args);
// TODO: That's not perfect yet: We should use open() on BeOS compatible
// platforms and _kern_open() otherwise.
return open(pathname, to_platform_open_mode(oflags),
to_platform_mode(mode));
}
+736
View File
@@ -0,0 +1,736 @@
/* Operations on file descriptors
*
* Copyright 2002-2007, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "fd.h"
#include <stdlib.h>
#include "fssh_fcntl.h"
#include "fssh_kernel_export.h"
#include "fssh_kernel_priv.h"
#include "fssh_string.h"
#include "fssh_uio.h"
//#define TRACE_FD
#ifdef TRACE_FD
# define TRACE(x) dprintf x
#else
# define TRACE(x)
#endif
namespace FSShell {
io_context gKernelIOContext;
/*** General fd routines ***/
#ifdef DEBUG
void dump_fd(int fd, struct file_descriptor *descriptor);
void
dump_fd(int fd,struct file_descriptor *descriptor)
{
dprintf("fd[%d] = %p: type = %ld, ref_count = %ld, ops = %p, u.vnode = %p, u.mount = %p, cookie = %p, open_mode = %lx, pos = %Ld\n",
fd, descriptor, descriptor->type, descriptor->ref_count, descriptor->ops,
descriptor->u.vnode, descriptor->u.mount, descriptor->cookie, descriptor->open_mode, descriptor->pos);
}
#endif
/** Allocates and initializes a new file_descriptor */
struct file_descriptor *
alloc_fd(void)
{
struct file_descriptor *descriptor;
descriptor = (file_descriptor*)malloc(sizeof(struct file_descriptor));
if (descriptor == NULL)
return NULL;
descriptor->u.vnode = NULL;
descriptor->cookie = NULL;
descriptor->ref_count = 1;
descriptor->open_count = 0;
descriptor->open_mode = 0;
descriptor->pos = 0;
return descriptor;
}
bool
fd_close_on_exec(struct io_context *context, int fd)
{
return CHECK_BIT(context->fds_close_on_exec[fd / 8], fd & 7) ? true : false;
}
void
fd_set_close_on_exec(struct io_context *context, int fd, bool closeFD)
{
if (closeFD)
context->fds_close_on_exec[fd / 8] |= (1 << (fd & 7));
else
context->fds_close_on_exec[fd / 8] &= ~(1 << (fd & 7));
}
/** Searches a free slot in the FD table of the provided I/O context, and inserts
* the specified descriptor into it.
*/
int
new_fd_etc(struct io_context *context, struct file_descriptor *descriptor,
int firstIndex)
{
int fd = -1;
uint32_t i;
mutex_lock(&context->io_mutex);
for (i = firstIndex; i < context->table_size; i++) {
if (!context->fds[i]) {
fd = i;
break;
}
}
if (fd < 0) {
fd = FSSH_B_NO_MORE_FDS;
goto err;
}
context->fds[fd] = descriptor;
context->num_used_fds++;
fssh_atomic_add(&descriptor->open_count, 1);
err:
mutex_unlock(&context->io_mutex);
return fd;
}
int
new_fd(struct io_context *context, struct file_descriptor *descriptor)
{
return new_fd_etc(context, descriptor, 0);
}
/** Reduces the descriptor's reference counter, and frees all resources
* when it's no longer used.
*/
void
put_fd(struct file_descriptor *descriptor)
{
int32_t previous = fssh_atomic_add(&descriptor->ref_count, -1);
TRACE(("put_fd(descriptor = %p [ref = %ld, cookie = %p])\n",
descriptor, descriptor->ref_count, descriptor->cookie));
// free the descriptor if we don't need it anymore
if (previous == 1) {
// free the underlying object
if (descriptor->ops != NULL && descriptor->ops->fd_free != NULL)
descriptor->ops->fd_free(descriptor);
free(descriptor);
} else if ((descriptor->open_mode & FSSH_O_DISCONNECTED) != 0
&& previous - 1 == descriptor->open_count
&& descriptor->ops != NULL) {
// the descriptor has been disconnected - it cannot
// be accessed anymore, let's close it (no one is
// currently accessing this descriptor)
if (descriptor->ops->fd_close)
descriptor->ops->fd_close(descriptor);
if (descriptor->ops->fd_free)
descriptor->ops->fd_free(descriptor);
// prevent this descriptor from being closed/freed again
descriptor->open_count = -1;
descriptor->ref_count = -1;
descriptor->ops = NULL;
descriptor->u.vnode = NULL;
// the file descriptor is kept intact, so that it's not
// reused until someone explicetly closes it
}
}
/** Decrements the open counter of the file descriptor and invokes
* its close hook when appropriate.
*/
void
close_fd(struct file_descriptor *descriptor)
{
if (fssh_atomic_add(&descriptor->open_count, -1) == 1) {
vfs_unlock_vnode_if_locked(descriptor);
if (descriptor->ops != NULL && descriptor->ops->fd_close != NULL)
descriptor->ops->fd_close(descriptor);
}
}
/** This descriptor's underlying object will be closed and freed
* as soon as possible (in one of the next calls to put_fd() -
* get_fd() will no longer succeed on this descriptor).
* This is useful if the underlying object is gone, for instance
* when a (mounted) volume got removed unexpectedly.
*/
void
disconnect_fd(struct file_descriptor *descriptor)
{
descriptor->open_mode |= FSSH_O_DISCONNECTED;
}
void
inc_fd_ref_count(struct file_descriptor *descriptor)
{
fssh_atomic_add(&descriptor->ref_count, 1);
}
struct file_descriptor *
get_fd(struct io_context *context, int fd)
{
struct file_descriptor *descriptor = NULL;
if (fd < 0)
return NULL;
mutex_lock(&context->io_mutex);
if ((uint32_t)fd < context->table_size)
descriptor = context->fds[fd];
if (descriptor != NULL) {
// Disconnected descriptors cannot be accessed anymore
if (descriptor->open_mode & FSSH_O_DISCONNECTED)
descriptor = NULL;
else
inc_fd_ref_count(descriptor);
}
mutex_unlock(&context->io_mutex);
return descriptor;
}
/** Removes the file descriptor from the specified slot.
*/
static struct file_descriptor *
remove_fd(struct io_context *context, int fd)
{
struct file_descriptor *descriptor = NULL;
if (fd < 0)
return NULL;
mutex_lock(&context->io_mutex);
if ((uint32_t)fd < context->table_size)
descriptor = context->fds[fd];
if (descriptor) {
// fd is valid
context->fds[fd] = NULL;
fd_set_close_on_exec(context, fd, false);
context->num_used_fds--;
if (descriptor->open_mode & FSSH_O_DISCONNECTED)
descriptor = NULL;
}
mutex_unlock(&context->io_mutex);
return descriptor;
}
static int
dup_fd(int fd, bool kernel)
{
struct io_context *context = get_current_io_context(kernel);
struct file_descriptor *descriptor;
int status;
TRACE(("dup_fd: fd = %d\n", fd));
// Try to get the fd structure
descriptor = get_fd(context, fd);
if (descriptor == NULL)
return FSSH_B_FILE_ERROR;
// now put the fd in place
status = new_fd(context, descriptor);
if (status < 0)
put_fd(descriptor);
else {
mutex_lock(&context->io_mutex);
fd_set_close_on_exec(context, status, false);
mutex_unlock(&context->io_mutex);
}
return status;
}
/** POSIX says this should be the same as:
* close(newfd);
* fcntl(oldfd, F_DUPFD, newfd);
*
* We do dup2() directly to be thread-safe.
*/
static int
dup2_fd(int oldfd, int newfd, bool kernel)
{
struct file_descriptor *evicted = NULL;
struct io_context *context;
TRACE(("dup2_fd: ofd = %d, nfd = %d\n", oldfd, newfd));
// quick check
if (oldfd < 0 || newfd < 0)
return FSSH_B_FILE_ERROR;
// Get current I/O context and lock it
context = get_current_io_context(kernel);
mutex_lock(&context->io_mutex);
// Check if the fds are valid (mutex must be locked because
// the table size could be changed)
if ((uint32_t)oldfd >= context->table_size
|| (uint32_t)newfd >= context->table_size
|| context->fds[oldfd] == NULL) {
mutex_unlock(&context->io_mutex);
return FSSH_B_FILE_ERROR;
}
// Check for identity, note that it cannot be made above
// because we always want to return an error on invalid
// handles
if (oldfd != newfd) {
// Now do the work
evicted = context->fds[newfd];
fssh_atomic_add(&context->fds[oldfd]->ref_count, 1);
fssh_atomic_add(&context->fds[oldfd]->open_count, 1);
context->fds[newfd] = context->fds[oldfd];
if (evicted == NULL)
context->num_used_fds++;
}
fd_set_close_on_exec(context, newfd, false);
mutex_unlock(&context->io_mutex);
// Say bye bye to the evicted fd
if (evicted) {
close_fd(evicted);
put_fd(evicted);
}
return newfd;
}
fssh_status_t
select_fd(int fd, uint8_t event, uint32_t ref, struct select_sync *sync, bool kernel)
{
// struct file_descriptor *descriptor;
// fssh_status_t status;
//
// TRACE(("select_fd(fd = %d, event = %u, ref = %lu, selectsync = %p)\n", fd, event, ref, sync));
//
// descriptor = get_fd(get_current_io_context(kernel), fd);
// if (descriptor == NULL)
// return FSSH_B_FILE_ERROR;
//
// if (descriptor->ops->fd_select) {
// status = descriptor->ops->fd_select(descriptor, event, ref, sync);
// } else {
// // if the I/O subsystem doesn't support select(), we will
// // immediately notify the select call
// status = notify_select_event((void *)sync, ref, event);
// }
//
// put_fd(descriptor);
// return status;
return FSSH_B_BAD_VALUE;
}
fssh_status_t
deselect_fd(int fd, uint8_t event, struct select_sync *sync, bool kernel)
{
// struct file_descriptor *descriptor;
// fssh_status_t status;
//
// TRACE(("deselect_fd(fd = %d, event = %u, selectsync = %p)\n", fd, event, sync));
//
// descriptor = get_fd(get_current_io_context(kernel), fd);
// if (descriptor == NULL)
// return FSSH_B_FILE_ERROR;
//
// if (descriptor->ops->fd_deselect)
// status = descriptor->ops->fd_deselect(descriptor, event, sync);
// else
// status = FSSH_B_OK;
//
// put_fd(descriptor);
// return status;
return FSSH_B_BAD_VALUE;
}
/** This function checks if the specified fd is valid in the current
* context. It can be used for a quick check; the fd is not locked
* so it could become invalid immediately after this check.
*/
bool
fd_is_valid(int fd, bool kernel)
{
struct file_descriptor *descriptor = get_fd(get_current_io_context(kernel), fd);
if (descriptor == NULL)
return false;
put_fd(descriptor);
return true;
}
struct vnode *
fd_vnode(struct file_descriptor *descriptor)
{
switch (descriptor->type) {
case FDTYPE_FILE:
case FDTYPE_DIR:
case FDTYPE_ATTR_DIR:
case FDTYPE_ATTR:
return descriptor->u.vnode;
}
return NULL;
}
static fssh_status_t
common_close(int fd, bool kernel)
{
struct io_context *io = get_current_io_context(kernel);
struct file_descriptor *descriptor = remove_fd(io, fd);
if (descriptor == NULL)
return FSSH_B_FILE_ERROR;
#ifdef TRACE_FD
if (!kernel)
TRACE(("_user_close(descriptor = %p)\n", descriptor));
#endif
close_fd(descriptor);
put_fd(descriptor);
// the reference associated with the slot
return FSSH_B_OK;
}
} // namespace FSShell
// #pragma mark -
// Kernel calls
using namespace FSShell;
fssh_ssize_t
_kern_read(int fd, fssh_off_t pos, void *buffer, fssh_size_t length)
{
struct file_descriptor *descriptor;
fssh_ssize_t bytesRead;
descriptor = get_fd(get_current_io_context(true), fd);
if (!descriptor)
return FSSH_B_FILE_ERROR;
if ((descriptor->open_mode & FSSH_O_RWMASK) == FSSH_O_WRONLY) {
put_fd(descriptor);
return FSSH_B_FILE_ERROR;
}
if (pos == -1)
pos = descriptor->pos;
if (descriptor->ops->fd_read) {
bytesRead = descriptor->ops->fd_read(descriptor, pos, buffer, &length);
if (bytesRead >= FSSH_B_OK) {
if (length > SSIZE_MAX)
bytesRead = SSIZE_MAX;
else
bytesRead = (fssh_ssize_t)length;
descriptor->pos = pos + length;
}
} else
bytesRead = FSSH_B_BAD_VALUE;
put_fd(descriptor);
return bytesRead;
}
fssh_ssize_t
_kern_readv(int fd, fssh_off_t pos, const fssh_iovec *vecs, fssh_size_t count)
{
struct file_descriptor *descriptor;
fssh_ssize_t bytesRead = 0;
fssh_status_t status;
uint32_t i;
descriptor = get_fd(get_current_io_context(true), fd);
if (!descriptor)
return FSSH_B_FILE_ERROR;
if ((descriptor->open_mode & FSSH_O_RWMASK) == FSSH_O_WRONLY) {
put_fd(descriptor);
return FSSH_B_FILE_ERROR;
}
if (pos == -1)
pos = descriptor->pos;
if (descriptor->ops->fd_read) {
for (i = 0; i < count; i++) {
fssh_size_t length = vecs[i].iov_len;
status = descriptor->ops->fd_read(descriptor, pos, vecs[i].iov_base, &length);
if (status < FSSH_B_OK) {
bytesRead = status;
break;
}
if ((uint32_t)bytesRead + length > SSIZE_MAX)
bytesRead = SSIZE_MAX;
else
bytesRead += (fssh_ssize_t)length;
pos += vecs[i].iov_len;
}
} else
bytesRead = FSSH_B_BAD_VALUE;
descriptor->pos = pos;
put_fd(descriptor);
return bytesRead;
}
fssh_ssize_t
_kern_write(int fd, fssh_off_t pos, const void *buffer, fssh_size_t length)
{
struct file_descriptor *descriptor;
fssh_ssize_t bytesWritten;
descriptor = get_fd(get_current_io_context(true), fd);
if (descriptor == NULL)
return FSSH_B_FILE_ERROR;
if ((descriptor->open_mode & FSSH_O_RWMASK) == FSSH_O_RDONLY) {
put_fd(descriptor);
return FSSH_B_FILE_ERROR;
}
if (pos == -1)
pos = descriptor->pos;
if (descriptor->ops->fd_write) {
bytesWritten = descriptor->ops->fd_write(descriptor, pos, buffer, &length);
if (bytesWritten >= FSSH_B_OK) {
if (length > SSIZE_MAX)
bytesWritten = SSIZE_MAX;
else
bytesWritten = (fssh_ssize_t)length;
descriptor->pos = pos + length;
}
} else
bytesWritten = FSSH_B_BAD_VALUE;
put_fd(descriptor);
return bytesWritten;
}
fssh_ssize_t
_kern_writev(int fd, fssh_off_t pos, const fssh_iovec *vecs, fssh_size_t count)
{
struct file_descriptor *descriptor;
fssh_ssize_t bytesWritten = 0;
fssh_status_t status;
uint32_t i;
descriptor = get_fd(get_current_io_context(true), fd);
if (!descriptor)
return FSSH_B_FILE_ERROR;
if ((descriptor->open_mode & FSSH_O_RWMASK) == FSSH_O_RDONLY) {
put_fd(descriptor);
return FSSH_B_FILE_ERROR;
}
if (pos == -1)
pos = descriptor->pos;
if (descriptor->ops->fd_write) {
for (i = 0; i < count; i++) {
fssh_size_t length = vecs[i].iov_len;
status = descriptor->ops->fd_write(descriptor, pos, vecs[i].iov_base, &length);
if (status < FSSH_B_OK) {
bytesWritten = status;
break;
}
if ((uint32_t)bytesWritten + length > SSIZE_MAX)
bytesWritten = SSIZE_MAX;
else
bytesWritten += (fssh_ssize_t)length;
pos += vecs[i].iov_len;
}
} else
bytesWritten = FSSH_B_BAD_VALUE;
descriptor->pos = pos;
put_fd(descriptor);
return bytesWritten;
}
fssh_off_t
_kern_seek(int fd, fssh_off_t pos, int seekType)
{
struct file_descriptor *descriptor;
descriptor = get_fd(get_current_io_context(true), fd);
if (!descriptor)
return FSSH_B_FILE_ERROR;
if (descriptor->ops->fd_seek)
pos = descriptor->ops->fd_seek(descriptor, pos, seekType);
else
pos = FSSH_ESPIPE;
put_fd(descriptor);
return pos;
}
fssh_status_t
_kern_ioctl(int fd, uint32_t op, void *buffer, fssh_size_t length)
{
struct file_descriptor *descriptor;
int status;
TRACE(("sys_ioctl: fd %d\n", fd));
descriptor = get_fd(get_current_io_context(true), fd);
if (descriptor == NULL)
return FSSH_B_FILE_ERROR;
if (descriptor->ops->fd_ioctl)
status = descriptor->ops->fd_ioctl(descriptor, op, buffer, length);
else
status = FSSH_EOPNOTSUPP;
put_fd(descriptor);
return status;
}
fssh_ssize_t
_kern_read_dir(int fd, struct fssh_dirent *buffer, fssh_size_t bufferSize, uint32_t maxCount)
{
struct file_descriptor *descriptor;
fssh_ssize_t retval;
TRACE(("sys_read_dir(fd = %d, buffer = %p, bufferSize = %ld, count = %lu)\n",fd, buffer, bufferSize, maxCount));
descriptor = get_fd(get_current_io_context(true), fd);
if (descriptor == NULL)
return FSSH_B_FILE_ERROR;
if (descriptor->ops->fd_read_dir) {
uint32_t count = maxCount;
retval = descriptor->ops->fd_read_dir(descriptor, buffer, bufferSize, &count);
if (retval >= 0)
retval = count;
} else
retval = FSSH_EOPNOTSUPP;
put_fd(descriptor);
return retval;
}
fssh_status_t
_kern_rewind_dir(int fd)
{
struct file_descriptor *descriptor;
fssh_status_t status;
TRACE(("sys_rewind_dir(fd = %d)\n",fd));
descriptor = get_fd(get_current_io_context(true), fd);
if (descriptor == NULL)
return FSSH_B_FILE_ERROR;
if (descriptor->ops->fd_rewind_dir)
status = descriptor->ops->fd_rewind_dir(descriptor);
else
status = FSSH_EOPNOTSUPP;
put_fd(descriptor);
return status;
}
fssh_status_t
_kern_close(int fd)
{
return common_close(fd, true);
}
int
_kern_dup(int fd)
{
return dup_fd(fd, true);
}
int
_kern_dup2(int ofd, int nfd)
{
return dup2_fd(ofd, nfd, true);
}
+117
View File
@@ -0,0 +1,117 @@
/*
* Copyright 2002-2006, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_FD_H
#define _FSSH_FD_H
#include "vfs.h"
namespace FSShell {
struct file_descriptor;
struct select_sync;
struct vnode;
extern io_context gKernelIOContext;
struct fd_ops {
fssh_status_t (*fd_read)(struct file_descriptor *, fssh_off_t pos,
void *buffer, fssh_size_t *length);
fssh_status_t (*fd_write)(struct file_descriptor *, fssh_off_t pos,
const void *buffer, fssh_size_t *length);
fssh_off_t (*fd_seek)(struct file_descriptor *, fssh_off_t pos,
int seekType);
fssh_status_t (*fd_ioctl)(struct file_descriptor *, uint32_t op,
void *buffer, fssh_size_t length);
fssh_status_t (*fd_select)(struct file_descriptor *, uint8_t event,
uint32_t ref, struct select_sync *sync);
fssh_status_t (*fd_deselect)(struct file_descriptor *, uint8_t event,
struct select_sync *sync);
fssh_status_t (*fd_read_dir)(struct file_descriptor *,
struct fssh_dirent *buffer, fssh_size_t bufferSize,
uint32_t *_count);
fssh_status_t (*fd_rewind_dir)(struct file_descriptor *);
fssh_status_t (*fd_read_stat)(struct file_descriptor *,
struct fssh_stat *);
fssh_status_t (*fd_write_stat)(struct file_descriptor *,
const struct fssh_stat *, int statMask);
fssh_status_t (*fd_close)(struct file_descriptor *);
void (*fd_free)(struct file_descriptor *);
};
struct file_descriptor {
int32_t type; /* descriptor type */
int32_t ref_count;
int32_t open_count;
struct fd_ops* ops;
union {
struct vnode* vnode;
struct fs_mount* mount;
} u;
void* cookie;
int32_t open_mode;
fssh_off_t pos;
};
/* Types of file descriptors we can create */
enum fd_types {
FDTYPE_FILE = 1,
FDTYPE_ATTR,
FDTYPE_DIR,
FDTYPE_ATTR_DIR,
FDTYPE_INDEX,
FDTYPE_INDEX_DIR,
FDTYPE_QUERY,
FDTYPE_SOCKET
};
// additional open mode - kernel special
#define FSSH_O_DISCONNECTED 0x80000000
/* Prototypes */
extern file_descriptor* alloc_fd(void);
extern int new_fd_etc(struct io_context *,
struct file_descriptor *, int firstIndex);
extern int new_fd(struct io_context *, struct file_descriptor *);
extern file_descriptor* get_fd(struct io_context *, int);
extern void close_fd(struct file_descriptor *descriptor);
extern void put_fd(struct file_descriptor *descriptor);
extern void disconnect_fd(struct file_descriptor *descriptor);
extern void inc_fd_ref_count(struct file_descriptor *descriptor);
extern fssh_status_t select_fd(int fd, uint8_t event, uint32_t ref,
struct select_sync *sync, bool kernel);
extern fssh_status_t deselect_fd(int fd, uint8_t event,
struct select_sync *sync, bool kernel);
extern bool fd_is_valid(int fd, bool kernel);
extern vnode* fd_vnode(struct file_descriptor *descriptor);
extern bool fd_close_on_exec(struct io_context *context, int fd);
extern void fd_set_close_on_exec(struct io_context *context, int fd,
bool closeFD);
static io_context* get_current_io_context(bool kernel);
/* The prototypes of the (sys|user)_ functions are currently defined in vfs.h */
/* Inlines */
static inline struct io_context *
get_current_io_context(bool /*kernel*/)
{
return &gKernelIOContext;
}
} // namespace FSShell
#endif /* _FSSH_FD_H */
File diff suppressed because it is too large Load Diff
+11
View File
@@ -0,0 +1,11 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
int
main()
{
return 0;
}
+310
View File
@@ -0,0 +1,310 @@
/* Generic hash table
**
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include "hash.h"
#include <stdlib.h>
#include "fssh_errors.h"
#include "fssh_kernel_export.h"
#undef TRACE
#define TRACE_HASH 0
#if TRACE_HASH
# define TRACE(x) fssh_dprintf x
#else
# define TRACE(x) ;
#endif
#undef ASSERT
#define ASSERT(x)
namespace FSShell {
// TODO: the hashtable is not expanded when necessary (no load factor, nothing)
// resizing should be optional, though, in case the hash is used at times
// that forbid resizing.
struct hash_table {
struct hash_element **table;
int next_ptr_offset;
uint32_t table_size;
int num_elements;
int flags;
int (*compare_func)(void *e, const void *key);
uint32_t (*hash_func)(void *e, const void *key, uint32_t range);
};
// XXX gross hack
#define NEXT_ADDR(t, e) ((void *)(((unsigned long)(e)) + (t)->next_ptr_offset))
#define NEXT(t, e) ((void *)(*(unsigned long *)NEXT_ADDR(t, e)))
#define PUT_IN_NEXT(t, e, val) (*(unsigned long *)NEXT_ADDR(t, e) = (long)(val))
static inline void *
next_element(hash_table *table, void *element)
{
// ToDo: should we use this instead of the NEXT() macro?
return (void *)(*(unsigned long *)NEXT_ADDR(table, element));
}
struct hash_table *
hash_init(uint32_t table_size, int next_ptr_offset,
int compare_func(void *e, const void *key),
uint32_t hash_func(void *e, const void *key, uint32_t range))
{
struct hash_table *t;
unsigned int i;
if (compare_func == NULL || hash_func == NULL) {
fssh_dprintf("hash_init() called with NULL function pointer\n");
return NULL;
}
t = (struct hash_table *)malloc(sizeof(struct hash_table));
if (t == NULL)
return NULL;
t->table = (struct hash_element **)malloc(sizeof(void *) * table_size);
if (t->table == NULL) {
free(t);
return NULL;
}
for (i = 0; i < table_size; i++)
t->table[i] = NULL;
t->table_size = table_size;
t->next_ptr_offset = next_ptr_offset;
t->flags = 0;
t->num_elements = 0;
t->compare_func = compare_func;
t->hash_func = hash_func;
TRACE(("hash_init: created table %p, next_ptr_offset %d, compare_func %p, hash_func %p\n",
t, next_ptr_offset, compare_func, hash_func));
return t;
}
int
hash_uninit(struct hash_table *table)
{
ASSERT(table->num_elements == 0);
free(table->table);
free(table);
return 0;
}
fssh_status_t
hash_insert(struct hash_table *table, void *element)
{
uint32_t hash;
ASSERT(table != NULL && element != NULL);
TRACE(("hash_insert: table 0x%x, element 0x%x\n", table, element));
hash = table->hash_func(element, NULL, table->table_size);
PUT_IN_NEXT(table, element, table->table[hash]);
table->table[hash] = (struct hash_element *)element;
table->num_elements++;
// ToDo: resize hash table if it's grown too much!
return FSSH_B_OK;
}
fssh_status_t
hash_remove(struct hash_table *table, void *_element)
{
uint32_t hash = table->hash_func(_element, NULL, table->table_size);
void *element, *lastElement = NULL;
for (element = table->table[hash]; element != NULL;
lastElement = element, element = NEXT(table, element)) {
if (element == _element) {
if (lastElement != NULL) {
// connect the previous entry with the next one
PUT_IN_NEXT(table, lastElement, NEXT(table, element));
} else
table->table[hash] = (struct hash_element *)NEXT(table, element);
table->num_elements--;
return FSSH_B_OK;
}
}
return FSSH_B_ERROR;
}
void
hash_remove_current(struct hash_table *table, struct hash_iterator *iterator)
{
uint32_t index = iterator->bucket;
void *element;
if (iterator->current == NULL)
fssh_panic("hash_remove_current() called too early.");
for (element = table->table[index]; index < table->table_size; index++) {
void *lastElement = NULL;
while (element != NULL) {
if (element == iterator->current) {
iterator->current = lastElement;
if (lastElement != NULL) {
// connect the previous entry with the next one
PUT_IN_NEXT(table, lastElement, NEXT(table, element));
} else {
table->table[index] = (struct hash_element *)NEXT(table,
element);
}
table->num_elements--;
return;
}
element = NEXT(table, element);
}
}
}
void *
hash_remove_first(struct hash_table *table, uint32_t *_cookie)
{
uint32_t index;
for (index = _cookie ? *_cookie : 0; index < table->table_size; index++) {
void *element = table->table[index];
if (element != NULL) {
// remove the first element we find
table->table[index] = (struct hash_element *)NEXT(table, element);
table->num_elements--;
if (_cookie)
*_cookie = index;
return element;
}
}
return NULL;
}
void *
hash_find(struct hash_table *table, void *searchedElement)
{
uint32_t hash = table->hash_func(searchedElement, NULL, table->table_size);
void *element;
for (element = table->table[hash]; element != NULL; element = NEXT(table, element)) {
if (element == searchedElement)
return element;
}
return NULL;
}
void *
hash_lookup(struct hash_table *table, const void *key)
{
uint32_t hash = table->hash_func(NULL, key, table->table_size);
void *element;
for (element = table->table[hash]; element != NULL; element = NEXT(table, element)) {
if (table->compare_func(element, key) == 0)
return element;
}
return NULL;
}
struct hash_iterator *
hash_open(struct hash_table *table, struct hash_iterator *iterator)
{
if (iterator == NULL) {
iterator = (struct hash_iterator *)malloc(sizeof(struct hash_iterator));
if (iterator == NULL)
return NULL;
}
hash_rewind(table, iterator);
return iterator;
}
void
hash_close(struct hash_table *table, struct hash_iterator *iterator, bool freeIterator)
{
if (freeIterator)
free(iterator);
}
void
hash_rewind(struct hash_table *table, struct hash_iterator *iterator)
{
iterator->current = NULL;
iterator->bucket = -1;
}
void *
hash_next(struct hash_table *table, struct hash_iterator *iterator)
{
uint32_t index;
restart:
if (iterator->current == NULL) {
// get next bucket
for (index = (uint32_t)(iterator->bucket + 1); index < table->table_size; index++) {
if (table->table[index]) {
iterator->bucket = index;
iterator->current = table->table[index];
break;
}
}
} else {
iterator->current = NEXT(table, iterator->current);
if (!iterator->current)
goto restart;
}
return iterator->current;
}
uint32_t
hash_hash_string(const char *string)
{
uint32_t hash = 0;
char c;
// we assume hash to be at least 32 bits
while ((c = *string++) != 0) {
hash ^= hash >> 28;
hash <<= 4;
hash ^= c;
}
return hash;
}
} // namespace FSShell
+51
View File
@@ -0,0 +1,51 @@
/*
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#ifndef _FSSH_HASH_H
#define _FSSH_HASH_H
#include "fssh_types.h"
namespace FSShell {
// can be allocated on the stack
typedef struct hash_iterator {
void *current;
int bucket;
} hash_iterator;
typedef struct hash_table hash_table;
struct hash_table *hash_init(uint32_t table_size, int next_ptr_offset,
int compare_func(void *element, const void *key),
uint32_t hash_func(void *element, const void *key, uint32_t range));
int hash_uninit(struct hash_table *table);
fssh_status_t hash_insert(struct hash_table *table, void *_element);
fssh_status_t hash_remove(struct hash_table *table, void *_element);
void hash_remove_current(struct hash_table *table, struct hash_iterator *iterator);
void *hash_remove_first(struct hash_table *table, uint32_t *_cookie);
void *hash_find(struct hash_table *table, void *e);
void *hash_lookup(struct hash_table *table, const void *key);
struct hash_iterator *hash_open(struct hash_table *table, struct hash_iterator *i);
void hash_close(struct hash_table *table, struct hash_iterator *i, bool free_iterator);
void *hash_next(struct hash_table *table, struct hash_iterator *i);
void hash_rewind(struct hash_table *table, struct hash_iterator *i);
/* function pointers must look like this:
*
* uint32 hash_func(void *e, const void *key, uint32 range);
* hash function should calculate hash on either e or key,
* depending on which one is not NULL - they also need
* to make sure the returned value is within range.
* int compare_func(void *e, const void *key);
* compare function should compare the element with
* the key, returning 0 if equal, other if not
*/
uint32_t hash_hash_string(const char *str);
} // namespace FSShell
#endif /* _FSSH_HASH_H */
+91
View File
@@ -0,0 +1,91 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "fssh_kernel_export.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "fssh_errors.h"
fssh_thread_id
fssh_spawn_kernel_thread(fssh_thread_func function, const char *threadName,
int32_t priority, void *arg)
{
return FSSH_B_ERROR;
}
void
fssh_dprintf(const char *format, ...)
{
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
void
fssh_kprintf(const char *format, ...)
{
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
void
fssh_dump_block(const char *buffer, int size, const char *prefix)
{
}
void
fssh_panic(const char *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
exit(1);
va_end(args);
}
void
fssh_kernel_debugger(const char *message)
{
fssh_panic("%s", message);
}
uint32_t
fssh_parse_expression(const char *string)
{
return 0;
}
int
fssh_add_debugger_command(char *name, fssh_debugger_command_hook hook,
char *help)
{
return 0;
}
int
fssh_remove_debugger_command(char *name, fssh_debugger_command_hook hook)
{
return 0;
}
+253
View File
@@ -0,0 +1,253 @@
/*
* Copyright 2003-2006, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "list.h"
#define GET_ITEM(list, item) ((void *)((uint8_t *)item - list->offset))
#define GET_LINK(list, item) ((list_link *)((uint8_t *)item + list->offset))
namespace FSShell {
/** Initializes the list with a specified offset to the link
* structure in the items that will be part of the list.
*/
void
list_init_etc(struct list *list, int32_t offset)
{
list->link.next = list->link.prev = &list->link;
list->offset = offset;
}
void
list_init(struct list *list)
{
list_init_etc(list, 0);
}
/** Adds a link to the head of the list
*/
void
list_add_link_to_head(struct list *list, void *_link)
{
list_link *link = (list_link *)_link;
link->next = list->link.next;
link->prev = &list->link;
list->link.next->prev = link;
list->link.next = link;
}
/** Adds a link to the tail of the list
*/
void
list_add_link_to_tail(struct list *list, void *_link)
{
list_link *link = (list_link *)_link;
link->next = &list->link;
link->prev = list->link.prev;
list->link.prev->next = link;
list->link.prev = link;
}
/** Removes a link from the list it's currently in.
* Note: the link has to be in a list when you call this function.
*/
void
list_remove_link(void *_link)
{
list_link *link = (list_link *)_link;
link->next->prev = link->prev;
link->prev->next = link->next;
}
static inline list_link *
get_next_link(struct list *list, list_link *link)
{
if (link->next == &list->link)
return NULL;
return link->next;
}
static inline list_link *
get_prev_link(struct list *list, list_link *link)
{
if (link->prev == &list->link)
return NULL;
return link->prev;
}
/** Gets the successor for the current item. If the passed
* item is NULL, it returns the first entry in the list,
* if there is one.
* Returns NULL if there aren't any more items in this list.
*/
void *
list_get_next_item(struct list *list, void *item)
{
list_link *link;
if (item == NULL)
return list_is_empty(list) ? NULL : GET_ITEM(list, list->link.next);
link = get_next_link(list, GET_LINK(list, item));
return link != NULL ? GET_ITEM(list, link) : NULL;
}
/** Gets the predecessor for the current item. If the passed
* item is NULL, it returns the last entry in the list,
* if there is one.
* Returns NULL if there aren't any previous items in this list.
*/
void *
list_get_prev_item(struct list *list, void *item)
{
list_link *link;
if (item == NULL)
return list_is_empty(list) ? NULL : GET_ITEM(list, list->link.prev);
link = get_prev_link(list, GET_LINK(list, item));
return link != NULL ? GET_ITEM(list, link) : NULL;
}
void *
list_get_last_item(struct list *list)
{
return list_is_empty(list) ? NULL : GET_ITEM(list, list->link.prev);
}
/** Adds an item to the end of the list.
* Similar to list_add_link_to_tail() but works on the item, not the link.
*/
void
list_add_item(struct list *list, void *item)
{
list_add_link_to_tail(list, GET_LINK(list, item));
}
/** Removes an item from the list.
* Similar to list_remove_link() but works on the item, not the link.
*/
void
list_remove_item(struct list *list, void *item)
{
list_remove_link(GET_LINK(list, item));
}
/** Inserts an item before another item in the list.
* If you pass NULL as \a before item, the item is added at the end of
* the list.
*/
void
list_insert_item_before(struct list *list, void *before, void *item)
{
list_link *beforeLink;
list_link *link;
if (before == NULL) {
list_add_item(list, item);
return;
}
beforeLink = GET_LINK(list, before);
link = GET_LINK(list, item);
link->prev = beforeLink->prev;
link->next = beforeLink;
beforeLink->prev->next = link;
beforeLink->prev = link;
}
/** Removes the first item in the list and returns it.
* Returns NULL if the list is empty.
*/
void *
list_remove_head_item(struct list *list)
{
list_link *link;
if (list_is_empty(list))
return NULL;
list_remove_link(link = list->link.next);
return GET_ITEM(list, link);
}
/** Removes the last item in the list and returns it.
* Returns NULL if the list is empty.
*/
void *
list_remove_tail_item(struct list *list)
{
list_link *link;
if (list_is_empty(list))
return NULL;
list_remove_link(link = list->link.prev);
return GET_ITEM(list, link);
}
/** Moves the contents of the source list to the target list.
* The target list will be emptied before the items are moved;
* this is a very fast operation.
*/
void
list_move_to_list(struct list *sourceList, struct list *targetList)
{
if (list_is_empty(sourceList)) {
targetList->link.next = targetList->link.prev = &targetList->link;
return;
}
*targetList = *sourceList;
// correct link pointers to this list
targetList->link.next->prev = &targetList->link;
targetList->link.prev->next = &targetList->link;
// empty source list
sourceList->link.next = sourceList->link.prev = &sourceList->link;
}
} // namespace FSShell
+74
View File
@@ -0,0 +1,74 @@
/*
* Copyright 2003-2006, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_LIST_H
#define _FSSH_LIST_H
#include "fssh_types.h"
/* This header defines a doubly-linked list. It differentiates between a link
* and an item.
* A link is what is put into and removed from a list, an item is the whole
* object that contains the link. The item doesn't have to be begin with a
* link; the offset to the link structure is given to init_list_etc(), so that
* list_get_next/prev_item() will work correctly.
* Note, the offset value is only needed for the *_item() functions. If the
* offset is 0, list_link and item are identical - if you use init_list(),
* you don't have to care about the difference between a link and an item.
*/
namespace FSShell {
typedef struct list_link list_link;
/* The object that is put into the list must begin with these
* fields, but it doesn't have to be this structure.
*/
struct list_link {
list_link *next;
list_link *prev;
};
struct list {
list_link link;
int32_t offset;
};
extern void list_init(struct list *list);
extern void list_init_etc(struct list *list, int32_t offset);
extern void list_add_link_to_head(struct list *list, void *_link);
extern void list_add_link_to_tail(struct list *list, void *_link);
extern void list_remove_link(void *_link);
extern void *list_get_next_item(struct list *list, void *item);
extern void *list_get_prev_item(struct list *list, void *item);
extern void *list_get_last_item(struct list *list);
extern void list_add_item(struct list *list, void *item);
extern void list_remove_item(struct list *list, void *item);
extern void list_insert_item_before(struct list *list, void *before, void *item);
extern void *list_remove_head_item(struct list *list);
extern void *list_remove_tail_item(struct list *list);
extern void list_move_to_list(struct list *sourceList, struct list *targetList);
static inline bool
list_is_empty(struct list *list)
{
return list->link.next == (list_link *)list;
}
static inline void *
list_get_first_item(struct list *list)
{
return list_get_next_item(list, NULL);
}
} // namespace FSShell
#endif /* _FSSH_LIST_H */
+243
View File
@@ -0,0 +1,243 @@
/*
* Copyright 2002-2007, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
/* Mutex and recursive_lock code */
#include "lock.h"
#include "fssh_kernel_export.h"
namespace FSShell {
int32_t
recursive_lock_get_recursion(recursive_lock *lock)
{
if (lock->holder == fssh_find_thread(NULL))
return lock->recursion;
return -1;
}
fssh_status_t
recursive_lock_init(recursive_lock *lock, const char *name)
{
if (lock == NULL)
return FSSH_B_BAD_VALUE;
if (name == NULL)
name = "recursive lock";
lock->holder = -1;
lock->recursion = 0;
lock->sem = fssh_create_sem(1, name);
if (lock->sem >= FSSH_B_OK)
return FSSH_B_OK;
return lock->sem;
}
void
recursive_lock_destroy(recursive_lock *lock)
{
if (lock == NULL)
return;
fssh_delete_sem(lock->sem);
lock->sem = -1;
}
fssh_status_t
recursive_lock_lock(recursive_lock *lock)
{
fssh_thread_id thread = fssh_find_thread(NULL);
if (thread != lock->holder) {
fssh_status_t status = fssh_acquire_sem(lock->sem);
if (status < FSSH_B_OK)
return status;
lock->holder = thread;
}
lock->recursion++;
return FSSH_B_OK;
}
void
recursive_lock_unlock(recursive_lock *lock)
{
if (fssh_find_thread(NULL) != lock->holder)
fssh_panic("recursive_lock %p unlocked by non-holder thread!\n", lock);
if (--lock->recursion == 0) {
lock->holder = -1;
fssh_release_sem(lock->sem);
}
}
// #pragma mark -
fssh_status_t
mutex_init(mutex *m, const char *name)
{
if (m == NULL)
return FSSH_EINVAL;
if (name == NULL)
name = "mutex_sem";
m->holder = -1;
m->sem = fssh_create_sem(1, name);
if (m->sem >= FSSH_B_OK)
return FSSH_B_OK;
return m->sem;
}
void
mutex_destroy(mutex *mutex)
{
if (mutex == NULL)
return;
if (mutex->sem >= 0) {
fssh_delete_sem(mutex->sem);
mutex->sem = -1;
}
mutex->holder = -1;
}
fssh_status_t
mutex_lock(mutex *mutex)
{
fssh_thread_id me = fssh_find_thread(NULL);
fssh_status_t status;
status = fssh_acquire_sem(mutex->sem);
if (status < FSSH_B_OK)
return status;
if (me == mutex->holder)
fssh_panic("mutex_lock failure: mutex %p (sem = 0x%x) acquired twice by thread 0x%x\n", mutex, (int)mutex->sem, (int)me);
mutex->holder = me;
return FSSH_B_OK;
}
void
mutex_unlock(mutex *mutex)
{
fssh_thread_id me = fssh_find_thread(NULL);
if (me != mutex->holder) {
fssh_panic("mutex_unlock failure: thread 0x%x is trying to release mutex %p (current holder 0x%x)\n",
(int)me, mutex, (int)mutex->holder);
}
mutex->holder = -1;
fssh_release_sem(mutex->sem);
}
// #pragma mark -
fssh_status_t
benaphore_init(benaphore *ben, const char *name)
{
if (ben == NULL || name == NULL)
return FSSH_B_BAD_VALUE;
ben->count = 1;
ben->sem = fssh_create_sem(0, name);
if (ben->sem >= FSSH_B_OK)
return FSSH_B_OK;
return ben->sem;
}
void
benaphore_destroy(benaphore *ben)
{
fssh_delete_sem(ben->sem);
ben->sem = -1;
}
// #pragma mark -
fssh_status_t
rw_lock_init(rw_lock *lock, const char *name)
{
if (lock == NULL)
return FSSH_B_BAD_VALUE;
if (name == NULL)
name = "r/w lock";
lock->sem = fssh_create_sem(FSSH_RW_MAX_READERS, name);
if (lock->sem >= FSSH_B_OK)
return FSSH_B_OK;
return lock->sem;
}
void
rw_lock_destroy(rw_lock *lock)
{
if (lock == NULL)
return;
fssh_delete_sem(lock->sem);
}
fssh_status_t
rw_lock_read_lock(rw_lock *lock)
{
return fssh_acquire_sem(lock->sem);
}
fssh_status_t
rw_lock_read_unlock(rw_lock *lock)
{
return fssh_release_sem(lock->sem);
}
fssh_status_t
rw_lock_write_lock(rw_lock *lock)
{
return fssh_acquire_sem_etc(lock->sem, FSSH_RW_MAX_READERS, 0, 0);
}
fssh_status_t
rw_lock_write_unlock(rw_lock *lock)
{
return fssh_release_sem_etc(lock->sem, FSSH_RW_MAX_READERS, 0);
}
} // namespace FSShell
+160
View File
@@ -0,0 +1,160 @@
/*
* Copyright 2002-2007, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#ifndef _FSSH_LOCK_H
#define _FSSH_LOCK_H
#include "fssh_atomic.h"
#include "fssh_auto_locker.h"
#include "fssh_errors.h"
#include "fssh_os.h"
namespace FSShell {
typedef struct recursive_lock {
fssh_sem_id sem;
fssh_thread_id holder;
int recursion;
} recursive_lock;
typedef struct mutex {
fssh_sem_id sem;
fssh_thread_id holder;
} mutex;
typedef struct benaphore {
fssh_sem_id sem;
int32_t count;
} benaphore;
// Note: this is currently a trivial r/w lock implementation
// it will be replaced with something better later - this
// or a similar API will be made publically available at this point.
typedef struct rw_lock {
fssh_sem_id sem;
int32_t count;
benaphore writeLock;
} rw_lock;
#define FSSH_RW_MAX_READERS 1000000
extern fssh_status_t recursive_lock_init(recursive_lock *lock,
const char *name);
extern void recursive_lock_destroy(recursive_lock *lock);
extern fssh_status_t recursive_lock_lock(recursive_lock *lock);
extern void recursive_lock_unlock(recursive_lock *lock);
extern int32_t recursive_lock_get_recursion(recursive_lock *lock);
extern fssh_status_t mutex_init(mutex *m, const char *name);
extern void mutex_destroy(mutex *m);
extern fssh_status_t mutex_lock(mutex *m);
extern void mutex_unlock(mutex *m);
extern fssh_status_t benaphore_init(benaphore *ben,
const char *name);
extern void benaphore_destroy(benaphore *ben);
static inline fssh_status_t
benaphore_lock_etc(benaphore *ben, uint32_t flags, fssh_bigtime_t timeout)
{
if (fssh_atomic_add(&ben->count, -1) <= 0)
return fssh_acquire_sem_etc(ben->sem, 1, flags, timeout);
return FSSH_B_OK;
}
static inline fssh_status_t
benaphore_lock(benaphore *ben)
{
if (fssh_atomic_add(&ben->count, -1) <= 0)
return fssh_acquire_sem(ben->sem);
return FSSH_B_OK;
}
static inline fssh_status_t
benaphore_unlock(benaphore *ben)
{
if (fssh_atomic_add(&ben->count, 1) < 0)
return fssh_release_sem(ben->sem);
return FSSH_B_OK;
}
extern fssh_status_t rw_lock_init(rw_lock *lock, const char *name);
extern void rw_lock_destroy(rw_lock *lock);
extern fssh_status_t rw_lock_read_lock(rw_lock *lock);
extern fssh_status_t rw_lock_read_unlock(rw_lock *lock);
extern fssh_status_t rw_lock_write_lock(rw_lock *lock);
extern fssh_status_t rw_lock_write_unlock(rw_lock *lock);
/* C++ Auto Locking */
// MutexLocking
class MutexLocking {
public:
inline bool Lock(mutex *lockable)
{
return mutex_lock(lockable) == FSSH_B_OK;
}
inline void Unlock(mutex *lockable)
{
mutex_unlock(lockable);
}
};
// MutexLocker
typedef AutoLocker<mutex, MutexLocking> MutexLocker;
// RecursiveLockLocking
class RecursiveLockLocking {
public:
inline bool Lock(recursive_lock *lockable)
{
return recursive_lock_lock(lockable) == FSSH_B_OK;
}
inline void Unlock(recursive_lock *lockable)
{
recursive_lock_unlock(lockable);
}
};
// RecursiveLocker
typedef AutoLocker<recursive_lock, RecursiveLockLocking> RecursiveLocker;
// BenaphoreLocking
class BenaphoreLocking {
public:
inline bool Lock(benaphore *lockable)
{
return benaphore_lock(lockable) == FSSH_B_OK;
}
inline void Unlock(benaphore *lockable)
{
benaphore_unlock(lockable);
}
};
// BenaphoreLocker
typedef AutoLocker<benaphore, BenaphoreLocking> BenaphoreLocker;
} // namespace FSShell
using FSShell::MutexLocker;
using FSShell::RecursiveLocker;
using FSShell::BenaphoreLocker;
#endif /* _FSSH_LOCK_H */
+66
View File
@@ -0,0 +1,66 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "fssh_errors.h"
#include "fssh_fs_interface.h"
fssh_status_t
fssh_notify_entry_created(fssh_mount_id device, fssh_vnode_id directory,
const char *name, fssh_vnode_id node)
{
return FSSH_B_OK;
}
fssh_status_t
fssh_notify_entry_removed(fssh_mount_id device, fssh_vnode_id directory,
const char *name, fssh_vnode_id node)
{
return FSSH_B_OK;
}
fssh_status_t
fssh_notify_entry_moved(fssh_mount_id device, fssh_vnode_id fromDirectory,
const char *fromName, fssh_vnode_id toDirectory, const char *toName,
fssh_vnode_id node)
{
return FSSH_B_OK;
}
fssh_status_t
fssh_notify_stat_changed(fssh_mount_id device, fssh_vnode_id node,
uint32_t statFields)
{
return FSSH_B_OK;
}
fssh_status_t
fssh_notify_attribute_changed(fssh_mount_id device, fssh_vnode_id node,
const char *attribute, int32_t cause)
{
return FSSH_B_OK;
}
fssh_status_t
fssh_notify_query_entry_created(fssh_port_id port, int32_t token,
fssh_mount_id device, fssh_vnode_id directory, const char *name,
fssh_vnode_id node)
{
return FSSH_B_OK;
}
fssh_status_t
fssh_notify_query_entry_removed(fssh_port_id port, int32_t token,
fssh_mount_id device, fssh_vnode_id directory, const char *name,
fssh_vnode_id node)
{
return FSSH_B_OK;
}
+113
View File
@@ -0,0 +1,113 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <BeOSBuildCompatibility.h>
#include <OS.h>
#include "fssh_errors.h"
#include "fssh_os.h"
static void
copy_sem_info(fssh_sem_info* info, const sem_info* systemInfo)
{
info->sem = systemInfo->sem;
info->team = systemInfo->team;
strcpy(info->name, systemInfo->name);
info->count = systemInfo->count;
info->latest_holder = systemInfo->latest_holder;
}
// #pragma mark -
fssh_sem_id
fssh_create_sem(int32_t count, const char *name)
{
return create_sem(count, name);
}
fssh_status_t
fssh_delete_sem(fssh_sem_id id)
{
return delete_sem(id);
}
fssh_status_t
fssh_acquire_sem(fssh_sem_id id)
{
return acquire_sem(id);
}
fssh_status_t
fssh_acquire_sem_etc(fssh_sem_id id, int32_t count, uint32_t flags,
fssh_bigtime_t timeout)
{
return acquire_sem_etc(id, count, flags, timeout);
}
fssh_status_t
fssh_release_sem(fssh_sem_id id)
{
return release_sem(id);
}
fssh_status_t
fssh_release_sem_etc(fssh_sem_id id, int32_t count, uint32_t flags)
{
return release_sem_etc(id, count, flags);
}
fssh_status_t
fssh_get_sem_count(fssh_sem_id id, int32_t *threadCount)
{
return get_sem_count(id, (int32*)threadCount);
}
fssh_status_t
fssh_set_sem_owner(fssh_sem_id id, fssh_team_id team)
{
return set_sem_owner(id, team);
}
fssh_status_t
_fssh_get_sem_info(fssh_sem_id id, struct fssh_sem_info *info,
fssh_size_t infoSize)
{
sem_info systemInfo;
status_t result = get_sem_info(id, &systemInfo);
if (result != B_OK)
return result;
copy_sem_info(info, &systemInfo);
return FSSH_B_OK;
}
fssh_status_t
_fssh_get_next_sem_info(fssh_team_id team, int32_t *cookie,
struct fssh_sem_info *info, fssh_size_t infoSize)
{
sem_info systemInfo;
status_t result = get_next_sem_info(team, (int32*)cookie, &systemInfo);
if (result != B_OK)
return result;
copy_sem_info(info, &systemInfo);
return FSSH_B_OK;
}
+162
View File
@@ -0,0 +1,162 @@
#include "fssh_os.h"
#include <new>
#include "fssh_errors.h"
#include "fssh_kernel_export.h"
#include "fssh_string.h"
static const int sSemaphoreCount = 1024;
static fssh_sem_info* sSemaphores[sSemaphoreCount];
fssh_sem_id
fssh_create_sem(int32_t count, const char *name)
{
// find a free slot
for (int i = 0; i < sSemaphoreCount; i++) {
if (!sSemaphores[i]) {
sSemaphores[i] = new fssh_sem_info;
sSemaphores[i]->sem = i;
sSemaphores[i]->team = 1;
fssh_strcpy(sSemaphores[i]->name, name);
sSemaphores[i]->count = count;
sSemaphores[i]->latest_holder = -1;
return i;
}
}
return FSSH_B_NO_MORE_SEMS;
}
fssh_status_t
fssh_delete_sem(fssh_sem_id id)
{
if (id < 0 || id >= sSemaphoreCount || !sSemaphores[id])
return FSSH_B_BAD_SEM_ID;
delete sSemaphores[id];
sSemaphores[id] = NULL;
return 0;
}
fssh_status_t
fssh_acquire_sem(fssh_sem_id id)
{
return fssh_acquire_sem_etc(id, 1, 0, 0);
}
fssh_status_t
fssh_acquire_sem_etc(fssh_sem_id id, int32_t count, uint32_t flags,
fssh_bigtime_t timeout)
{
if (id < 0 || id >= sSemaphoreCount || !sSemaphores[id])
return FSSH_B_BAD_SEM_ID;
if (count < 0)
return FSSH_B_BAD_VALUE;
if (sSemaphores[id]->count >= count) {
sSemaphores[id]->count -= count;
return FSSH_B_OK;
}
// can't acquire the sem with that count at the moment
if (!flags & (FSSH_B_RELATIVE_TIMEOUT | FSSH_B_ABSOLUTE_TIMEOUT)) {
fssh_panic("blocking on semaphore %d without timeout!\n", (int)id);
return FSSH_B_BAD_VALUE;
}
// simulate timeout
if (flags & FSSH_B_RELATIVE_TIMEOUT) {
if (timeout == 0)
return FSSH_B_WOULD_BLOCK;
fssh_snooze(timeout);
} else
fssh_snooze_until(timeout, FSSH_B_SYSTEM_TIMEBASE);
return FSSH_B_TIMED_OUT;
}
fssh_status_t
fssh_release_sem(fssh_sem_id id)
{
return fssh_release_sem_etc(id, 1, 0);
}
fssh_status_t
fssh_release_sem_etc(fssh_sem_id id, int32_t count, uint32_t flags)
{
if (id < 0 || id >= sSemaphoreCount || !sSemaphores[id])
return FSSH_B_BAD_SEM_ID;
if (count < 0)
return FSSH_B_BAD_VALUE;
sSemaphores[id]->count += count;
return FSSH_B_OK;
}
fssh_status_t
fssh_get_sem_count(fssh_sem_id id, int32_t *threadCount)
{
if (id < 0 || id >= sSemaphoreCount || !sSemaphores[id])
return FSSH_B_BAD_SEM_ID;
if (!threadCount)
return FSSH_B_BAD_VALUE;
*threadCount = sSemaphores[id]->count;
return FSSH_B_OK;
}
fssh_status_t
fssh_set_sem_owner(fssh_sem_id id, fssh_team_id team)
{
if (id < 0 || id >= sSemaphoreCount || !sSemaphores[id])
return FSSH_B_BAD_SEM_ID;
if (team != 1)
return FSSH_B_BAD_VALUE;
sSemaphores[id]->team = team;
return FSSH_B_OK;
}
fssh_status_t
_fssh_get_sem_info(fssh_sem_id id, struct fssh_sem_info *info,
fssh_size_t infoSize)
{
if (id < 0 || id >= sSemaphoreCount || !sSemaphores[id])
return FSSH_B_BAD_SEM_ID;
if (!info)
return FSSH_B_BAD_VALUE;
fssh_memcpy(info, sSemaphores[id], sizeof(fssh_sem_info));
return FSSH_B_OK;
}
fssh_status_t
_fssh_get_next_sem_info(fssh_team_id team, int32_t *cookie,
struct fssh_sem_info *info, fssh_size_t infoSize)
{
if (team != 0 || team != 1)
return FSSH_B_BAD_TEAM_ID;
for (int i = *cookie; i < sSemaphoreCount; i++) {
if (sSemaphores[i]) {
*cookie = i + 1;
return _fssh_get_sem_info(i, info, infoSize);
}
}
return FSSH_B_ENTRY_NOT_FOUND;
}
+54
View File
@@ -0,0 +1,54 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <BeOSBuildCompatibility.h>
#include "fssh_stat.h"
#include <sys/stat.h>
#include "stat_util.h"
using FSShell::from_platform_stat;
int
fssh_stat(const char *path, struct fssh_stat *fsshStat)
{
struct stat st;
if (stat(path, &st) < 0)
return -1;
from_platform_stat(&st, fsshStat);
return 0;
}
int
fssh_fstat(int fd, struct fssh_stat *fsshStat)
{
struct stat st;
if (fstat(fd, &st) < 0)
return -1;
from_platform_stat(&st, fsshStat);
return 0;
}
int
fssh_lstat(const char *path, struct fssh_stat *fsshStat)
{
struct stat st;
if (lstat(path, &st) < 0)
return -1;
from_platform_stat(&st, fsshStat);
return 0;
}
+227
View File
@@ -0,0 +1,227 @@
/*
* Copyright 2005-2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <BeOSBuildCompatibility.h>
#include "stat_util.h"
#include <fcntl.h>
#include <sys/stat.h>
#include "fssh_fcntl.h"
#include "fssh_stat.h"
namespace FSShell {
// Haiku only mode_t flags
#ifndef HAIKU_HOST_PLATFORM_HAIKU
# define S_LINK_SELF_HEALING 0
# define S_LINK_AUTO_DELETE 0
#endif
fssh_mode_t
from_platform_mode(mode_t mode)
{
#define SET_ST_MODE_BIT(flag, fsshFlag) \
if (mode & flag) \
fsshMode |= fsshFlag;
fssh_mode_t fsshMode = 0;
// BeOS/Haiku only
#ifdef __BEOS__
SET_ST_MODE_BIT(FSSH_S_ATTR_DIR, S_ATTR_DIR);
SET_ST_MODE_BIT(FSSH_S_ATTR, S_ATTR);
SET_ST_MODE_BIT(FSSH_S_INDEX_DIR, S_INDEX_DIR);
SET_ST_MODE_BIT(FSSH_S_INT_INDEX, S_INT_INDEX);
SET_ST_MODE_BIT(FSSH_S_UINT_INDEX, S_UINT_INDEX);
SET_ST_MODE_BIT(FSSH_S_LONG_LONG_INDEX, S_LONG_LONG_INDEX);
SET_ST_MODE_BIT(FSSH_S_ULONG_LONG_INDEX, S_ULONG_LONG_INDEX);
SET_ST_MODE_BIT(FSSH_S_FLOAT_INDEX, S_FLOAT_INDEX);
SET_ST_MODE_BIT(FSSH_S_DOUBLE_INDEX, S_DOUBLE_INDEX);
SET_ST_MODE_BIT(FSSH_S_ALLOW_DUPS, S_ALLOW_DUPS);
SET_ST_MODE_BIT(FSSH_S_LINK_SELF_HEALING, S_LINK_SELF_HEALING);
SET_ST_MODE_BIT(FSSH_S_LINK_AUTO_DELETE, S_LINK_AUTO_DELETE);
#endif
switch (mode & S_IFMT) {
case S_IFLNK:
fsshMode |= FSSH_S_IFLNK;
break;
case S_IFREG:
fsshMode |= FSSH_S_IFREG;
break;
case S_IFBLK:
fsshMode |= FSSH_S_IFBLK;
break;
case S_IFDIR:
fsshMode |= FSSH_S_IFDIR;
break;
case S_IFIFO:
fsshMode |= FSSH_S_IFIFO;
break;
}
SET_ST_MODE_BIT(FSSH_S_ISUID, S_ISUID);
SET_ST_MODE_BIT(FSSH_S_ISGID, S_ISGID);
SET_ST_MODE_BIT(FSSH_S_ISVTX, S_ISVTX);
SET_ST_MODE_BIT(FSSH_S_IRUSR, S_IRUSR);
SET_ST_MODE_BIT(FSSH_S_IWUSR, S_IWUSR);
SET_ST_MODE_BIT(FSSH_S_IXUSR, S_IXUSR);
SET_ST_MODE_BIT(FSSH_S_IRGRP, S_IRGRP);
SET_ST_MODE_BIT(FSSH_S_IWGRP, S_IWGRP);
SET_ST_MODE_BIT(FSSH_S_IXGRP, S_IXGRP);
SET_ST_MODE_BIT(FSSH_S_IROTH, S_IROTH);
SET_ST_MODE_BIT(FSSH_S_IWOTH, S_IWOTH);
SET_ST_MODE_BIT(FSSH_S_IXOTH, S_IXOTH);
#undef SET_ST_MODE_BIT
return fsshMode;
}
mode_t
to_platform_mode(fssh_mode_t fsshMode)
{
#define SET_ST_MODE_BIT(flag, fsshFlag) \
if (fsshMode & fsshFlag) \
mode |= flag;
mode_t mode = 0;
// BeOS/Haiku only
#ifdef __BEOS__
SET_ST_MODE_BIT(FSSH_S_ATTR_DIR, S_ATTR_DIR);
SET_ST_MODE_BIT(FSSH_S_ATTR, S_ATTR);
SET_ST_MODE_BIT(FSSH_S_INDEX_DIR, S_INDEX_DIR);
SET_ST_MODE_BIT(FSSH_S_INT_INDEX, S_INT_INDEX);
SET_ST_MODE_BIT(FSSH_S_UINT_INDEX, S_UINT_INDEX);
SET_ST_MODE_BIT(FSSH_S_LONG_LONG_INDEX, S_LONG_LONG_INDEX);
SET_ST_MODE_BIT(FSSH_S_ULONG_LONG_INDEX, S_ULONG_LONG_INDEX);
SET_ST_MODE_BIT(FSSH_S_FLOAT_INDEX, S_FLOAT_INDEX);
SET_ST_MODE_BIT(FSSH_S_DOUBLE_INDEX, S_DOUBLE_INDEX);
SET_ST_MODE_BIT(FSSH_S_ALLOW_DUPS, S_ALLOW_DUPS);
SET_ST_MODE_BIT(FSSH_S_LINK_SELF_HEALING, S_LINK_SELF_HEALING);
SET_ST_MODE_BIT(FSSH_S_LINK_AUTO_DELETE, S_LINK_AUTO_DELETE);
#endif
switch (fsshMode & FSSH_S_IFMT) {
case FSSH_S_IFLNK:
mode |= S_IFLNK;
break;
case FSSH_S_IFREG:
mode |= S_IFREG;
break;
case FSSH_S_IFBLK:
mode |= S_IFBLK;
break;
case FSSH_S_IFDIR:
mode |= S_IFDIR;
break;
case FSSH_S_IFIFO:
mode |= S_IFIFO;
break;
}
SET_ST_MODE_BIT(FSSH_S_ISUID, S_ISUID);
SET_ST_MODE_BIT(FSSH_S_ISGID, S_ISGID);
SET_ST_MODE_BIT(FSSH_S_ISVTX, S_ISVTX);
SET_ST_MODE_BIT(FSSH_S_IRUSR, S_IRUSR);
SET_ST_MODE_BIT(FSSH_S_IWUSR, S_IWUSR);
SET_ST_MODE_BIT(FSSH_S_IXUSR, S_IXUSR);
SET_ST_MODE_BIT(FSSH_S_IRGRP, S_IRGRP);
SET_ST_MODE_BIT(FSSH_S_IWGRP, S_IWGRP);
SET_ST_MODE_BIT(FSSH_S_IXGRP, S_IXGRP);
SET_ST_MODE_BIT(FSSH_S_IROTH, S_IROTH);
SET_ST_MODE_BIT(FSSH_S_IWOTH, S_IWOTH);
SET_ST_MODE_BIT(FSSH_S_IXOTH, S_IXOTH);
#undef SET_ST_MODE_BIT
return mode;
}
void
from_platform_stat(const struct stat *st, struct fssh_stat *fsshStat)
{
fsshStat->fssh_st_dev = st->st_dev;
fsshStat->fssh_st_ino = st->st_ino;
fsshStat->fssh_st_mode = from_platform_mode(st->st_mode);
fsshStat->fssh_st_nlink = st->st_nlink;
fsshStat->fssh_st_uid = st->st_uid;
fsshStat->fssh_st_gid = st->st_gid;
fsshStat->fssh_st_size = st->st_size;
fsshStat->fssh_st_blksize = st->st_blksize;
fsshStat->fssh_st_atime = st->st_atime;
fsshStat->fssh_st_mtime = st->st_mtime;
fsshStat->fssh_st_ctime = st->st_ctime;
fsshStat->fssh_st_crtime = st->st_ctime;
fsshStat->fssh_st_type = 0;
}
void
to_platform_stat(const struct fssh_stat *fsshStat, struct stat *st)
{
st->st_dev = fsshStat->fssh_st_dev;
st->st_ino = fsshStat->fssh_st_ino;
st->st_mode = to_platform_mode(fsshStat->fssh_st_mode);
st->st_nlink = fsshStat->fssh_st_nlink;
st->st_uid = fsshStat->fssh_st_uid;
st->st_gid = fsshStat->fssh_st_gid;
st->st_size = fsshStat->fssh_st_size;
st->st_blksize = fsshStat->fssh_st_blksize;
st->st_atime = fsshStat->fssh_st_atime;
st->st_mtime = fsshStat->fssh_st_mtime;
st->st_ctime = fsshStat->fssh_st_ctime;
// st->st_crtime = fsshStat->fssh_st_crtime;
// st->st_type = fsshStat->fssh_st_type;
}
int
to_platform_open_mode(int fsshMode)
{
#define SET_OPEN_MODE_FLAG(flag, fsshFlag) \
if (fsshMode & fsshFlag) \
mode |= flag;
int mode = 0;
// the r/w mode
switch (fsshMode & FSSH_O_RWMASK) {
case FSSH_O_RDONLY:
mode |= O_RDONLY;
break;
case FSSH_O_WRONLY:
mode |= O_WRONLY;
break;
case FSSH_O_RDWR:
mode |= O_RDWR;
break;
}
// the flags
//SET_OPEN_MODE_FLAG(O_CLOEXEC, FSSH_O_CLOEXEC)
SET_OPEN_MODE_FLAG(O_NONBLOCK, FSSH_O_NONBLOCK)
SET_OPEN_MODE_FLAG(O_EXCL, FSSH_O_EXCL)
SET_OPEN_MODE_FLAG(O_CREAT, FSSH_O_CREAT)
SET_OPEN_MODE_FLAG(O_TRUNC, FSSH_O_TRUNC)
SET_OPEN_MODE_FLAG(O_APPEND, FSSH_O_APPEND)
SET_OPEN_MODE_FLAG(O_NOCTTY, FSSH_O_NOCTTY)
SET_OPEN_MODE_FLAG(O_NOTRAVERSE, FSSH_O_NOTRAVERSE)
//SET_OPEN_MODE_FLAG(O_TEXT, FSSH_O_TEXT)
//SET_OPEN_MODE_FLAG(O_BINARY, FSSH_O_BINARY)
#undef SET_OPEN_MODE_FLAG
return mode;
}
} // namespace FSShell
+26
View File
@@ -0,0 +1,26 @@
/*
* Copyright 2005-2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_STAT_UTIL_H
#define _FSSH_STAT_UTIL_H
#include <sys/stat.h>
#include "fssh_defs.h"
#include "fssh_stat.h"
namespace FSShell {
mode_t to_platform_mode(fssh_mode_t mode);
void from_platform_stat(const struct stat *st, struct fssh_stat *fsshStat);
void to_platform_stat(const struct my_stat *fsshStat, struct stat *st);
extern int to_platform_open_mode(int fsshMode);
} // namespace FSShell
#endif // _FSSH_STAT_UTIL_H
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "fssh_stdio.h"
#include <stdio.h>
#include <stdlib.h>
int
fssh_sprintf(char *string, char const *format, ...)
{
va_list args;
va_start(args, format);
int result = vsprintf(string, format, args);
va_end(args);
return result;
}
int
fssh_snprintf(char *string, fssh_size_t size, char const *format, ...)
{
va_list args;
va_start(args, format);
int result = vsnprintf(string, size, format, args);
va_end(args);
return result;
}
int
fssh_vsprintf(char *string, char const *format, va_list ap)
{
return vsprintf(string, format, ap);
}
int
fssh_vsnprintf(char *string, fssh_size_t size, char const *format, va_list ap)
{
return vsnprintf(string, size, format, ap);
}
+281
View File
@@ -0,0 +1,281 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <BeOSBuildCompatibility.h>
#include "fssh_string.h"
#include <string.h>
void*
fssh_memchr(const void *source, int value, fssh_size_t length)
{
return memchr(source, value, length);
}
int
fssh_memcmp(const void *buffer1, const void *buffer2, fssh_size_t length)
{
return memcmp(buffer1, buffer2, length);
}
void*
fssh_memcpy(void *dest, const void *source, fssh_size_t length)
{
return memcpy(dest, source, length);
}
void*
fssh_memccpy(void *dest, const void *source, int stopByte, fssh_size_t length)
{
return memccpy(dest, source, stopByte, length);
}
void*
fssh_memmove(void *dest, const void *source, fssh_size_t length)
{
return memmove(dest, source, length);
}
void*
fssh_memset(void *dest, int value, fssh_size_t length)
{
return memset(dest, value, length);
}
char*
fssh_strcpy(char *dest, const char *source)
{
return strcpy(dest, source);
}
char*
fssh_strncpy(char *dest, const char *source, fssh_size_t length)
{
return strncpy(dest, source, length);
}
char*
fssh_strcat(char *dest, const char *source)
{
return strcat(dest, source);
}
char*
fssh_strncat(char *dest, const char *source, fssh_size_t length)
{
return strncat(dest, source, length);
}
fssh_size_t
fssh_strlen(const char *string)
{
return strlen(string);
}
int
fssh_strcmp(const char *string1, const char *string2)
{
return strcmp(string1, string2);
}
int
fssh_strncmp(const char *string1, const char *string2, fssh_size_t length)
{
return strncmp(string1, string2, length);
}
char*
fssh_strchr(const char *string, int character)
{
return strchr(string, character);
}
char*
fssh_strrchr(const char *string, int character)
{
return strrchr(string, character);
}
char*
fssh_strstr(const char *string, const char *searchString)
{
return strstr(string, searchString);
}
#if 0
char*
fssh_strchrnul(const char *string, int character)
{
}
#endif // 0
char*
fssh_strpbrk(const char *string, const char *set)
{
return strpbrk(string, set);
}
char*
fssh_strtok(char *string, const char *set)
{
return strtok(string, set);
}
char*
fssh_strtok_r(char *string, const char *set, char **savePointer)
{
return strtok_r(string, set, savePointer);
}
fssh_size_t
fssh_strspn(const char *string, const char *set)
{
return strspn(string, set);
}
fssh_size_t
fssh_strcspn(const char *string, const char *set)
{
return strcspn(string, set);
}
int
fssh_strcoll(const char *string1, const char *string2)
{
return strcoll(string1, string2);
}
fssh_size_t
fssh_strxfrm(char *string1, const char *string2, fssh_size_t length)
{
return strxfrm(string1, string2, length);
}
char*
fssh_strerror(int errorCode)
{
return strerror(errorCode);
}
#if 0
int
fssh_strerror_r(int errorCode, char *buffer, fssh_size_t bufferSize)
{
return strerror_r(errorCode, buffer, bufferSize);
}
#endif // 0
int
fssh_strcasecmp(const char *string1, const char *string2)
{
return strcasecmp(string1, string2);
}
int
fssh_strncasecmp(const char *string1, const char *string2, fssh_size_t length)
{
return strncasecmp(string1, string2, length);
}
char*
fssh_strcasestr(const char *string, const char *searchString)
{
return strcasestr(string, searchString);
}
char*
fssh_strdup(const char *string)
{
return strdup(string);
}
char*
fssh_stpcpy(char *dest, const char *source)
{
return stpcpy(dest, source);
}
#if 0
const char *
fssh_strtcopy(char *dest, const char *source)
{
return strtcopy(dest, source);
}
#endif // 0
fssh_size_t
fssh_strlcat(char *dest, const char *source, fssh_size_t length)
{
return strlcat(dest, source, length);
}
fssh_size_t
fssh_strlcpy(char *dest, const char *source, fssh_size_t length)
{
return strlcpy(dest, source, length);
}
fssh_size_t
fssh_strnlen(const char *string, fssh_size_t count)
{
return strnlen(string, count);
}
int
fssh_ffs(int i)
{
return ffs(i);
}
char*
fssh_index(const char *s, int c)
{
return index(s, c);
}
char*
fssh_rindex(char const *s, int c)
{
return rindex(s, c);
}
+54
View File
@@ -0,0 +1,54 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <BeOSBuildCompatibility.h>
#include "fssh_os.h"
#include <OS.h>
#include "fssh_errors.h"
fssh_status_t
fssh_kill_thread(fssh_thread_id thread)
{
return kill_thread(thread);
}
fssh_status_t
fssh_resume_thread(fssh_thread_id thread)
{
return resume_thread(thread);
}
fssh_status_t
fssh_suspend_thread(fssh_thread_id thread)
{
return suspend_thread(thread);
}
fssh_thread_id
fssh_find_thread(const char *name)
{
return find_thread(name);
}
fssh_status_t
fssh_snooze(fssh_bigtime_t amount)
{
return snooze(amount);
}
fssh_status_t
fssh_snooze_until(fssh_bigtime_t time, int timeBase)
{
return snooze_until(time, timeBase);
}
+62
View File
@@ -0,0 +1,62 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <BeOSBuildCompatibility.h>
#include "fssh_os.h"
#include "fssh_time.h"
#include <time.h>
#include <OS.h>
// #pragma mark - OS.h
#if 0
uint32_t
fssh_real_time_clock(void)
{
}
void
fssh_set_real_time_clock(uint32_t secs_since_jan1_1970)
{
}
fssh_bigtime_t
fssh_real_time_clock_usecs(void)
{
}
fssh_status_t
fssh_set_timezone(char *timezone)
{
}
#endif // 0
fssh_bigtime_t
fssh_system_time(void)
{
return system_time();
}
// #pragma mark - time.h
fssh_time_t
fssh_time(fssh_time_t *timer)
{
time_t result = time(NULL);
if (timer)
*timer = result;
return result;
}
+80
View File
@@ -0,0 +1,80 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <BeOSBuildCompatibility.h>
#include "fssh_uio.h"
#include <new>
#include <errno.h>
#include <sys/uio.h>
static const fssh_size_t kMaxIOVecs = 1024;
bool
prepare_iovecs(const struct fssh_iovec *vecs, fssh_size_t count,
struct iovec* systemVecs)
{
if (count > kMaxIOVecs) {
errno = B_BAD_VALUE;
return false;
}
for (fssh_size_t i = 0; i < count; i++) {
systemVecs[i].iov_base = vecs[i].iov_base;
systemVecs[i].iov_len = vecs[i].iov_len;
}
return true;
}
fssh_ssize_t
fssh_readv(int fd, const struct fssh_iovec *vector, fssh_size_t count)
{
struct iovec systemVecs[kMaxIOVecs];
if (!prepare_iovecs(vector, count, systemVecs))
return -1;
return readv(fd, systemVecs, count);
}
fssh_ssize_t
fssh_readv_pos(int fd, fssh_off_t pos, const struct fssh_iovec *vec,
fssh_size_t count)
{
struct iovec systemVecs[kMaxIOVecs];
if (!prepare_iovecs(vec, count, systemVecs))
return -1;
return readv_pos(fd, pos, systemVecs, count);
}
fssh_ssize_t
fssh_writev(int fd, const struct fssh_iovec *vector, fssh_size_t count)
{
struct iovec systemVecs[kMaxIOVecs];
if (!prepare_iovecs(vector, count, systemVecs))
return -1;
return writev(fd, systemVecs, count);
}
fssh_ssize_t
fssh_writev_pos(int fd, fssh_off_t pos, const struct fssh_iovec *vec,
fssh_size_t count)
{
struct iovec systemVecs[kMaxIOVecs];
if (!prepare_iovecs(vec, count, systemVecs))
return -1;
return writev_pos(fd, pos, systemVecs, count);
}
+226
View File
@@ -0,0 +1,226 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <BeOSBuildCompatibility.h>
#include "fssh_unistd.h"
#include <errno.h>
#include <stdarg.h>
#include <unistd.h>
#include <SupportDefs.h>
#include "fssh_drivers.h"
#include "fssh_errno.h"
#ifdef __BEOS__
# include <Drivers.h>
#else
# include <stropts.h> // the correct place of definition for ioctl()
# if defined(HAIKU_HOST_PLATFORM_LINUX)
# include <linux/hdreg.h>
# endif
#endif
#ifdef HAIKU_HOST_PLATFORM_LINUX
static bool
test_size(int fd, off_t size)
{
char buffer[1];
if (size == 0)
return true;
if (lseek(fd, size - 1, SEEK_SET) < 0)
return false;
return (read(fd, &buffer, 1) == 1);
}
static off_t
get_partition_size(int fd, off_t maxSize)
{
// binary search
off_t lower = 0;
off_t upper = maxSize;
while (lower < upper) {
off_t mid = (lower + upper + 1) / 2;
if (test_size(fd, mid))
lower = mid;
else
upper = mid - 1;
}
return lower;
}
#endif // HAIKU_HOST_PLATFORM_LINUX
int
fssh_close(int fd)
{
return close(fd);
}
int
fssh_ioctl(int fd, unsigned long op, ...)
{
status_t error = B_BAD_VALUE;
va_list list;
// count arguments
va_start(list, op);
switch (op) {
case FSSH_B_GET_GEOMETRY:
{
fssh_device_geometry *geometry
= va_arg(list, fssh_device_geometry*);
#ifdef __BEOS__
if (ioctl(fd, B_GET_GEOMETRY, systemGeometry) == 0) {
geometry->bytes_per_sector
= systemGeometry->bytes_per_sector;
geometry->sectors_per_track
= systemGeometry->sectors_per_track;
geometry->cylinder_count = systemGeometry->cylinder_count;
geometry->head_count = systemGeometry->head_count;
geometry->device_type = systemGeometry->device_type;
geometry->removable = systemGeometry->removable;
geometry->read_only = systemGeometry->read_only;
geometry->write_once = systemGeometry->write_once;
error = B_OK;
} else
error = errno;
#elif defined(HAIKU_HOST_PLATFORM_LINUX)
struct hd_geometry hdGeometry;
// BLKGETSIZE and BLKGETSIZE64 don't seem to work for
// partitions. So we get the device geometry (there only seems
// to be HDIO_GETGEO, which is kind of obsolete, BTW), and
// get the partition size via binary search.
if (ioctl(fd, HDIO_GETGEO, &hdGeometry) == 0) {
off_t bytesPerCylinder = (off_t)hdGeometry.heads
* hdGeometry.sectors * 512;
off_t deviceSize = bytesPerCylinder * hdGeometry.cylinders;
off_t partitionSize = get_partition_size(fd, deviceSize);
geometry->head_count = hdGeometry.heads;
geometry->cylinder_count = partitionSize / bytesPerCylinder;
geometry->sectors_per_track = hdGeometry.sectors;
// TODO: Get the real values...
geometry->bytes_per_sector = 512;
geometry->device_type = FSSH_B_DISK;
geometry->removable = false;
geometry->read_only = false;
geometry->write_once = false;
error = B_OK;
} else
error = errno;
#else
// Not implemented for this platform, i.e. we won't be able to
// deal with block devices.
#endif
break;
}
case FSSH_B_FLUSH_DRIVE_CACHE:
{
#ifdef __BEOS__
if (ioctl(fd, B_FLUSH_DRIVE_CACHE) == 0)
error = B_OK;
else
error = errno;
#else
error = B_OK;
#endif
break;
}
case 10000: // IOCTL_FILE_UNCACHED_IO
{
#ifdef __BEOS__
if (ioctl(fd, 10000) == 0)
error = B_OK;
else
error = errno;
#else
error = B_OK;
#endif
break;
}
}
va_end(list);
if (error != B_OK) {
fssh_set_errno(error);
return -1;
}
return 0;
}
fssh_ssize_t
fssh_read_pos(int fd, fssh_off_t pos, void *buffer, fssh_size_t count)
{
return read_pos(fd, pos, buffer, count);
}
fssh_ssize_t
fssh_write_pos(int fd, fssh_off_t pos, const void *buffer, fssh_size_t count)
{
return write_pos(fd, pos, buffer, count);
}
fssh_gid_t
fssh_getegid(void)
{
return 0;
}
fssh_uid_t
fssh_geteuid(void)
{
return 0;
}
fssh_gid_t
fssh_getgid(void)
{
return 0;
}
#if 0
int
fssh_getgroups(int groupSize, fssh_gid_t groupList[])
{
}
#endif // 0
fssh_uid_t
fssh_getuid(void)
{
return 0;
}
File diff suppressed because it is too large Load Diff
+111
View File
@@ -0,0 +1,111 @@
/*
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#ifndef _FSSH_VFS_H
#define _FSSH_VFS_H
#include "fssh_fs_interface.h"
#include "list.h"
#include "lock.h"
namespace FSShell {
/* R5 figures, but we don't use a table for monitors anyway */
#define DEFAULT_FD_TABLE_SIZE 128
#define MAX_FD_TABLE_SIZE 8192
#define DEFAULT_NODE_MONITORS 4096
#define MAX_NODE_MONITORS 65536
struct kernel_args;
struct vm_cache_ref;
struct file_descriptor;
/** The I/O context of a process/team, holds the fd array among others */
typedef struct io_context {
struct vnode *cwd;
mutex io_mutex;
uint32_t table_size;
uint32_t num_used_fds;
struct file_descriptor **fds;
uint8_t *fds_close_on_exec;
} io_context;
struct fd_info {
int number;
int32_t open_mode;
fssh_dev_t device;
fssh_ino_t node;
};
/* macro to allocate a iovec array on the stack */
#define IOVECS(name, size) \
uint8_t _##name[sizeof(fssh_iovecs) + (size)*sizeof(fssh_iovec)]; \
fssh_iovecs *name = (fssh_iovecs *)_##name
fssh_status_t vfs_init(struct kernel_args *args);
fssh_status_t vfs_bootstrap_file_systems(void);
void vfs_mount_boot_file_system(struct kernel_args *args);
void vfs_exec_io_context(void *context);
void* vfs_new_io_context(void *parentContext);
fssh_status_t vfs_free_io_context(void *context);
/* calls needed by the VM for paging and by the file cache */
int vfs_get_vnode_from_fd(int fd, bool kernel, void **vnode);
fssh_status_t vfs_get_vnode_from_path(const char *path, bool kernel, void **vnode);
fssh_status_t vfs_get_vnode(fssh_mount_id mountID, fssh_vnode_id vnodeID,
void **_vnode);
fssh_status_t vfs_entry_ref_to_vnode(fssh_mount_id mountID,
fssh_vnode_id directoryID, const char *name, void **_vnode);
void vfs_vnode_to_node_ref(void *_vnode, fssh_mount_id *_mountID,
fssh_vnode_id *_vnodeID);
fssh_status_t vfs_lookup_vnode(fssh_mount_id mountID, fssh_vnode_id vnodeID,
void **_vnode);
void vfs_put_vnode(void *vnode);
void vfs_acquire_vnode(void *vnode);
fssh_status_t vfs_get_cookie_from_fd(int fd, void **_cookie);
fssh_status_t vfs_get_file_map(void *_vnode, fssh_off_t offset,
fssh_size_t size, fssh_file_io_vec *vecs,
fssh_size_t *_count);
fssh_status_t vfs_get_fs_node_from_path(fssh_mount_id mountID,
const char *path, bool kernel, void **_node);
fssh_status_t vfs_stat_vnode(void *_vnode, struct fssh_stat *stat);
fssh_status_t vfs_get_vnode_name(void *vnode, char *name,
fssh_size_t nameSize);
fssh_status_t vfs_get_cwd(fssh_mount_id *_mountID, fssh_vnode_id *_vnodeID);
void vfs_unlock_vnode_if_locked(struct file_descriptor *descriptor);
fssh_status_t vfs_disconnect_vnode(fssh_mount_id mountID,
fssh_vnode_id vnodeID);
void vfs_free_unused_vnodes(int32_t level);
/* special module convenience call */
fssh_status_t vfs_get_module_path(const char *basePath,
const char *moduleName, char *pathBuffer,
fssh_size_t bufferSize);
/* service call for whoever needs a normalized path */
fssh_status_t vfs_normalize_path(const char *path, char *buffer,
fssh_size_t bufferSize, bool kernel);
/* service call for the node monitor */
fssh_status_t resolve_mount_point_to_volume_root(fssh_mount_id mountID,
fssh_vnode_id nodeID, fssh_mount_id *resolvedMountID,
fssh_vnode_id *resolvedNodeID);
// cache initialization functions defined in the respective cache implementation
extern fssh_status_t block_cache_init();
extern fssh_status_t file_cache_init();
} // namespace FSShell
#endif /* _FSSH_VFS_H */