From 4ebe00546574e97c5316881881f7f2562deea74b Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 21 Aug 2012 22:29:11 +0800 Subject: [PATCH] Kernel - VFS API Update - ReadDir caller provided buffer --- AcessNative/acesskernel_src/nativefs.c | 15 ++-- KernelLand/Kernel/drv/fifo.c | 23 +++--- KernelLand/Kernel/drv/pci.c | 12 +-- KernelLand/Kernel/drv/proc.c | 14 ++-- KernelLand/Kernel/drv/vterm.c | 11 +-- KernelLand/Kernel/include/acess.h | 1 + KernelLand/Kernel/include/errno.h | 1 + KernelLand/Kernel/include/vfs.h | 13 ++- KernelLand/Kernel/include/vfs_ext.h | 5 +- KernelLand/Kernel/libc.c | 10 +++ KernelLand/Kernel/vfs/dir.c | 24 +++--- KernelLand/Kernel/vfs/fs/devfs.c | 17 ++-- KernelLand/Kernel/vfs/fs/root.c | 29 ++++--- KernelLand/Kernel/vfs/open.c | 38 ++++++++- KernelLand/Modules/Filesystems/Ext2/dir.c | 43 +++++----- .../Modules/Filesystems/Ext2/ext2_common.h | 4 +- KernelLand/Modules/Filesystems/FAT/common.h | 4 +- KernelLand/Modules/Filesystems/FAT/dir.c | 80 +++++++------------ .../Modules/Filesystems/InitRD/initrd.h | 6 +- KernelLand/Modules/Filesystems/InitRD/main.c | 9 ++- KernelLand/Modules/Filesystems/NTFS/common.h | 3 + KernelLand/Modules/Filesystems/NTFS/dir.c | 6 +- KernelLand/Modules/Filesystems/NTFS/main.c | 4 - .../Modules/Filesystems/RAMDisk/ramdisk.c | 19 ++--- KernelLand/Modules/IPStack/adapters.c | 14 ++-- KernelLand/Modules/IPStack/init.h | 12 +++ KernelLand/Modules/IPStack/interface.c | 65 ++++++--------- KernelLand/Modules/IPStack/interface.h | 10 +++ KernelLand/Modules/IPStack/main.c | 18 +---- KernelLand/Modules/IPStack/routing.c | 46 ++++++----- KernelLand/Modules/IPStack/tcp.c | 14 ++-- KernelLand/Modules/Input/Mouse/main.c | 10 ++- KernelLand/Modules/Storage/FDDv2/main.c | 15 ++-- KernelLand/Modules/Storage/LVM/main.c | 33 +++++--- KernelLand/Modules/USB/Core/main.c | 6 +- 35 files changed, 341 insertions(+), 293 deletions(-) create mode 100644 KernelLand/Modules/IPStack/init.h create mode 100644 KernelLand/Modules/IPStack/interface.h diff --git a/AcessNative/acesskernel_src/nativefs.c b/AcessNative/acesskernel_src/nativefs.c index 7c20b69e..0e791b8f 100644 --- a/AcessNative/acesskernel_src/nativefs.c +++ b/AcessNative/acesskernel_src/nativefs.c @@ -31,7 +31,7 @@ typedef struct tVFS_Node *NativeFS_Mount(const char *Device, const char **Arguments); void NativeFS_Unmount(tVFS_Node *Node); tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name); -char *NativeFS_ReadDir(tVFS_Node *Node, int Position); + int NativeFS_ReadDir(tVFS_Node *Node, int Position, char Dest[FILENAME_MAX]); size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void *Buffer); size_t NativeFS_Write(tVFS_Node *Node, _acess_off_t Offset, size_t Length, const void *Buffer); void NativeFS_Close(tVFS_Node *Node); @@ -168,11 +168,10 @@ tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name) return Inode_CacheNode(info->InodeHandle, &baseRet); } -char *NativeFS_ReadDir(tVFS_Node *Node, int Position) +int NativeFS_ReadDir(tVFS_Node *Node, int Position, char Dest[FILENAME_MAX]) { struct dirent *ent; DIR *dp = (void*)(tVAddr)Node->Inode; - char *ret; ENTER("pNode iPosition", Node, Position); @@ -184,16 +183,16 @@ char *NativeFS_ReadDir(tVFS_Node *Node, int Position) } while(Position-- && ent); if( !ent ) { - LEAVE('n'); - return NULL; + LEAVE('i', -ENOENT); + return -ENOENT; } - ret = strdup(ent->d_name); + strncpy(Dest, ent->d_name, FILENAME_MAX); // TODO: Unlock node - LEAVE('s', ret); - return ret; + LEAVE('i', 0); + return 0; } size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void *Buffer) diff --git a/KernelLand/Kernel/drv/fifo.c b/KernelLand/Kernel/drv/fifo.c index cb62193a..2adaec7c 100644 --- a/KernelLand/Kernel/drv/fifo.c +++ b/KernelLand/Kernel/drv/fifo.c @@ -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; } diff --git a/KernelLand/Kernel/drv/pci.c b/KernelLand/Kernel/drv/pci.c index f09389bc..702c9ccc 100644 --- a/KernelLand/Kernel/drv/pci.c +++ b/KernelLand/Kernel/drv/pci.c @@ -33,7 +33,7 @@ typedef struct sPCIDevice int PCI_Install(char **Arguments); int PCI_ScanBus(int ID, int bFill); -char *PCI_int_ReadDirRoot(tVFS_Node *node, int pos); + int PCI_int_ReadDirRoot(tVFS_Node *node, int pos, char Dest[FILENAME_MAX]); tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename); Uint32 PCI_int_GetBusAddr(Uint16 Bus, Uint16 Slot, Uint16 Fcn, Uint8 Offset); size_t PCI_int_ReadDevice(tVFS_Node *node, off_t Offset, size_t Length, void *buffer); @@ -197,16 +197,16 @@ int PCI_ScanBus(int BusID, int bFill) /** * \brief Read from Root of PCI Driver */ -char *PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos) +int PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]) { ENTER("pNode iPos", Node, Pos); if(Pos < 0 || Pos >= giPCI_DeviceCount) { - LEAVE('n'); - return NULL; + LEAVE_RET('i', -EINVAL); } - LEAVE('s', gPCI_Devices[Pos].Name); - return strdup( gPCI_Devices[Pos].Name ); + LOG("Name = %s", gPCI_Devices[Pos].Name); + strncpy(Dest, gPCI_Devices[Pos].Name, FILENAME_MAX); + LEAVE_RET('i', 0); } /** */ diff --git a/KernelLand/Kernel/drv/proc.c b/KernelLand/Kernel/drv/proc.c index e8cab198..1e0c6bd8 100644 --- a/KernelLand/Kernel/drv/proc.c +++ b/KernelLand/Kernel/drv/proc.c @@ -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; } /** diff --git a/KernelLand/Kernel/drv/vterm.c b/KernelLand/Kernel/drv/vterm.c index 63db01e4..fc6dea26 100644 --- a/KernelLand/Kernel/drv/vterm.c +++ b/KernelLand/Kernel/drv/vterm.c @@ -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; } /** diff --git a/KernelLand/Kernel/include/acess.h b/KernelLand/Kernel/include/acess.h index 51ae771b..1d062a5e 100644 --- a/KernelLand/Kernel/include/acess.h +++ b/KernelLand/Kernel/include/acess.h @@ -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); diff --git a/KernelLand/Kernel/include/errno.h b/KernelLand/Kernel/include/errno.h index 7c2e97ab..a327cc00 100644 --- a/KernelLand/Kernel/include/errno.h +++ b/KernelLand/Kernel/include/errno.h @@ -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 diff --git a/KernelLand/Kernel/include/vfs.h b/KernelLand/Kernel/include/vfs.h index 98bc0275..59824e23 100644 --- a/KernelLand/Kernel/include/vfs.h +++ b/KernelLand/Kernel/include/vfs.h @@ -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 diff --git a/KernelLand/Kernel/include/vfs_ext.h b/KernelLand/Kernel/include/vfs_ext.h index d9bc833c..44c70f86 100644 --- a/KernelLand/Kernel/include/vfs_ext.h +++ b/KernelLand/Kernel/include/vfs_ext.h @@ -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 diff --git a/KernelLand/Kernel/libc.c b/KernelLand/Kernel/libc.c index 08ebc623..ef944267 100644 --- a/KernelLand/Kernel/libc.c +++ b/KernelLand/Kernel/libc.c @@ -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 diff --git a/KernelLand/Kernel/vfs/dir.c b/KernelLand/Kernel/vfs/dir.c index 65218af0..fab9d563 100644 --- a/KernelLand/Kernel/vfs/dir.c +++ b/KernelLand/Kernel/vfs/dir.c @@ -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; } diff --git a/KernelLand/Kernel/vfs/fs/devfs.c b/KernelLand/Kernel/vfs/fs/devfs.c index 9ab2b7b4..93898226 100644 --- a/KernelLand/Kernel/vfs/fs/devfs.c +++ b/KernelLand/Kernel/vfs/fs/devfs.c @@ -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; + } } /** diff --git a/KernelLand/Kernel/vfs/fs/root.c b/KernelLand/Kernel/vfs/fs/root.c index abe59457..56858617 100644 --- a/KernelLand/Kernel/vfs/fs/root.c +++ b/KernelLand/Kernel/vfs/fs/root.c @@ -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; } /** diff --git a/KernelLand/Kernel/vfs/open.c b/KernelLand/Kernel/vfs/open.c index 22d20e99..5ea67c19 100644 --- a/KernelLand/Kernel/vfs/open.c +++ b/KernelLand/Kernel/vfs/open.c @@ -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 diff --git a/KernelLand/Modules/Filesystems/Ext2/dir.c b/KernelLand/Modules/Filesystems/Ext2/dir.c index 7b78ae43..de0b30a5 100644 --- a/KernelLand/Modules/Filesystems/Ext2/dir.c +++ b/KernelLand/Modules/Filesystems/Ext2/dir.c @@ -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); } /** diff --git a/KernelLand/Modules/Filesystems/Ext2/ext2_common.h b/KernelLand/Modules/Filesystems/Ext2/ext2_common.h index 57b74932..5515429f 100644 --- a/KernelLand/Modules/Filesystems/Ext2/ext2_common.h +++ b/KernelLand/Modules/Filesystems/Ext2/ext2_common.h @@ -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); diff --git a/KernelLand/Modules/Filesystems/FAT/common.h b/KernelLand/Modules/Filesystems/FAT/common.h index b473bf73..9402830b 100644 --- a/KernelLand/Modules/Filesystems/FAT/common.h +++ b/KernelLand/Modules/Filesystems/FAT/common.h @@ -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 diff --git a/KernelLand/Modules/Filesystems/FAT/dir.c b/KernelLand/Modules/Filesystems/FAT/dir.c index 8a690a13..b74b31ff 100644 --- a/KernelLand/Modules/Filesystems/FAT/dir.c +++ b/KernelLand/Modules/Filesystems/FAT/dir.c @@ -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; } /** diff --git a/KernelLand/Modules/Filesystems/InitRD/initrd.h b/KernelLand/Modules/Filesystems/InitRD/initrd.h index 92af1144..1848613b 100644 --- a/KernelLand/Modules/Filesystems/InitRD/initrd.h +++ b/KernelLand/Modules/Filesystems/InitRD/initrd.h @@ -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; diff --git a/KernelLand/Modules/Filesystems/InitRD/main.c b/KernelLand/Modules/Filesystems/InitRD/main.c index 863a24a3..96f783e3 100644 --- a/KernelLand/Modules/Filesystems/InitRD/main.c +++ b/KernelLand/Modules/Filesystems/InitRD/main.c @@ -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; } /** diff --git a/KernelLand/Modules/Filesystems/NTFS/common.h b/KernelLand/Modules/Filesystems/NTFS/common.h index 598120d2..312bee74 100644 --- a/KernelLand/Modules/Filesystems/NTFS/common.h +++ b/KernelLand/Modules/Filesystems/NTFS/common.h @@ -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 diff --git a/KernelLand/Modules/Filesystems/NTFS/dir.c b/KernelLand/Modules/Filesystems/NTFS/dir.c index 37661e82..11cd2417 100644 --- a/KernelLand/Modules/Filesystems/NTFS/dir.c +++ b/KernelLand/Modules/Filesystems/NTFS/dir.c @@ -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; } /** diff --git a/KernelLand/Modules/Filesystems/NTFS/main.c b/KernelLand/Modules/Filesystems/NTFS/main.c index 87f2a09a..b9c4b8dd 100644 --- a/KernelLand/Modules/Filesystems/NTFS/main.c +++ b/KernelLand/Modules/Filesystems/NTFS/main.c @@ -11,10 +11,6 @@ #include "common.h" #include -// === 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); diff --git a/KernelLand/Modules/Filesystems/RAMDisk/ramdisk.c b/KernelLand/Modules/Filesystems/RAMDisk/ramdisk.c index defa50b4..eeef8f68 100644 --- a/KernelLand/Modules/Filesystems/RAMDisk/ramdisk.c +++ b/KernelLand/Modules/Filesystems/RAMDisk/ramdisk.c @@ -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) diff --git a/KernelLand/Modules/IPStack/adapters.c b/KernelLand/Modules/IPStack/adapters.c index 16e0f975..2a02fd27 100644 --- a/KernelLand/Modules/IPStack/adapters.c +++ b/KernelLand/Modules/IPStack/adapters.c @@ -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 index 00000000..1f14bf10 --- /dev/null +++ b/KernelLand/Modules/IPStack/init.h @@ -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 + diff --git a/KernelLand/Modules/IPStack/interface.c b/KernelLand/Modules/IPStack/interface.c index 9bd00d92..9ab4b9ae 100644 --- a/KernelLand/Modules/IPStack/interface.c +++ b/KernelLand/Modules/IPStack/interface.c @@ -8,6 +8,7 @@ #include "link.h" #include #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 index 00000000..60459a0a --- /dev/null +++ b/KernelLand/Modules/IPStack/interface.h @@ -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 + diff --git a/KernelLand/Modules/IPStack/main.c b/KernelLand/Modules/IPStack/main.c index 5763e2db..bc920f1f 100644 --- a/KernelLand/Modules/IPStack/main.c +++ b/KernelLand/Modules/IPStack/main.c @@ -9,19 +9,10 @@ #include #include #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", { diff --git a/KernelLand/Modules/IPStack/routing.c b/KernelLand/Modules/IPStack/routing.c index 3153ef26..d9efa99f 100644 --- a/KernelLand/Modules/IPStack/routing.c +++ b/KernelLand/Modules/IPStack/routing.c @@ -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; } /** diff --git a/KernelLand/Modules/IPStack/tcp.c b/KernelLand/Modules/IPStack/tcp.c index c8a5584c..71dd4e55 100644 --- a/KernelLand/Modules/IPStack/tcp.c +++ b/KernelLand/Modules/IPStack/tcp.c @@ -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; } /** diff --git a/KernelLand/Modules/Input/Mouse/main.c b/KernelLand/Modules/Input/Mouse/main.c index 56bf9b52..25185a2d 100644 --- a/KernelLand/Modules/Input/Mouse/main.c +++ b/KernelLand/Modules/Input/Mouse/main.c @@ -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) diff --git a/KernelLand/Modules/Storage/FDDv2/main.c b/KernelLand/Modules/Storage/FDDv2/main.c index c33dcdad..f6290d90 100644 --- a/KernelLand/Modules/Storage/FDDv2/main.c +++ b/KernelLand/Modules/Storage/FDDv2/main.c @@ -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; } /** diff --git a/KernelLand/Modules/Storage/LVM/main.c b/KernelLand/Modules/Storage/LVM/main.c index d4e9aa40..8793d68b 100644 --- a/KernelLand/Modules/Storage/LVM/main.c +++ b/KernelLand/Modules/Storage/LVM/main.c @@ -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) { diff --git a/KernelLand/Modules/USB/Core/main.c b/KernelLand/Modules/USB/Core/main.c index 94ec2531..cdbe2ee7 100644 --- a/KernelLand/Modules/USB/Core/main.c +++ b/KernelLand/Modules/USB/Core/main.c @@ -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; } /** -- 2.20.1