Kernel/IPStack - (minor) TODO retransmit timer
[tpg/acess2.git] / KernelLand / Kernel / drv / fifo.c
index 5d344e5..6d5d483 100644 (file)
 #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;
@@ -31,17 +32,20 @@ typedef struct sPipe {
  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,
@@ -71,7 +75,6 @@ tVFS_Node     gFIFO_AnonNode = {
        .NumACLs = 1,
        .ACLs = &gVFS_ACL_EveryoneRW,
        };
-tPipe  *gFIFO_NamedPipes = NULL;
 
 // === CODE ===
 /**
@@ -80,6 +83,7 @@ tPipe *gFIFO_NamedPipes = NULL;
  */
 int FIFO_Install(char **Options)
 {
+       MemFS_InitDir( &gFIFO_RootDir );
        DevFS_AddDevice( &gFIFO_DriverInfo );
        return MODULE_ERR_OK;
 }
@@ -98,22 +102,14 @@ int FIFO_IOCtl(tVFS_Node *Node, int Id, void *Data)
  */
 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);
 }
 
 /**
@@ -121,30 +117,26 @@ int FIFO_ReadDir(tVFS_Node *Node, int Id, char Dest[FILENAME_MAX])
  * \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;
 }
 
 /**
@@ -152,6 +144,25 @@ tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename)
  */
 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;
 }
 
@@ -168,58 +179,27 @@ void FIFO_Reference(tVFS_Node *Node)
  */
 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;
@@ -232,7 +212,7 @@ size_t FIFO_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
        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");
@@ -303,7 +283,7 @@ size_t FIFO_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
 /**
  * \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;
@@ -316,7 +296,7 @@ size_t FIFO_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buff
        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");
@@ -353,11 +333,14 @@ size_t FIFO_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buff
                if(len > pipe->BufSize - pipe->WritePos)
                {
                        int ofs = pipe->BufSize - pipe->WritePos;
+                       LOG("pipe->Buffer = %p, pipe->WritePos = %i, ofs=%i, len=%i",
+                               pipe->Buffer, pipe->WritePos, ofs, len);
                        memcpy(&pipe->Buffer[pipe->WritePos], Buffer, ofs);
-                       memcpy(&pipe->Buffer, (Uint8*)Buffer + ofs, len-ofs);
+                       memcpy(&pipe->Buffer[0], (Uint8*)Buffer + ofs, len-ofs);
                }
                else
                {
+                       LOG("pipe->Buffer = %p, pipe->WritePos = %i", pipe->Buffer, pipe->WritePos);
                        memcpy(&pipe->Buffer[pipe->WritePos], Buffer, len);
                }
                
@@ -382,7 +365,7 @@ size_t FIFO_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buff
        return Length;
 }
 
-// --- HELPERS ---
+// --- HeLPERS ---
 /**
  * \fn tPipe *FIFO_Int_NewPipe(int Size, const char *Name)
  * \brief Create a new pipe
@@ -406,10 +389,8 @@ tPipe *FIFO_Int_NewPipe(int Size, const char *Name)
        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;
@@ -419,10 +400,10 @@ tPipe *FIFO_Int_NewPipe(int Size, const char *Name)
        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();

UCC git Repository :: git.ucc.asn.au