X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=AcessNative%2Facesskernel_src%2Fnativefs.c;h=e603c26b123370b6b0be94a7d67dfb4cd9d00dd0;hb=2207af75e8ed7a19de57ec756ef849f41b67530f;hp=6d6e2fedd6a60ceaea9d3d06b90b0090341f2e20;hpb=3764c294f21229bdf700f436fa4884f5e76e0d3a;p=tpg%2Facess2.git diff --git a/AcessNative/acesskernel_src/nativefs.c b/AcessNative/acesskernel_src/nativefs.c index 6d6e2fed..e603c26b 100644 --- a/AcessNative/acesskernel_src/nativefs.c +++ b/AcessNative/acesskernel_src/nativefs.c @@ -5,12 +5,16 @@ * nativefs.c * - Host filesystem access */ -#define DEBUG 1 +#define DEBUG 0 +#define off_t _acess_off_t +#define sprintf _acess_sprintf #include // Acess #include // Acess +#undef off_t +#undef sprintf #include // Posix #include // Posix -#include // Posix +#include // C //NOTES: // tVFS_Node->ImplPtr is a pointer to the filesystem flags (tNativeFS) @@ -20,7 +24,7 @@ // === STRUCTURES === typedef struct { - int InodeHandle; + void *InodeHandle; int bReadOnly; } tNativeFS; @@ -28,15 +32,29 @@ typedef struct int NativeFS_Install(char **Arguments); 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); -Uint64 NativeFS_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); +tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name, Uint Flags); + int NativeFS_ReadDir(tVFS_Node *Node, int Position, char Dest[FILENAME_MAX]); +tVFS_Node *NativeFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags); +size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void *Buffer, Uint Flags); +size_t NativeFS_Write(tVFS_Node *Node, _acess_off_t Offset, size_t Length, const void *Buffer, Uint Flags); +void NativeFS_Close(tVFS_Node *Node); // === GLOBALS === +tVFS_NodeType gNativeFS_FileNodeType = { + .Read = NativeFS_Read, + .Write = NativeFS_Write, + .Close = NativeFS_Close +}; +tVFS_NodeType gNativeFS_DirNodeType = { + .FindDir = NativeFS_FindDir, + .ReadDir = NativeFS_ReadDir, + .MkNod = NativeFS_MkNod, + .Close = NativeFS_Close +}; tVFS_Driver gNativeFS_Driver = { - "nativefs", 0, - NativeFS_Mount, NativeFS_Unmount, - NULL, + .Name = "nativefs", + .InitDevice = NativeFS_Mount, + .Unmount = NativeFS_Unmount }; // === CODE === @@ -53,12 +71,15 @@ tVFS_Node *NativeFS_Mount(const char *Device, const char **Arguments) DIR *dp; dp = opendir(Device); - if(!dp) return NULL; + if(!dp) { + Log_Warning("NativeFS", "ERROR: Unable to open device root '%s'", Device); + return NULL; + } // Check if directory exists // Parse flags from arguments info = malloc(sizeof(tNativeFS)); - info->InodeHandle = Inode_GetHandle(); + info->InodeHandle = Inode_GetHandle(NULL); info->bReadOnly = 0; // Create node ret = malloc(sizeof(tVFS_Node)); @@ -66,11 +87,11 @@ tVFS_Node *NativeFS_Mount(const char *Device, const char **Arguments) ret->Data = strdup(Device); ret->ImplInt = strlen(ret->Data); ret->ImplPtr = info; - ret->Inode = (Uint64)dp; - - ret->FindDir = NativeFS_FindDir; - ret->ReadDir = NativeFS_ReadDir; - + ret->Inode = (Uint64)(tVAddr)dp; + ret->Flags = VFS_FFLAG_DIRECTORY; + + ret->Type = &gNativeFS_DirNodeType; + return ret; } @@ -78,7 +99,7 @@ void NativeFS_Unmount(tVFS_Node *Node) { tNativeFS *info = Node->ImplPtr; Inode_ClearCache( info->InodeHandle ); - closedir( (void *)Node->Inode ); + closedir( (void *)(tVAddr)Node->Inode ); free(Node->Data); free(Node); free(info); @@ -87,12 +108,18 @@ void NativeFS_Unmount(tVFS_Node *Node) void NativeFS_Close(tVFS_Node *Node) { tNativeFS *info = Node->ImplPtr; - Inode_UncacheNode( info->InodeHandle, Node->Inode ); + DIR *dp = (Node->Flags & VFS_FFLAG_DIRECTORY) ? (DIR*)(tVAddr)Node->Inode : 0; + FILE *fp = (Node->Flags & VFS_FFLAG_DIRECTORY) ? 0 : (FILE*)(tVAddr)Node->Inode; + + if( Inode_UncacheNode( info->InodeHandle, Node->Inode ) == 1 ) { + if(dp) closedir(dp); + if(fp) fclose(fp); + } } -tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name) +tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name, Uint Flags) { - char *path = malloc(Node->ImplInt + 1 + strlen(Name) + 1); + char *path; tNativeFS *info = Node->ImplPtr; tVFS_Node baseRet; struct stat statbuf; @@ -100,6 +127,7 @@ tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name) ENTER("pNode sName", Node, Name); // Create path + path = malloc(Node->ImplInt + 1 + strlen(Name) + 1); strcpy(path, Node->Data); path[Node->ImplInt] = '/'; strcpy(path + Node->ImplInt + 1, Name); @@ -120,16 +148,26 @@ tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name) if( S_ISDIR(statbuf.st_mode) ) { LOG("Directory"); - baseRet.Inode = (Uint64) opendir(path); - baseRet.FindDir = NativeFS_FindDir; - baseRet.ReadDir = NativeFS_ReadDir; + baseRet.Inode = (Uint64)(tVAddr) opendir(path); + baseRet.Type = &gNativeFS_DirNodeType; baseRet.Flags |= VFS_FFLAG_DIRECTORY; + baseRet.Size = -1; } else { LOG("File"); - baseRet.Inode = (Uint64) fopen(path, "r+"); - baseRet.Read = NativeFS_Read; + FILE *fp = fopen(path, "r+"); + if( !fp ) { + Log_Error("NativeFS", "fopen of '%s' failed: %s", path, strerror(errno)); + free(path); + LEAVE('n'); + return NULL; + } + baseRet.Inode = (Uint64)(tVAddr) fp; + baseRet.Type = &gNativeFS_FileNodeType; + + fseek( fp, 0, SEEK_END ); + baseRet.Size = ftell( fp ); } // Create new node @@ -141,20 +179,75 @@ 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]) { - // Keep track of the current directory position - return NULL; + struct dirent *ent; + DIR *dp = (void*)(tVAddr)Node->Inode; + + ENTER("pNode iPosition", Node, Position); + + // TODO: Keep track of current position in the directory + // TODO: Lock node during this + rewinddir(dp); + do { + ent = readdir(dp); + } while(Position-- && ent); + + if( !ent ) { + LEAVE('i', -ENOENT); + return -ENOENT; + } + + strncpy(Dest, ent->d_name, FILENAME_MAX); + + // TODO: Unlock node + + LEAVE('i', 0); + return 0; } -Uint64 NativeFS_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +tVFS_Node *NativeFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags) { - ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); - if( fseek( (void *)Node->Inode, Offset, SEEK_SET ) != 0 ) + char path[Node->ImplInt+1+strlen(Name)+1]; + sprintf(path, "%s/%s", Node->Data, Name); + if( Flags & VFS_FFLAG_DIRECTORY ) + { + mkdir(path, 0755); + } + else + { + FILE *tmp = fopen(path, "w"); + if(!tmp) return NULL; + fclose(tmp); + } + return NativeFS_FindDir(Node, Name, 0); +} + +size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void *Buffer, Uint Flags) +{ + ENTER("pNode XOffset xLength pBuffer", Node, Offset, Length, Buffer); + if( fseek( (FILE *)(tVAddr)Node->Inode, Offset, SEEK_SET ) != 0 ) { LEAVE('i', 0); return 0; } - LEAVE('-'); - return fread( Buffer, 1, Length, (void *)Node->Inode ); + size_t ret = fread( Buffer, 1, Length, (FILE *)(tVAddr)Node->Inode ); + LEAVE('x', ret); + return ret; +} + +size_t NativeFS_Write(tVFS_Node *Node, _acess_off_t Offset, size_t Length, const void *Buffer, Uint Flags) +{ + FILE *fp = (FILE *)(tVAddr)Node->Inode; + ENTER("pNode XOffset xLength pBuffer", Node, Offset, Length, Buffer); + if( fseek( fp, Offset, SEEK_SET ) != 0 ) + { + LEAVE('i', 0); + return 0; + } + size_t ret = fwrite( Buffer, 1, Length, fp ); + fflush( fp ); + LEAVE('i', ret); + return ret; + }