Kernel - VFS API Update - ReadDir caller provided buffer
authorJohn Hodge <[email protected]>
Tue, 21 Aug 2012 14:29:11 +0000 (22:29 +0800)
committerJohn Hodge <[email protected]>
Tue, 21 Aug 2012 14:29:11 +0000 (22:29 +0800)
35 files changed:
AcessNative/acesskernel_src/nativefs.c
KernelLand/Kernel/drv/fifo.c
KernelLand/Kernel/drv/pci.c
KernelLand/Kernel/drv/proc.c
KernelLand/Kernel/drv/vterm.c
KernelLand/Kernel/include/acess.h
KernelLand/Kernel/include/errno.h
KernelLand/Kernel/include/vfs.h
KernelLand/Kernel/include/vfs_ext.h
KernelLand/Kernel/libc.c
KernelLand/Kernel/vfs/dir.c
KernelLand/Kernel/vfs/fs/devfs.c
KernelLand/Kernel/vfs/fs/root.c
KernelLand/Kernel/vfs/open.c
KernelLand/Modules/Filesystems/Ext2/dir.c
KernelLand/Modules/Filesystems/Ext2/ext2_common.h
KernelLand/Modules/Filesystems/FAT/common.h
KernelLand/Modules/Filesystems/FAT/dir.c
KernelLand/Modules/Filesystems/InitRD/initrd.h
KernelLand/Modules/Filesystems/InitRD/main.c
KernelLand/Modules/Filesystems/NTFS/common.h
KernelLand/Modules/Filesystems/NTFS/dir.c
KernelLand/Modules/Filesystems/NTFS/main.c
KernelLand/Modules/Filesystems/RAMDisk/ramdisk.c
KernelLand/Modules/IPStack/adapters.c
KernelLand/Modules/IPStack/init.h [new file with mode: 0644]
KernelLand/Modules/IPStack/interface.c
KernelLand/Modules/IPStack/interface.h [new file with mode: 0644]
KernelLand/Modules/IPStack/main.c
KernelLand/Modules/IPStack/routing.c
KernelLand/Modules/IPStack/tcp.c
KernelLand/Modules/Input/Mouse/main.c
KernelLand/Modules/Storage/FDDv2/main.c
KernelLand/Modules/Storage/LVM/main.c
KernelLand/Modules/USB/Core/main.c

index 7c20b69..0e791b8 100644 (file)
@@ -31,7 +31,7 @@ typedef struct
 tVFS_Node      *NativeFS_Mount(const char *Device, const char **Arguments);\r
 void   NativeFS_Unmount(tVFS_Node *Node);\r
 tVFS_Node      *NativeFS_FindDir(tVFS_Node *Node, const char *Name);\r
-char   *NativeFS_ReadDir(tVFS_Node *Node, int Position);\r
+ int   NativeFS_ReadDir(tVFS_Node *Node, int Position, char Dest[FILENAME_MAX]);\r
 size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void *Buffer);\r
 size_t NativeFS_Write(tVFS_Node *Node, _acess_off_t Offset, size_t Length, const void *Buffer);\r
 void   NativeFS_Close(tVFS_Node *Node);\r
@@ -168,11 +168,10 @@ tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name)
        return Inode_CacheNode(info->InodeHandle, &baseRet);\r
 }\r
 \r
-char *NativeFS_ReadDir(tVFS_Node *Node, int Position)\r
+int NativeFS_ReadDir(tVFS_Node *Node, int Position, char Dest[FILENAME_MAX])\r
 {\r
        struct dirent   *ent;\r
        DIR     *dp = (void*)(tVAddr)Node->Inode;\r
-       char    *ret;\r
 \r
        ENTER("pNode iPosition", Node, Position);\r
 \r
@@ -184,16 +183,16 @@ char *NativeFS_ReadDir(tVFS_Node *Node, int Position)
        } while(Position-- && ent);\r
 \r
        if( !ent ) {\r
-               LEAVE('n');\r
-               return NULL;\r
+               LEAVE('i', -ENOENT);\r
+               return -ENOENT;\r
        }\r
        \r
-       ret = strdup(ent->d_name);\r
+       strncpy(Dest, ent->d_name, FILENAME_MAX);\r
 \r
        // TODO: Unlock node    \r
 \r
-       LEAVE('s', ret);\r
-       return ret;\r
+       LEAVE('i', 0);\r
+       return 0;\r
 }\r
 \r
 size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void *Buffer)\r
index cb62193..2adaec7 100644 (file)
@@ -26,9 +26,9 @@ typedef struct sPipe {
 // === PROTOTYPES ===
  int   FIFO_Install(char **Arguments);
  int   FIFO_IOCtl(tVFS_Node *Node, int Id, void *Data);
-char   *FIFO_ReadDir(tVFS_Node *Node, int Id);
+ int   FIFO_ReadDir(tVFS_Node *Node, int Id, char Dest[FILENAME_MAX]);
 tVFS_Node      *FIFO_FindDir(tVFS_Node *Node, const char *Filename);
- int   FIFO_MkNod(tVFS_Node *Node, const char *Name, 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);
@@ -92,19 +92,24 @@ int FIFO_IOCtl(tVFS_Node *Node, int Id, void *Data)
  * \fn char *FIFO_ReadDir(tVFS_Node *Node, int Id)
  * \brief Reads from the FIFO root
  */
-char *FIFO_ReadDir(tVFS_Node *Node, int Id)
+int FIFO_ReadDir(tVFS_Node *Node, int Id, char Dest[FILENAME_MAX])
 {
        tPipe   *tmp = gFIFO_NamedPipes;
        
        // Entry 0 is Anon Pipes
-       if(Id == 0)     return strdup("anon");
+       if(Id == 0) {
+               strcpy(Dest, "anon");
+               return 0;
+       }
        
        // Find the id'th node
        while(--Id && tmp)      tmp = tmp->Next;
-       // If node found, return it
-       if(tmp) return strdup(tmp->Name);
-       // else error return
-       return NULL;
+       // If the list ended, error return
+       if(!tmp)
+               return -EINVAL;
+       // Return good
+       strncpy(Dest, tmp->Name, FILENAME_MAX);
+       return 0;
 }
 
 /**
@@ -142,7 +147,7 @@ tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename)
 /**
  * \fn int FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
  */
-int FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
+tVFS_Node *FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
 {
        return 0;
 }
index f09389b..702c9cc 100644 (file)
@@ -33,7 +33,7 @@ typedef struct sPCIDevice
  int   PCI_Install(char **Arguments);\r
  int   PCI_ScanBus(int ID, int bFill);\r
  \r
-char   *PCI_int_ReadDirRoot(tVFS_Node *node, int pos);\r
+ int   PCI_int_ReadDirRoot(tVFS_Node *node, int pos, char Dest[FILENAME_MAX]);\r
 tVFS_Node      *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename);\r
 Uint32 PCI_int_GetBusAddr(Uint16 Bus, Uint16 Slot, Uint16 Fcn, Uint8 Offset);\r
 size_t PCI_int_ReadDevice(tVFS_Node *node, off_t Offset, size_t Length, void *buffer);\r
@@ -197,16 +197,16 @@ int PCI_ScanBus(int BusID, int bFill)
 /**\r
  * \brief Read from Root of PCI Driver\r
 */\r
-char *PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos)\r
+int PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])\r
 {\r
        ENTER("pNode iPos", Node, Pos);\r
        if(Pos < 0 || Pos >= giPCI_DeviceCount) {\r
-               LEAVE('n');\r
-               return NULL;\r
+               LEAVE_RET('i', -EINVAL);\r
        }\r
        \r
-       LEAVE('s', gPCI_Devices[Pos].Name);\r
-       return strdup( gPCI_Devices[Pos].Name );\r
+       LOG("Name = %s", gPCI_Devices[Pos].Name);\r
+       strncpy(Dest, gPCI_Devices[Pos].Name, FILENAME_MAX);\r
+       LEAVE_RET('i', 0);\r
 }\r
 /**\r
  */\r
index e8cab19..1e0c6bd 100644 (file)
@@ -31,7 +31,7 @@ typedef struct sSysFS_Ent
  int   SysFS_RemoveFile(int ID);
 #endif
 
-char   *SysFS_Comm_ReadDir(tVFS_Node *Node, int Id);
+ int   SysFS_Comm_ReadDir(tVFS_Node *Node, int Id, char Dest[FILENAME_MAX]);
 tVFS_Node      *SysFS_Comm_FindDir(tVFS_Node *Node, const char *Filename);
 size_t SysFS_Comm_ReadFile(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
 void   SysFS_Comm_CloseFile(tVFS_Node *Node);
@@ -324,16 +324,20 @@ int SysFS_RemoveFile(int ID)
  * \fn char *SysFS_Comm_ReadDir(tVFS_Node *Node, int Pos)
  * \brief Reads from a SysFS directory
  */
-char *SysFS_Comm_ReadDir(tVFS_Node *Node, int Pos)
+int SysFS_Comm_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tSysFS_Ent      *child = (tSysFS_Ent*)Node->ImplPtr;
-       if(Pos < 0 || (Uint64)Pos >= Node->Size)        return NULL;
+       if(Pos < 0 || (Uint64)Pos >= Node->Size)
+               return -EINVAL;
        
        for( ; child; child = child->Next, Pos-- )
        {
-               if( Pos == 0 )  return strdup(child->Name);
+               if( Pos == 0 ) {
+                       strncpy(Dest, child->Name, FILENAME_MAX);
+                       return 0;
+               }
        }
-       return NULL;
+       return -ENOENT;
 }
 
 /**
index 63db01e..fc6dea2 100644 (file)
@@ -34,7 +34,7 @@ extern void   Debug_SetKTerminal(const char *File);
 
 // === PROTOTYPES ===
  int   VT_Install(char **Arguments);
-char   *VT_ReadDir(tVFS_Node *Node, int Pos);
+ int   VT_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *VT_FindDir(tVFS_Node *Node, const char *Name);
  int   VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data);
 size_t VT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
@@ -268,11 +268,12 @@ void VT_SetResolution(int Width, int Height)
  * \fn char *VT_ReadDir(tVFS_Node *Node, int Pos)
  * \brief Read from the VTerm Directory
  */
-char *VT_ReadDir(tVFS_Node *Node, int Pos)
+int VT_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
-       if(Pos < 0)     return NULL;
-       if(Pos >= NUM_VTS)      return NULL;
-       return strdup( gVT_Terminals[Pos].Name );
+       if(Pos < 0)     return -EINVAL;
+       if(Pos >= NUM_VTS)      return -EINVAL;
+       strncpy(Dest, gVT_Terminals[Pos].Name, FILENAME_MAX);
+       return 0;
 }
 
 /**
index 51ae771..1d062a5 100644 (file)
@@ -426,6 +426,7 @@ extern int  strucmp(const char *Str1, const char *Str2);
 extern char    *_strdup(const char *File, int Line, const char *Str);
 extern char    **str_split(const char *__str, char __ch);
 extern char    *strchr(const char *__s, int __c);
+extern char    *strrchr(const char *__s, int __c);
 extern int     strpos(const char *Str, char Ch);
 extern int     strpos8(const char *str, Uint32 search);
 extern void    itoa(char *buf, Uint64 num, int base, int minLength, char pad);
index 7c2e97a..a327cc0 100644 (file)
@@ -21,6 +21,7 @@ enum eErrorNums
        EEXIST, // Already exists
        ENFILE, // Too many open files
        ENOTDIR,        // Not a directory
+       EIO,    // IO Error
        
        EALREADY,       // Operation was a NOP
        EINTERNAL,      // Internal Error
index 98bc027..59824e2 100644 (file)
@@ -295,22 +295,19 @@ struct sVFS_NodeType
         * \brief Read from a directory
         * \param Node  Pointer to this node
         * \param Pos   Offset in the directory
-        * \return Pointer to the name of the item on the heap (will be freed
-        *         by the caller). If the directory end has been reached, NULL
-        *         will be returned.
-        *         If an item is required to be skipped either &::NULLNode,
-        *         ::VFS_SKIP or ::VFS_SKIPN(0...1023) will be returned.
+        * \param Dest  Destination for filename
+        * \return Zero on success, negative on error or +ve for ignore entry
         */
-       char    *(*ReadDir)(struct sVFS_Node *Node, int Pos);
+        int    (*ReadDir)(struct sVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
        
        /**
         * \brief Create a node in a directory
         * \param Node  Pointer to this node
         * \param Name  Name of the new child
         * \param Flags Flags to apply to the new child (directory or symlink)
-        * \return Zero on Success, non-zero on error (see errno.h)
+        * \return Created node or NULL on error
         */
-        int    (*MkNod)(struct sVFS_Node *Node, const char *Name, Uint Flags);
+       tVFS_Node       *(*MkNod)(struct sVFS_Node *Node, const char *Name, Uint Flags);
        
        /**
         * \brief Relink (Rename/Remove) a file/directory
index d9bc833..44c70f8 100644 (file)
@@ -13,6 +13,7 @@ typedef Uint64        tInode;
 typedef Uint32 tMount;
 
 // === CONSTANTS ===
+#define FILENAME_MAX   256
 //! Maximum size of a Memory Path generated by VFS_GetMemPath
 #define        VFS_MEMPATH_SIZE        (3 + (BITS/4)*2)
 /**
@@ -368,10 +369,10 @@ extern int        VFS_Symlink(const char *Name, const char *Link);
 /**
  * \brief Read from a directory
  * \param FD   File handle returned by ::VFS_Open
- * \param Dest Destination array for the file name (max 255 bytes)
+ * \param Dest Destination array for the file name (max FILENAME_MAX bytes)
  * \return Boolean Success
  */
-extern int     VFS_ReadDir(int FD, char *Dest);
+extern int     VFS_ReadDir(int FD, char Dest[FILENAME_MAX]);
 /**
  * \brief Wait for an aciton on a file descriptor
  * \param MaxHandle    Maximum set handle in \a *Handles
index 08ebc62..ef94426 100644 (file)
@@ -49,6 +49,7 @@ EXPORT(tolower);
 
 EXPORT(strucmp);
 EXPORT(strchr);
+EXPORT(strrchr);
 EXPORT(strpos);
 EXPORT(strlen);
 EXPORT(strcpy);
@@ -529,6 +530,15 @@ char *strchr(const char *__s, int __c)
        return NULL;
 }
 
+char *strrchr(const char *__s, int __c)
+{
+       size_t ofs = strlen(__s);
+       while(--ofs && __s[ofs] != __c);
+       if( __s[ofs] == __c )
+               return (char*)__s + ofs;
+       return NULL;
+}
+
 /**
  * \fn int strpos(const char *Str, char Ch)
  * \brief Search a string for an ascii character
index 65218af..fab9d56 100644 (file)
@@ -41,7 +41,7 @@ int VFS_MkNod(const char *Path, Uint Flags)
         int    pos = 0, oldpos = 0;
         int    next = 0;
        tVFS_Node       *parent;
-        int    ret;
+       tVFS_Node       *ret;
        
        ENTER("sPath xFlags", Path, Flags);
        
@@ -92,6 +92,7 @@ int VFS_MkNod(const char *Path, Uint Flags)
        
        // Create node
        ret = parent->Type->MkNod(parent, name, Flags);
+       _CloseNode(ret);
        
        // Free allocated string
        free(absPath);
@@ -101,8 +102,8 @@ int VFS_MkNod(const char *Path, Uint Flags)
        _CloseNode(parent);
 
        // Return whatever the driver said      
-       LEAVE('i', ret);
-       return ret;
+       LEAVE('i', ret==NULL);
+       return ret==NULL;
 }
 
 /**
@@ -154,7 +155,7 @@ int VFS_Symlink(const char *Name, const char *Link)
 int VFS_ReadDir(int FD, char *Dest)
 {
        tVFS_Handle     *h = VFS_GetHandle(FD);
-       char    *tmp;
+        int    rv;
        
        //ENTER("ph pDest", h, Dest);
        
@@ -169,23 +170,18 @@ int VFS_ReadDir(int FD, char *Dest)
        }
        
        do {
-               tmp = h->Node->Type->ReadDir(h->Node, h->Position);
-               if((Uint)tmp < (Uint)VFS_MAXSKIP)
-                       h->Position += (Uint)tmp;
+               rv = h->Node->Type->ReadDir(h->Node, h->Position, Dest);
+               if(rv > 0)
+                       h->Position += rv;
                else
                        h->Position ++;
-       } while(tmp != NULL && (Uint)tmp < (Uint)VFS_MAXSKIP);
+       } while(rv > 0);
        
-       //LOG("tmp = '%s'", tmp);
-       
-       if(!tmp) {
+       if(rv < 0) {
                //LEAVE('i', 0);
                return 0;
        }
        
-       strcpy(Dest, tmp);
-       free(tmp);
-       
        //LEAVE('i', 1);
        return 1;
 }
index 9ab2b7b..9389822 100644 (file)
@@ -15,7 +15,7 @@ void  DevFS_DelDevice(tDevFS_Driver *Device);
 #endif
 tVFS_Node      *DevFS_InitDevice(const char *Device, const char **Options);
 void   DevFS_Unmount(tVFS_Node *RootNode);
-char   *DevFS_ReadDir(tVFS_Node *Node, int Pos);
+ int   DevFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *DevFS_FindDir(tVFS_Node *Node, const char *Name);
 
 // === GLOBALS ===
@@ -128,21 +128,24 @@ void DevFS_Unmount(tVFS_Node *RootNode)
 /**
  * \fn char *DevFS_ReadDir(tVFS_Node *Node, int Pos)
  */
-char *DevFS_ReadDir(tVFS_Node *Node, int Pos)
+int DevFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tDevFS_Driver   *dev;
        
-       if(Pos < 0)     return NULL;
+       if(Pos < 0)     return -EINVAL;
        
        for(dev = gDevFS_Drivers;
                dev && Pos--;
                dev = dev->Next
                );
        
-       if(dev)
-               return strdup(dev->Name);
-       else
-               return NULL;
+       if(dev) {
+               strncpy(Dest, dev->Name, FILENAME_MAX);
+               return 0;
+       }
+       else {
+               return -ENOENT;
+       }
 }
 
 /**
index abe5945..5685861 100644 (file)
@@ -13,9 +13,9 @@
 
 // === PROTOTYPES ===
 tVFS_Node      *Root_InitDevice(const char *Device, const char **Options);
- int   Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node      *Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
 tVFS_Node      *Root_FindDir(tVFS_Node *Node, const char *Name);
-char   *Root_ReadDir(tVFS_Node *Node, int Pos);
+ int   Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 size_t Root_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
 size_t Root_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);
 tRamFS_File    *Root_int_AllocFile(void);
@@ -82,7 +82,7 @@ tVFS_Node *Root_InitDevice(const char *Device, const char **Options)
  * \fn int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
  * \brief Create an entry in the root directory
  */
-int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
+tVFS_Node *Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
 {
        tRamFS_File     *parent = Node->ImplPtr;
        tRamFS_File     *child;
@@ -91,16 +91,18 @@ int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
        ENTER("pNode sName xFlags", Node, Name, Flags);
        
        LOG("Sanity check name length - %i > %i", strlen(Name)+1, sizeof(child->Name));
-       if(strlen(Name) + 1 > sizeof(child->Name))
-               LEAVE_RET('i', EINVAL);
+       if(strlen(Name) + 1 > sizeof(child->Name)) {
+               errno = EINVAL;
+               LEAVE_RET('n', NULL);
+       }
        
        // Find last child, while we're at it, check for duplication
        for( child = parent->Data.FirstChild; child; prev = child, child = child->Next )
        {
                if(strcmp(child->Name, Name) == 0) {
                        LOG("Duplicate");
-                       LEAVE('i', EEXIST);
-                       return EEXIST;
+                       errno = EEXIST;
+                       LEAVE_RET('n', NULL);
                }
        }
        
@@ -139,8 +141,8 @@ int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
        
        parent->Node.Size ++;
        
-       LEAVE('i', EOK);
-       return EOK;
+       LEAVE('n', &child->Node);
+       return &child->Node;
 }
 
 /**
@@ -172,16 +174,19 @@ tVFS_Node *Root_FindDir(tVFS_Node *Node, const char *Name)
  * \fn char *Root_ReadDir(tVFS_Node *Node, int Pos)
  * \brief Get an entry from the filesystem
  */
-char *Root_ReadDir(tVFS_Node *Node, int Pos)
+int Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tRamFS_File     *parent = Node->ImplPtr;
        tRamFS_File     *child = parent->Data.FirstChild;
        
        for( ; child && Pos--; child = child->Next ) ;
        
-       if(child)       return strdup(child->Name);
+       if(child) {
+               strncpy(Dest, child->Name, FILENAME_MAX);
+               return 0;
+       }
        
-       return NULL;
+       return -ENOENT;
 }
 
 /**
index 22d20e9..5ea67c1 100644 (file)
@@ -504,12 +504,44 @@ int VFS_OpenEx(const char *Path, Uint Flags, Uint Mode)
        if( !node && (Flags & VFS_OPENFLAG_CREATE) )
        {
                // TODO: Translate `Mode` into ACL and node flags
-               // Get parent, create node
-               if( VFS_MkNod(absPath, 0) ) {
+               Uint    new_flags = 0;
+               
+               // Split path at final separator
+               char *file = strrchr(absPath, '/');
+               *file = '\0';
+               file ++;
+
+               // Get parent node
+               tVFS_Mount      *pmnt;
+               tVFS_Node *pnode = VFS_ParsePath(absPath, NULL, &pmnt);
+               if(!pnode) {
+                       LOG("Unable to open parent '%s'", absPath);
+                       free(absPath);
+                       errno = ENOENT;
+                       LEAVE_RET('i', -1);
+               }
+
+               // TODO: Check ACLs on the parent
+               if( !VFS_CheckACL(pnode, VFS_PERM_EXECUTE|VFS_PERM_WRITE) ) {
+                       _CloseNode(pnode);
+                       pmnt->OpenHandleCount --;
                        free(absPath);
+                       LEAVE('i', -1);
                        return -1;
                }
-               node = VFS_ParsePath(absPath, NULL, &mnt);
+
+               // Check that there's a MkNod method
+               if( !pnode->Type || !pnode->Type->MkNod ) {
+                       Log_Warning("VFS", "VFS_Open - Directory has no MkNod method");
+                       errno = EINVAL;
+                       LEAVE_RET('i', -1);
+               }
+               
+               node = pnode->Type->MkNod(pnode, file, new_flags);
+               // Fall through on error check
+               
+               _CloseNode(pnode);
+               pmnt->OpenHandleCount --;
        }
        
        // Free generated path
index 7b78ae4..de0b30a 100644 (file)
@@ -5,7 +5,7 @@
  * dir.c
  * - Directory Handling
  */
-#define DEBUG  0
+#define DEBUG  1
 #define VERBOSE        0
 #include "ext2_common.h"
 
@@ -13,9 +13,9 @@
 #define BLOCK_DIR_OFS(_data, _block)   (((Uint16*)(_data))[(_block)])
 
 // === PROTOTYPES ===
-char   *Ext2_ReadDir(tVFS_Node *Node, int Pos);
+ int   Ext2_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *Ext2_FindDir(tVFS_Node *Node, const char *FileName);
- int   Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node      *Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
  int   Ext2_Unlink(tVFS_Node *Node, const char *OldName);
  int   Ext2_Link(tVFS_Node *Parent, const char *Name, tVFS_Node *Node);
 // --- Helpers ---
@@ -44,7 +44,7 @@ tVFS_NodeType gExt2_FileType = {
  * \param Node Directory node
  * \param Pos  Position of desired element
  */
-char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
+int Ext2_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tExt2_Inode     inode;
        tExt2_DirEnt    dirent;
@@ -92,8 +92,8 @@ char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
        
        // Check for the end of the list
        if(size <= 0 || size > inode.i_size) {
-               LEAVE('n');
-               return NULL;
+               LEAVE('i', -ENOENT);
+               return -ENOENT;
        }
        
        // Read Entry
@@ -103,20 +103,21 @@ char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
        dirent.name[ dirent.name_len ] = '\0';  // Cap off string
        
        if( dirent.name_len == 0 ) {
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;
+               LEAVE('i', 1);
+               return 1;
        }
        
        // Ignore . and .. (these are done in the VFS)
        if( (dirent.name[0] == '.' && dirent.name[1] == '\0')
        ||  (dirent.name[0] == '.' && dirent.name[1] == '.' && dirent.name[2]=='\0')) {
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;        // Skip
+               LEAVE('i', 1);
+               return 1;       // Skip
        }
        
-       LEAVE('s', dirent.name);
-       // Create new node
-       return strdup(dirent.name);
+       LOG("Name '%s'", dirent.name);
+       strncpy(Dest, dirent.name, FILENAME_MAX);
+       LEAVE('i', 0);
+       return 0;
 }
 
 /**
@@ -177,22 +178,20 @@ tVFS_Node *Ext2_FindDir(tVFS_Node *Node, const char *Filename)
  * \fn int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
  * \brief Create a new node
  */
-int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
+tVFS_Node *Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
 {
        ENTER("pParent sName xFlags", Parent, Name, Flags);
        
        Uint64 inodeNum = Ext2_int_AllocateInode(Parent->ImplPtr, Parent->Inode);
        if( inodeNum == 0 ) {
                LOG("Inode allocation failed");
-               LEAVE('i', -1);
-               return -1;
+               LEAVE_RET('n', NULL);
        }
        tVFS_Node *child = Ext2_int_CreateNode(Parent->ImplPtr, inodeNum);
        if( !child ) {
                Ext2_int_DereferenceInode(Parent->ImplPtr, inodeNum);
                Log_Warning("Ext2", "Ext2_MkNod - Node creation failed");
-               LEAVE('i', -1);
-               return -1;
+               LEAVE_RET('n', NULL);
        }
 
        child->Flags = Flags & (VFS_FFLAG_DIRECTORY|VFS_FFLAG_SYMLINK|VFS_FFLAG_READONLY);
@@ -206,9 +205,11 @@ int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
        // TODO: Set up ACLs
 
        int rv = Ext2_Link(Parent, Name, child);
-       child->Type->Close(child);
-       LEAVE('i', rv);
-       return rv;
+       if( rv ) {
+               Ext2_CloseFile(child);
+               return NULL;
+       }
+       LEAVE_RET('p', child);
 }
 
 /**
index 57b7493..5515429 100644 (file)
@@ -33,9 +33,9 @@ extern void   Ext2_int_DereferenceInode(tExt2_Disk *Disk, Uint32 Inode);
 extern int     Ext2_int_ReadInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode);
 extern int     Ext2_int_WriteInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode);
 // --- Dir ---
-extern char    *Ext2_ReadDir(tVFS_Node *Node, int Pos);
+extern int     Ext2_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 extern tVFS_Node       *Ext2_FindDir(tVFS_Node *Node, const char *FileName);
-extern int     Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+extern tVFS_Node       *Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
 extern int     Ext2_Link(tVFS_Node *Parent, const char *Name, tVFS_Node *Node);
 // --- Read ---
 extern size_t  Ext2_Read(tVFS_Node *node, off_t offset, size_t length, void *buffer);
index b473bf7..9402830 100644 (file)
@@ -106,13 +106,13 @@ extern void       FAT_int_ReadCluster(tFAT_VolInfo *Disk, Uint32 Cluster, int Length,
 extern void    FAT_int_WriteCluster(tFAT_VolInfo *Disk, Uint32 Cluster, const void *Buffer);
 
 // --- Directory Access ---
-extern char    *FAT_ReadDir(tVFS_Node *Node, int ID);
+extern int     FAT_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
 extern tVFS_Node       *FAT_FindDir(tVFS_Node *Node, const char *Name);
 extern tVFS_Node       *FAT_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode);
 extern int     FAT_int_GetEntryByCluster(tVFS_Node *DirNode, Uint32 Cluster, fat_filetable *Entry);
 #if SUPPORT_WRITE
 extern int     FAT_int_WriteDirEntry(tVFS_Node *Node, int ID, fat_filetable *Entry);
-extern int     FAT_Mknod(tVFS_Node *Node, const char *Name, Uint Flags);
+extern tVFS_Node       *FAT_Mknod(tVFS_Node *Node, const char *Name, Uint Flags);
 extern int     FAT_Link(tVFS_Node *DirNode, const char *NewName, tVFS_Node *Node);
 extern int     FAT_Unlink(tVFS_Node *DirNode, const char *OldName);
 #endif
index 8a690a1..b74b31f 100644 (file)
@@ -12,7 +12,7 @@
 
 // === PROTOTYPES ===
 void   FAT_int_ProperFilename(char *dest, const char *src);
-char   *FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName);
+ int   FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName, char *Dest);
  int   FAT_int_ConvertUTF16_to_UTF8(Uint8 *Dest, const Uint16 *Source);
  int   FAT_int_ConvertUTF8_to_UTF16(Uint16 *Dest, const Uint8 *Source);
 
@@ -26,11 +26,11 @@ char        *FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName);
 Uint16 *FAT_int_GetLFN(tVFS_Node *Node, int ID);
 void   FAT_int_DelLFN(tVFS_Node *Node, int ID);
 #endif
-char   *FAT_ReadDir(tVFS_Node *Node, int ID);
+ int   FAT_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
 tVFS_Node      *FAT_FindDir(tVFS_Node *Node, const char *Name);
 tVFS_Node      *FAT_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode);
 #if SUPPORT_WRITE
- int   FAT_Mknod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node      *FAT_Mknod(tVFS_Node *Node, const char *Name, Uint Flags);
  int   FAT_int_IsValid83Filename(const char *Name);
  int   FAT_Link(tVFS_Node *DirNode, const char *NewName, tVFS_Node *Node);
  int   FAT_Relink(tVFS_Node *node, const char *OldName, const char *NewName);
@@ -75,32 +75,26 @@ void FAT_int_ProperFilename(char *dest, const char *src)
  * \param LongFileName Long file name pointer
  * \return Filename as a heap string
  */
-char *FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName)
+int FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName, char *Dest)
 {
-       char    *ret;
        ENTER("pft sLongFileName", ft, LongFileName);
-       //Log_Debug("FAT", "FAT_int_CreateName(ft=%p, LongFileName=%p'%s')", ft, LongFileName);
        #if USE_LFN
        if(LongFileName && LongFileName[0] != 0)
        {
                 int    len = FAT_int_ConvertUTF16_to_UTF8(NULL, LongFileName);
-               ret = malloc( len + 1 );
-               FAT_int_ConvertUTF16_to_UTF8((Uint8*)ret, LongFileName);
+               if( len > FILENAME_MAX ) {
+                       return -1;
+               }
+               FAT_int_ConvertUTF16_to_UTF8((Uint8*)Dest, LongFileName);
        }
        else
        {
        #endif
-               ret = (char*) malloc(13);
-               if( !ret ) {
-                       Log_Warning("FAT", "FAT_int_CreateName: malloc(13) failed");
-                       return NULL;
-               }
-               FAT_int_ProperFilename(ret, ft->name);
+               FAT_int_ProperFilename(Dest, ft->name);
        #if USE_LFN
        }
        #endif
-       LEAVE('s', ret);
-       return ret;
+       return 0;
 }
 
 #if USE_LFN
@@ -537,11 +531,10 @@ void FAT_int_DelLFN(tVFS_Node *Node, int ID)
  * \param ID   Directory position
  * \return Filename as a heap string, NULL or VFS_SKIP
  */
-char *FAT_ReadDir(tVFS_Node *Node, int ID)
+int FAT_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
 {
        fat_filetable   fileinfo[16];   // sizeof(fat_filetable)=32, so 16 per sector
         int    a;
-       char    *ret;
        #if USE_LFN
        Uint16  *lfn = NULL;
        #endif
@@ -551,8 +544,8 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
        if(FAT_int_ReadDirSector(Node, ID/16, fileinfo))
        {
                LOG("End of chain, end of dir");
-               LEAVE('n');
-               return NULL;
+               LEAVE('i', -EIO);
+               return -EIO;
        }
        
        // Offset in sector
@@ -564,20 +557,14 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
        if( fileinfo[a].name[0] == '\0' ) {
                Node->Size = ID;
                LOG("End of list");
-               LEAVE('n');
-               return NULL;    // break
+               LEAVE('i', -ENOENT);
+               return -ENOENT; // break
        }
        
        // Check for empty entry
        if( (Uint8)fileinfo[a].name[0] == 0xE5 ) {
                LOG("Empty Entry");
-               #if 0   // Stop on empty entry?
-               LEAVE('n');
-               return NULL;    // Stop
-               #else
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;        // Skip
-               #endif
+               LEAVE_RET('i', 1);      // Skip
        }
        
        #if USE_LFN
@@ -595,31 +582,24 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
                a = FAT_int_ParseLFN(&fileinfo[a], lfn);
                if( a < 0 ) {
                        LOG("Invalid LFN, error");
-                       LEAVE('n');
-                       return NULL;
+                       LEAVE_RET('i', -EIO);
                }
 
-//             LOG("lfn = '%s'", lfn);
-               //Log_Debug("FAT", "lfn = '%s'", lfn);
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;
+               LEAVE_RET('i', 1);      // Skip
        }
        #endif
        
        // Check if it is a volume entry
        if(fileinfo[a].attrib & 0x08) {
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;
+               LEAVE_RET('i', 1);      // Skip
        }
        // Ignore .
        if(fileinfo[a].name[0] == '.' && fileinfo[a].name[1] == ' ') {
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;
+               LEAVE_RET('i', 1);      // Skip
        }
        // and ..
        if(fileinfo[a].name[0] == '.' && fileinfo[a].name[1] == '.' && fileinfo[a].name[2] == ' ') {
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;
+               LEAVE_RET('i', 1);      // Skip
        }
        
        LOG("name='%c%c%c%c%c%c%c%c.%c%c%c'",
@@ -630,13 +610,13 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
        #if USE_LFN
        lfn = FAT_int_GetLFN(Node, ID);
        //Log_Debug("FAT", "lfn = %p'%s'", lfn, lfn);
-       ret = FAT_int_CreateName(&fileinfo[a], lfn);
+       FAT_int_CreateName(&fileinfo[a], lfn, Dest);
        #else
-       ret = FAT_int_CreateName(&fileinfo[a], NULL);
+       FAT_int_CreateName(&fileinfo[a], NULL, Dest);
        #endif
        
-       LEAVE('s', ret);
-       return ret;
+       LEAVE('i', 0);
+       return 0;
 }
 
 /**
@@ -705,7 +685,7 @@ tVFS_Node *FAT_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode)
 /**
  * \brief Create a new node
  */
-int FAT_Mknod(tVFS_Node *DirNode, const char *Name, Uint Flags)
+tVFS_Node *FAT_Mknod(tVFS_Node *DirNode, const char *Name, Uint Flags)
 {
        tFAT_VolInfo    *disk = DirNode->ImplPtr;
         int    rv;
@@ -729,7 +709,8 @@ int FAT_Mknod(tVFS_Node *DirNode, const char *Name, Uint Flags)
        
        tVFS_Node *newnode = FAT_int_CreateNode(DirNode, &ft);
        if( !newnode ) {
-               return -1;
+               errno = -EINTERNAL;
+               return NULL;
        }
        LOG("newnode = %p", newnode);
 
@@ -737,9 +718,8 @@ int FAT_Mknod(tVFS_Node *DirNode, const char *Name, Uint Flags)
        if( (rv = FAT_Link(DirNode, Name, newnode)) ) {
                newnode->ImplInt |= FAT_FLAG_DELETE;
        }
-       FAT_CloseFile(newnode);
-       LEAVE('i', rv);
-       return rv;
+       LEAVE('p', newnode);
+       return newnode;
 }
 
 /**
index 92af114..1848613 100644 (file)
@@ -14,9 +14,9 @@ typedef struct sInitRD_File
 
 
 // === Functions ===
-extern size_t  InitRD_ReadFile(tVFS_Node *Node, off_t Offset, size_t Size, void *Buffer);
-extern char    *InitRD_ReadDir(tVFS_Node *Node, int ID);
-extern tVFS_Node       *InitRD_FindDir(tVFS_Node *Node, const char *Name);
+//extern size_t        InitRD_ReadFile(tVFS_Node *Node, off_t Offset, size_t Size, void *Buffer);
+//extern int   InitRD_ReadDir(tVFS_Node *Node, int ID);
+//extern tVFS_Node     *InitRD_FindDir(tVFS_Node *Node, const char *Name);
 
 // === Globals ===
 tVFS_NodeType  gInitRD_DirType;
index 863a24a..96f783e 100644 (file)
@@ -18,7 +18,7 @@ tVFS_Node     *InitRD_InitDevice(const char *Device, const char **Arguments);
 void   InitRD_Unmount(tVFS_Node *Node);
 tVFS_Node      *InitRD_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode);
 size_t InitRD_ReadFile(tVFS_Node *Node, off_t Offset, size_t Size, void *Buffer);
-char   *InitRD_ReadDir(tVFS_Node *Node, int ID);
+ int   InitRD_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
 tVFS_Node      *InitRD_FindDir(tVFS_Node *Node, const char *Name);
 void   InitRD_DumpDir(tVFS_Node *Node, int Indent);
 
@@ -92,14 +92,15 @@ size_t InitRD_ReadFile(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffe
 /**
  * \brief Read from a directory
  */
-char *InitRD_ReadDir(tVFS_Node *Node, int ID)
+int InitRD_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
 {
        tInitRD_File    *dir = Node->ImplPtr;
        
        if(ID >= Node->Size)
-               return NULL;
+               return -EINVAL;
        
-       return strdup(dir[ID].Name);
+       strncpy(Dest, dir[ID].Name, FILENAME_MAX);
+       return 0;
 }
 
 /**
index 598120d..312bee7 100644 (file)
@@ -150,4 +150,7 @@ typedef struct sNTFS_FILE_Attrib
        };
 } PACKED       tNTFS_FILE_Attrib;
 
+extern int     NTFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
+extern tVFS_Node       *NTFS_FindDir(tVFS_Node *Node, const char *Name);
+
 #endif
index 37661e8..11cd241 100644 (file)
@@ -10,7 +10,7 @@
 #include "index.h"
 
 // === PROTOTYPES ===
-char   *NTFS_ReadDir(tVFS_Node *Node, int Pos);
+ int   NTFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *NTFS_FindDir(tVFS_Node *Node, const char *Name);
 Uint64 NTFS_int_IndexLookup(Uint64 Inode, const char *IndexName, const char *Str);
 
@@ -18,9 +18,9 @@ Uint64        NTFS_int_IndexLookup(Uint64 Inode, const char *IndexName, const char *Str
 /**
  * \brief Get the name of an indexed directory entry
  */
-char *NTFS_ReadDir(tVFS_Node *Node, int Pos)
+int NTFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
-       return NULL;
+       return -ENOTIMPL;
 }
 
 /**
index 87f2a09..b9c4b8d 100644 (file)
 #include "common.h"
 #include <modules.h>
 
-// === IMPORTS ===
-extern char    *NTFS_ReadDir(tVFS_Node *Node, int Pos);
-extern tVFS_Node       *NTFS_FindDir(tVFS_Node *Node, const char *Name);
-
 // === PROTOTYPES ===
  int   NTFS_Install(char **Arguments);
 tVFS_Node      *NTFS_InitDevice(const char *Devices, const char **Options);
index defa50b..eeef8f6 100644 (file)
@@ -21,9 +21,9 @@
 tVFS_Node      *RAMFS_InitDevice(const char *Device, const char **Options);
 void   RAMFS_Unmount(tVFS_Node *Node);
 // --- Directories ---
-char   *RAMFS_ReadDir(tVFS_Node *Node, int Index);
+ int   RAMFS_ReadDir(tVFS_Node *Node, int Index, char Dest[256]);
 tVFS_Node      *RAMFS_FindDir(tVFS_Node *Node, const char *Name);
- int   RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node      *RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
  int   RAMFS_Link(tVFS_Node *DirNode, const char *Name, tVFS_Node *Node);
  int   RAMFS_Unlink(tVFS_Node *Node, const char *Name);
 // --- Files ---
@@ -136,18 +136,19 @@ void RAMFS_Unmount(tVFS_Node *Node)
 }
 
 // --- Directories ---
-char *RAMFS_ReadDir(tVFS_Node *Node, int Index)
+int RAMFS_ReadDir(tVFS_Node *Node, int Index, char Dest[FILENAME_MAX])
 {
        tRAMFS_Dir      *dir = Node->ImplPtr;
        for( tRAMFS_DirEnt *d = dir->FirstEnt; d; d = d->Next )
        {
                if( Index -- == 0 ) {
                        LOG("Return %s", d->Name);
-                       return strdup(d->Name);
+                       strncpy(Dest, d->Name, FILENAME_MAX);
+                       return 0;
                }
        }
-       LOG("Return NULL");
-       return NULL;
+       LOG("Return -ENOENT");
+       return -ENOENT;
 }
 
 tVFS_Node *RAMFS_FindDir(tVFS_Node *Node, const char *Name)
@@ -166,11 +167,11 @@ tVFS_Node *RAMFS_FindDir(tVFS_Node *Node, const char *Name)
        return NULL;
 }
 
-int RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
+tVFS_Node *RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
 {
        tRAMFS_Dir      *dir = Node->ImplPtr;
        if( RAMFS_FindDir(Node, Name) != NULL )
-               return -1;
+               return NULL;
        
        tRAMFS_DirEnt   *de = malloc( sizeof(tRAMFS_DirEnt) + strlen(Name) + 1 );
        de->Next = NULL;
@@ -200,7 +201,7 @@ int RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
                dir->FirstEnt = de;
        dir->LastEnt = de;
 
-       return 0;
+       return &de->Inode->Node;
 }
 
 int RAMFS_Link(tVFS_Node *DirNode, const char *Name, tVFS_Node *FileNode)
index 16e0f97..2a02fd2 100644 (file)
@@ -20,7 +20,7 @@
 void   *IPStack_Adapter_Add(const tIPStack_AdapterType *Type, void *Ptr, const void *HWAddr);
 void   IPStack_Adapter_Del(void *Handle);
 // --- VFS API ---
-char   *Adapter_ReadDir(tVFS_Node *Node, int Pos);
+ int   Adapter_ReadDir(tVFS_Node *Node, int Pos, char Name[FILENAME_MAX]);
 tVFS_Node      *Adapter_FindDir(tVFS_Node *Node, const char *Name);
  int   Adapter_DirIOCtl(tVFS_Node *Node, int Num, void *Data);
  int   Adapter_IOCtl(tVFS_Node *Node, int Num, void *Data);
@@ -130,13 +130,14 @@ void IPStack_Adapter_Del(void *Handle)
 }
 
 // --- VFS API ---
-char *Adapter_ReadDir(tVFS_Node *Node, int Pos)
+int Adapter_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
-       if( Pos < 0 )   return NULL;
+       if( Pos < 0 )   return -EINVAL;
 
        // Loopback
        if( Pos == 0 ) {
-               return strdup("lo");
+               strcpy(Dest, "lo");
+               return 0;
        }
        Pos --;
        
@@ -144,7 +145,8 @@ char *Adapter_ReadDir(tVFS_Node *Node, int Pos)
                tAdapter *a;  int i;\
                for(i=0,a=list; i < Pos && a; i ++, a = a->Next ); \
                if( a ) { \
-                       return Adapter_GetName(a);\
+                       strncpy(Dest, Adapter_GetName(a), FILENAME_MAX);\
+                       return 0;\
                } \
                Pos -= i; \
        } while(0);
@@ -152,7 +154,7 @@ char *Adapter_ReadDir(tVFS_Node *Node, int Pos)
        CHECK_LIST(gpIP_AdapterList, "eth");
        // TODO: Support other types of adapters (wifi, tap, ...)
 
-       return NULL;
+       return -EINVAL;
 }
 
 tVFS_Node *Adapter_FindDir(tVFS_Node *Node, const char *Name)
diff --git a/KernelLand/Modules/IPStack/init.h b/KernelLand/Modules/IPStack/init.h
new file mode 100644 (file)
index 0000000..1f14bf1
--- /dev/null
@@ -0,0 +1,12 @@
+
+#ifndef _IPSTACK__INIT_H_
+#define _IPSTACK__INIT_H_
+
+extern int     ARP_Initialise();
+extern void    UDP_Initialise();
+extern void    TCP_Initialise();
+extern int     IPv4_Initialise();
+extern int     IPv6_Initialise();
+
+#endif
+
index 9bd00d9..9ab4b9a 100644 (file)
@@ -8,6 +8,7 @@
 #include "link.h"
 #include <api_drv_common.h>
 #include "include/adapters.h"
+#include "interface.h"
 
 // === CONSTANTS ===
 //! Default timeout value, 5 seconds
@@ -20,18 +21,23 @@ extern tVFS_Node    gIP_RouteNode;
 extern tVFS_Node       gIP_AdaptersNode;
 
 // === PROTOTYPES ===
-char   *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos);
+ int   IPStack_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name);
  int   IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data);
 
  int   IPStack_AddFile(tSocketFile *File);
 tInterface     *IPStack_AddInterface(const char *Device, const char *Name);
 
-char   *IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos);
+ int   IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *IPStack_Iface_FindDir(tVFS_Node *Node, const char *Name);
  int   IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data);
 
 // === GLOBALS ===
+tVFS_NodeType  gIP_RootNodeType = {
+       .ReadDir = IPStack_Root_ReadDir,
+       .FindDir = IPStack_Root_FindDir,
+       .IOCtl = IPStack_Root_IOCtl
+};
 tVFS_NodeType  gIP_InterfaceNodeType = {
                .ReadDir = IPStack_Iface_ReadDir,
                .FindDir = IPStack_Iface_FindDir,
@@ -62,27 +68,26 @@ tSocketFile *gIP_FileTemplates;
 /**
  * \brief Read from the IP Stack's Device Directory
  */
-char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos)
+int IPStack_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tInterface      *iface;
-       char    *name;
        ENTER("pNode iPos", Node, Pos);
        
 
        // Routing Subdir
        if( Pos == 0 ) {
-               LEAVE('s', "routes");
-               return strdup("routes");
+               strcpy(Dest, "routes");
+               return 0;
        }
        // Adapters
        if( Pos == 1 ) {
-               LEAVE('s', "adapters");
-               return strdup("adapters");
+               strcpy(Dest, "adapters");
+               return 0;
        }
        // Pseudo Interfaces
        if( Pos == 2 ) {
-               LEAVE('s', "lo");
-               return strdup("lo");
+               strcpy(Dest, "lo");
+               return 0;
        }
        Pos -= 3;
        
@@ -91,38 +96,16 @@ char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos)
        
        // Did we run off the end?
        if(!iface) {
-               LEAVE('n');
-               return NULL;
-       }
-       
-       name = malloc(4);
-       if(!name) {
-               Log_Warning("IPStack", "IPStack_Root_ReadDir - malloc error");
-               LEAVE('n');
-               return NULL;
+               LEAVE('i', -EINTERNAL);
+               return -EINVAL;
        }
        
        // Create the name
        Pos = iface->Node.ImplInt;
-       if(Pos < 10) {
-               name[0] = '0' + Pos;
-               name[1] = '\0';
-       }
-       else if(Pos < 100) {
-               name[0] = '0' + Pos/10;
-               name[1] = '0' + Pos%10;
-               name[2] = '\0';
-       }
-       else {
-               name[0] = '0' + Pos/100;
-               name[1] = '0' + (Pos/10)%10;
-               name[2] = '0' + Pos%10;
-               name[3] = '\0';
-       }
+       snprintf(Dest, FILENAME_MAX, "%i", Pos);
        
-       LEAVE('s', name);
-       // Return the pre-generated name
-       return name;
+       LEAVE('i', 0);
+       return 0;
 }
 
 /**
@@ -296,16 +279,18 @@ int IPStack_AddFile(tSocketFile *File)
 /**
  * \brief Read from an interface's directory
  */
-char *IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos)
+int IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tSocketFile     *file = gIP_FileTemplates;
        while(Pos-- && file) {
                file = file->Next;
        }
        
-       if(!file)       return NULL;
+       if(!file)
+               return -EINVAL;
        
-       return strdup(file->Name);
+       strncpy(Dest, file->Name, FILENAME_MAX);
+       return 0;
 }
 
 /**
diff --git a/KernelLand/Modules/IPStack/interface.h b/KernelLand/Modules/IPStack/interface.h
new file mode 100644 (file)
index 0000000..60459a0
--- /dev/null
@@ -0,0 +1,10 @@
+
+#ifndef _IPSTACK__INTERFACE_H_
+#define _IPSTACK__INTERFACE_H_
+
+extern tInterface      gIP_LoopInterface;
+extern tVFS_NodeType   gIP_RootNodeType;
+extern tInterface      *IPStack_AddInterface(const char *Device, const char *Name);
+
+#endif
+
index 5763e2d..bc920f1 100644 (file)
@@ -9,19 +9,10 @@
 #include <modules.h>
 #include <fs_devfs.h>
 #include "include/adapters.h"
+#include "interface.h"
+#include "init.h"
 
 // === IMPORTS ===
-extern int     ARP_Initialise();
-extern void    UDP_Initialise();
-extern void    TCP_Initialise();
-extern int     IPv4_Initialise();
-extern int     IPv6_Initialise();
-
-extern char    *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos);
-extern tVFS_Node       *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name);
-extern int     IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data);
-extern tInterface      gIP_LoopInterface;
-extern tInterface      *IPStack_AddInterface(const char *Device, const char *Name);
 extern tRoute  *IPStack_AddRoute(const char *Interface, void *Network, int SubnetBits, void *NextHop, int Metric);
 
 // === PROTOTYPES ===
@@ -30,11 +21,6 @@ extern tRoute        *IPStack_AddRoute(const char *Interface, void *Network, int Subnet
 
 // === GLOBALS ===
 MODULE_DEFINE(0, VERSION, IPStack, IPStack_Install, NULL, NULL);
-tVFS_NodeType  gIP_RootNodeType = {
-       .ReadDir = IPStack_Root_ReadDir,
-       .FindDir = IPStack_Root_FindDir,
-       .IOCtl = IPStack_Root_IOCtl
-};
 tDevFS_Driver  gIP_DriverInfo = {
        NULL, "ip",
        {
index 3153ef2..d9efa99 100644 (file)
@@ -17,9 +17,9 @@ extern tVFS_Node      *IPStack_Root_FindDir(tVFS_Node *Node, const char *Filename);
 
 // === PROTOTYPES ===
 // - Routes directory
-char   *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos);
+ int   IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name);
- int   IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node      *IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
  int   IPStack_RouteDir_Unlink(tVFS_Node *Node, const char *OldName);
 tRoute *_Route_FindExactRoute(int Type, void *Network, int Subnet, int Metric);
  int   _Route_ParseRouteName(const char *Name, void *Addr, int *SubnetBits, int *Metric);
@@ -58,22 +58,20 @@ tVFS_Node   gIP_RouteNode = {
 /**
  * \brief ReadDir for the /Devices/ip/routes/ directory
  */
-char *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos)
+int IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tRoute  *rt;
        
        for(rt = gIP_Routes; rt && Pos --; rt = rt->Next);
-       if( !rt )       return NULL;
+       if( !rt )       return -EINVAL;
        
        {
                 int    addrlen = IPStack_GetAddressSize(rt->AddressType);
-                int    len = sprintf(NULL, "%i::%i:%i", rt->AddressType, rt->SubnetBits, rt->Metric) + addrlen*2;
-               char    buf[len+1];
                 int    ofs;
-               ofs = sprintf(buf, "%i:", rt->AddressType);
-               ofs += Hex(buf+ofs, addrlen, rt->Network);
-               sprintf(buf+ofs, ":%i:%i", rt->SubnetBits, rt->Metric);
-               return strdup(buf);
+               ofs = sprintf(Dest, "%i:", rt->AddressType);
+               ofs += Hex(Dest+ofs, addrlen, rt->Network);
+               sprintf(Dest+ofs, ":%i:%i", rt->SubnetBits, rt->Metric);
+               return 0;
        }
 }
 
@@ -169,13 +167,22 @@ tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name)
 /**
  * \brief Create a new route node
  */
-int IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
+tVFS_Node *IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
 {
-       if( Flags )     return -EINVAL; 
-       if( Threads_GetUID() != 0 )     return -EACCES;
+       if( Flags ) {
+               errno = EINVAL;
+               return NULL;
+       }
+       if( Threads_GetUID() != 0 ) {
+               errno = EACCES;
+               return NULL;
+       }
 
         int    type = _Route_ParseRouteName(Name, NULL, NULL, NULL);
-       if( type <= 0 ) return -EINVAL;
+       if( type <= 0 ) {
+               errno = EINVAL;
+               return NULL;
+       }
 
         int    size = IPStack_GetAddressSize(type);
        Uint8   addrdata[size]; 
@@ -184,12 +191,15 @@ int IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
        _Route_ParseRouteName(Name, addrdata, &subnet, &metric);
 
        // Check for duplicates
-       if( _Route_FindExactRoute(type, addrdata, subnet, metric) )
-               return -EEXIST;
+       if( _Route_FindExactRoute(type, addrdata, subnet, metric) ) {
+               errno = EEXIST;
+               return NULL;
+       }
 
-       IPStack_Route_Create(type, addrdata, subnet, metric);
+       tRoute *rt = IPStack_Route_Create(type, addrdata, subnet, metric);
+       rt->Node.ReferenceCount ++;
 
-       return 0;
+       return &rt->Node;
 }
 
 /**
index c8a5584..71dd4e5 100644 (file)
@@ -33,7 +33,7 @@ Uint16        TCP_GetUnusedPort();
  int   TCP_DeallocatePort(Uint16 Port);
 // --- Server
 tVFS_Node      *TCP_Server_Init(tInterface *Interface);
-char   *TCP_Server_ReadDir(tVFS_Node *Node, int Pos);
+ int   TCP_Server_ReadDir(tVFS_Node *Node, int Pos, char Name[FILENAME_MAX]);
 tVFS_Node      *TCP_Server_FindDir(tVFS_Node *Node, const char *Name);
  int   TCP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data);
 void   TCP_Server_Close(tVFS_Node *Node);
@@ -878,11 +878,10 @@ tVFS_Node *TCP_Server_Init(tInterface *Interface)
  * \param Node Server node
  * \param Pos  Position (ignored)
  */
-char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos)
+int TCP_Server_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tTCPListener    *srv = Node->ImplPtr;
        tTCPConnection  *conn;
-       char    *ret;
        
        ENTER("pNode iPos", Node, Pos);
 
@@ -911,11 +910,10 @@ char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos)
        LOG("srv->NewConnections = %p", srv->NewConnections);
        LOG("srv->ConnectionsTail = %p", srv->ConnectionsTail);
 
-       ret = malloc(9);
-       itoa(ret, conn->Node.ImplInt, 16, 8, '0');
-       Log_Log("TCP", "Thread %i got '%s'", Threads_GetTID(), ret);
-       LEAVE('s', ret);
-       return ret;
+       itoa(Dest, conn->Node.ImplInt, 16, 8, '0');
+       Log_Log("TCP", "Thread %i got connection '%s'", Threads_GetTID(), Dest);
+       LEAVE('i', 0);
+       return 0;
 }
 
 /**
index 56bf9b5..25185a2 100644 (file)
@@ -17,7 +17,7 @@
  int   Mouse_Install(char **Arguments);
  int   Mouse_Cleanup(void);
 // - "User" side
-char   *Mouse_Root_ReadDir(tVFS_Node *Node, int Pos);
+ int   Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name);
  int   Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data);
 size_t Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Data);
@@ -68,10 +68,12 @@ int Mouse_Cleanup(void)
 }
 
 // --- VFS Interface ---
-char *Mouse_Root_ReadDir(tVFS_Node *Node, int Pos)
+int Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
-       if( Pos != 0 )  return NULL;
-       return strdup("system");
+       if( Pos != 0 )
+               return -EINVAL;
+       strcpy(Dest, "system");
+       return 0;
 }
 
 tVFS_Node *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name)
index c33dcda..f6290d9 100644 (file)
@@ -21,7 +21,7 @@
  int   FDD_Install(char **Arguments);
  int   FDD_RegisterFS(void);
 // --- VFS
-char   *FDD_ReadDir(tVFS_Node *Node, int pos);
+ int   FDD_ReadDir(tVFS_Node *Node, int pos, char dest[FILENAME_MAX]);
 tVFS_Node      *FDD_FindDir(tVFS_Node *dirNode, const char *Name);
  int   FDD_IOCtl(tVFS_Node *Node, int ID, void *Data);
 size_t FDD_ReadFS(tVFS_Node *node, off_t Offset, size_t Len, void *buffer);
@@ -111,17 +111,16 @@ int FDD_RegisterFS(void)
  * \param Pos  Position
  * \return Heap string of node name
  */
-char *FDD_ReadDir(tVFS_Node *Node, int Pos)
+int FDD_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
-       char    ret_tpl[2];
        if(Pos < 0 || Pos > MAX_DISKS )
-               return NULL;
+               return -ENOENT;
        if(gaFDD_Disks[Pos].bValid)
-               return VFS_SKIP;
+               return 1;
        
-       ret_tpl[0] = '0' + Pos;
-       ret_tpl[1] = '\0';
-       return strdup(ret_tpl);
+       Dest[0] = '0' + Pos;
+       Dest[1] = '\0';
+       return 0;
 }
 
 /**
index d4e9aa4..8793d68 100644 (file)
@@ -17,9 +17,9 @@
  int   LVM_Initialise(char **Arguments);
  int   LVM_Cleanup(void);
 // ---
-char   *LVM_Root_ReadDir(tVFS_Node *Node, int ID);
+ int   LVM_Root_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
 tVFS_Node      *LVM_Root_FindDir(tVFS_Node *Node, const char *Name);
-char   *LVM_Vol_ReadDir(tVFS_Node *Node, int ID);
+ int   LVM_Vol_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
 tVFS_Node      *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name);
 size_t LVM_Vol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
 size_t LVM_Vol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);
@@ -124,18 +124,20 @@ int LVM_Cleanup(void)
 // --------------------------------------------------------------------
 // VFS Inteface
 // --------------------------------------------------------------------
-char *LVM_Root_ReadDir(tVFS_Node *Node, int ID)
+int LVM_Root_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
 {
        tLVM_Vol        *vol;
        
-       if( ID < 0 )    return NULL;    
+       if( ID < 0 )    return -EINVAL;
 
        for( vol = gpLVM_FirstVolume; vol && ID --; vol = vol->Next );
        
-       if(vol)
-               return strdup(vol->Name);
+       if(vol) {
+               strncpy(Dest, vol->Name, FILENAME_MAX);
+               return 0;
+       }
        else
-               return NULL;
+               return -ENOENT;
 }
 tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name)
 {
@@ -151,17 +153,22 @@ tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name)
        return NULL;
 }
 
-char *LVM_Vol_ReadDir(tVFS_Node *Node, int ID)
+int LVM_Vol_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
 {
        tLVM_Vol        *vol = Node->ImplPtr;
+       const char *src;
        
        if( ID < 0 || ID >= vol->nSubVolumes+1 )
-               return NULL;
+               return -EINVAL;
 
-       if( ID == 0 )
-               return strdup("ROOT");
-       else
-               return strdup( vol->SubVolumes[ID-1]->Name );
+       if( ID == 0 ) {
+               src = "ROOT";
+       }
+       else {
+               src = vol->SubVolumes[ID-1]->Name;
+       }
+       strncpy(Dest, src, FILENAME_MAX);
+       return 0;
 }
 tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name)
 {
index 94ec253..cdbe2ee 100644 (file)
@@ -17,7 +17,7 @@ extern void   USB_AsyncThread(void *Unused);
 // === PROTOTYPES ===
  int   USB_Install(char **Arguments);
 void   USB_Cleanup(void);
-char   *USB_ReadDir(tVFS_Node *Node, int Pos);
+ int   USB_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *USB_FindDir(tVFS_Node *Node, const char *Name);
  int   USB_IOCtl(tVFS_Node *Node, int Id, void *Data);
 
@@ -60,9 +60,9 @@ void USB_Cleanup()
  * \fn char *USB_ReadDir(tVFS_Node *Node, int Pos)
  * \brief Read from the USB root
  */
-char *USB_ReadDir(tVFS_Node *Node, int Pos)
+int USB_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
-       return NULL;
+       return -ENOTIMPL;
 }
 
 /**

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