#include <modules.h>
#include <fs_devfs.h>
#include <semaphore.h>
+#include <memfs_helpers.h>
// === CONSTANTS ===
#define DEFAULT_RING_SIZE 2048
#define PF_BLOCKING 1
// === TYPES ===
-typedef struct sPipe {
- struct sPipe *Next;
- char *Name;
+typedef struct sPipe
+{
+ tMemFS_FileHdr FileHdr;
tVFS_Node Node;
Uint Flags;
int ReadPos;
int FIFO_Install(char **Arguments);
int FIFO_IOCtl(tVFS_Node *Node, int Id, void *Data);
int FIFO_ReadDir(tVFS_Node *Node, int Id, char Dest[FILENAME_MAX]);
-tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename);
+tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename, Uint Flags);
tVFS_Node *FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
void FIFO_Reference(tVFS_Node *Node);
void FIFO_Close(tVFS_Node *Node);
int FIFO_Unlink(tVFS_Node *Node, const char *OldName);
-size_t FIFO_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
-size_t FIFO_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);
+size_t FIFO_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags);
+size_t FIFO_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags);
tPipe *FIFO_Int_NewPipe(int Size, const char *Name);
// === GLOBALS ===
MODULE_DEFINE(0, 0x0032, FIFO, FIFO_Install, NULL, NULL);
+tMemFS_DirHdr gFIFO_RootDir = {
+ .FileHdr = { .Name = "FIFO" },
+};
tVFS_NodeType gFIFO_DirNodeType = {
.TypeName = "FIFO Dir Node",
.ReadDir = FIFO_ReadDir,
.NumACLs = 1,
.ACLs = &gVFS_ACL_EveryoneRW,
};
-tPipe *gFIFO_NamedPipes = NULL;
// === CODE ===
/**
*/
int FIFO_Install(char **Options)
{
+ MemFS_InitDir( &gFIFO_RootDir );
DevFS_AddDevice( &gFIFO_DriverInfo );
return MODULE_ERR_OK;
}
*/
int FIFO_ReadDir(tVFS_Node *Node, int Id, char Dest[FILENAME_MAX])
{
- tPipe *tmp = gFIFO_NamedPipes;
-
// Entry 0 is Anon Pipes
- if(Id == 0) {
+ if(Id == 0)
+ {
strcpy(Dest, "anon");
return 0;
}
- // Find the id'th node
- while(--Id && tmp) tmp = tmp->Next;
- // If the list ended, error return
- if(!tmp)
- return -EINVAL;
- // Return good
- strncpy(Dest, tmp->Name, FILENAME_MAX);
- return 0;
+ return MemFS_ReadDir(&gFIFO_RootDir, Id-1, Dest);
}
/**
* \brief Find a file in the FIFO root
* \note Creates an anon pipe if anon is requested
*/
-tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename)
+tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename, Uint Flags)
{
- tPipe *tmp;
- if(!Filename) return NULL;
-
- // NULL String Check
- if(Filename[0] == '\0') return NULL;
+ ASSERTR(Filename, NULL);
+ ASSERTR(Filename[0], NULL);
// Anon Pipe
if( strcmp(Filename, "anon") == 0 )
{
- tmp = FIFO_Int_NewPipe(DEFAULT_RING_SIZE, "anon");
- return &tmp->Node;
+ if( Flags & VFS_FDIRFLAG_STAT ) {
+ //return &gFIFI_TemplateAnonNode;
+ }
+ tPipe *ret = FIFO_Int_NewPipe(DEFAULT_RING_SIZE, "anon");
+ return &ret->Node;
}
// Check Named List
- tmp = gFIFO_NamedPipes;
- while(tmp)
- {
- if(strcmp(tmp->Name, Filename) == 0)
- return &tmp->Node;
- tmp = tmp->Next;
- }
- return NULL;
+ tPipe *ret = (tPipe*)MemFS_FindDir(&gFIFO_RootDir, Filename);
+ if(!ret)
+ return NULL;
+ return &ret->Node;
}
/**
*/
tVFS_Node *FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
{
+ UNIMPLEMENTED();
+ return NULL;
+}
+
+/**
+ * \brief Delete a pipe
+ */
+int FIFO_Unlink(tVFS_Node *Node, const char *OldName)
+{
+ if(Node != &gFIFO_DriverInfo.RootNode) return 0;
+
+ // Can't relink anon
+ if(strcmp(OldName, "anon")) return 0;
+
+ // Find node
+ tPipe* pipe = (tPipe*)MemFS_Remove(&gFIFO_RootDir, OldName);
+ if(!pipe) return 0;
+
+ free(pipe);
return 0;
}
*/
void FIFO_Close(tVFS_Node *Node)
{
- tPipe *pipe;
if(!Node->ImplPtr) return ;
Node->ReferenceCount --;
if(Node->ReferenceCount) return ;
- pipe = Node->ImplPtr;
+ tPipe *pipe = Node->ImplPtr;
- if(strcmp(pipe->Name, "anon") == 0) {
- Log_Debug("FIFO", "Pipe %p closed", Node->ImplPtr);
- free(Node->ImplPtr);
+ if(strcmp(pipe->FileHdr.Name, "anon") == 0)
+ {
+ Log_Debug("FIFO", "Pipe %p closed", pipe);
+ free(pipe);
return ;
}
return ;
}
-/**
- * \brief Delete a pipe
- */
-int FIFO_Unlink(tVFS_Node *Node, const char *OldName)
-{
- tPipe *pipe;
-
- if(Node != &gFIFO_DriverInfo.RootNode) return 0;
-
- // Can't relink anon
- if(strcmp(OldName, "anon")) return 0;
-
- // Find node
- for(pipe = gFIFO_NamedPipes;
- pipe;
- pipe = pipe->Next)
- {
- if(strcmp(pipe->Name, OldName) == 0)
- break;
- }
- if(!pipe) return 0;
-
- // Unlink the pipe
- if(Node->ImplPtr) {
- free(Node->ImplPtr);
- return 1;
- }
-
- return 0;
-}
-
/**
* \brief Read from a fifo pipe
*/
-size_t FIFO_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
+size_t FIFO_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags)
{
tPipe *pipe = Node->ImplPtr;
Uint len;
while(remaining)
{
// Wait for buffer to fill
- if(pipe->Flags & PF_BLOCKING)
+ if( (pipe->Flags & PF_BLOCKING) && !(Flags & VFS_IOFLAG_NOBLOCK) )
{
if( pipe->ReadPos == pipe->WritePos )
VFS_SelectNode(Node, VFS_SELECT_READ, NULL, "FIFO_Read");
/**
* \brief Write to a fifo pipe
*/
-size_t FIFO_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)
+size_t FIFO_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags)
{
tPipe *pipe = Node->ImplPtr;
Uint len;
while(remaining)
{
// Wait for buffer to empty
- if(pipe->Flags & PF_BLOCKING)
+ if( (pipe->Flags & PF_BLOCKING) && !(Flags & VFS_IOFLAG_NOBLOCK) )
{
if( pipe->ReadPos == (pipe->WritePos+1)%pipe->BufSize ) {
LOG("Blocking write on FIFO");
return Length;
}
-// --- HELPERS ---
+// --- HeLPERS ---
/**
* \fn tPipe *FIFO_Int_NewPipe(int Size, const char *Name)
* \brief Create a new pipe
ret->Buffer = (void*)( (Uint)ret + sizeof(tPipe) + sizeof(tVFS_ACL) );
// Set name (and FIFO name)
- ret->Name = ret->Buffer + Size;
- strcpy(ret->Name, Name);
- // - Start empty, max of `Size`
- //Semaphore_Init( &ret->Semaphore, 0, Size, "FIFO", ret->Name );
+ ret->FileHdr.Name = ret->Buffer + Size;
+ strcpy((char*)ret->FileHdr.Name, Name);
// Set Node
ret->Node.ReferenceCount = 1;
ret->Node.GID = Threads_GetGID();
ret->Node.NumACLs = 1;
ret->Node.ACLs = (void*)( (Uint)ret + sizeof(tPipe) );
- ret->Node.ACLs->Group = 0;
- ret->Node.ACLs->ID = ret->Node.UID;
- ret->Node.ACLs->Inv = 0;
- ret->Node.ACLs->Perms = -1;
+ ret->Node.ACLs->Ent.Group = 0;
+ ret->Node.ACLs->Ent.ID = ret->Node.UID;
+ ret->Node.ACLs->Perm.Inv = 0;
+ ret->Node.ACLs->Perm.Perms = -1;
ret->Node.CTime
= ret->Node.MTime
= ret->Node.ATime = now();