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:
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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_ */
|
||||
@@ -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_ */
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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
|
||||
;
|
||||
@@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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 */
|
||||
Reference in New Issue
Block a user