CFLAGS += -g
endif
-OBJ = $(addprefix arch/$(ARCHDIR)/,$(A_OBJ))
-OBJ += heap.o messages.o debug.o modules.o lib.o syscalls.o system.o threads.o drvutil.o logging.o
+OBJ := $(addprefix arch/$(ARCHDIR)/,$(A_OBJ))
+OBJ += heap.o drvutil.o logging.o debug.o lib.o adt.o
+OBJ += messages.o modules.o syscalls.o system.o threads.o
OBJ += $(addprefix vfs/fs/, $(addsuffix .o,$(FILESYSTEMS)))
OBJ += drv/vterm.o drv/proc.o drv/fifo.o drv/iocache.o drv/dma.o drv/pci.o drv/kb.o drv/vga.o
OBJ += binary.o bin/elf.o bin/pe.o
-BUILD_NUM = 1837
+BUILD_NUM = 1866
#include <binary_ext.h>
#include <vfs_ext.h>
+#include <adt.h>
#endif
EACCES,
ENOTFOUND,
EREADONLY,
- ENOTIMPL
+ ENOTIMPL,
+ ENOENT,
+ ENFILE,
+ ENOTDIR,
+
+ NUM_ERRS
};
#endif
SYS_WRITE, // 68 - Write to an open file
SYS_IOCTL, // 69 - Perform an IOCtl Call
SYS_READDIR, // 70 - Read from an open directory
- SYS_MKDIR, // 71 - Create a new directory
- SYS_SYMLINK, // 72 - Create a symbolic link
- SYS_GETACL, // 73 - Get an ACL Value
- SYS_SETACL, // 74 - Set an ACL Value
- SYS_FINFO, // 75 - Get file information
- SYS_SEEK, // 76 - Seek to a new position in the file
- SYS_TELL, // 77 - Return the current file position
- SYS_CHDIR, // 78 - Change current directory
- SYS_GETCWD, // 79 - Get current directory
- SYS_MOUNT, // 80 - Mount a filesystem
+ SYS_OPENCHILD, // 71 - Open a child entry in a directory
+ SYS_MKDIR, // 72 - Create a new directory
+ SYS_SYMLINK, // 73 - Create a symbolic link
+ SYS_GETACL, // 74 - Get an ACL Value
+ SYS_SETACL, // 75 - Set an ACL Value
+ SYS_FINFO, // 76 - Get file information
+ SYS_SEEK, // 77 - Seek to a new position in the file
+ SYS_TELL, // 78 - Return the current file position
+ SYS_CHDIR, // 79 - Change current directory
+ SYS_GETCWD, // 80 - Get current directory
+ SYS_MOUNT, // 81 - Mount a filesystem
NUM_SYSCALLS,
SYS_DEBUG = 0x100 // 0x100 - Print a debug string
};
"","","","","","",
"","","","","","",
"","","","","SYS_OPEN","SYS_REOPEN",
- "SYS_CLOSE","SYS_READ","SYS_WRITE","SYS_IOCTL","SYS_READDIR","SYS_MKDIR",
- "SYS_SYMLINK","SYS_GETACL","SYS_SETACL","SYS_FINFO","SYS_SEEK","SYS_TELL",
- "SYS_CHDIR","SYS_GETCWD","SYS_MOUNT",""
+ "SYS_CLOSE","SYS_READ","SYS_WRITE","SYS_IOCTL","SYS_READDIR","SYS_OPENCHILD",
+ "SYS_MKDIR","SYS_SYMLINK","SYS_GETACL","SYS_SETACL","SYS_FINFO","SYS_SEEK",
+ "SYS_TELL","SYS_CHDIR","SYS_GETCWD","SYS_MOUNT",""
};
#endif
%define SYS_WRITE 68 ; Write to an open file
%define SYS_IOCTL 69 ; Perform an IOCtl Call
%define SYS_READDIR 70 ; Read from an open directory
-%define SYS_MKDIR 71 ; Create a new directory
-%define SYS_SYMLINK 72 ; Create a symbolic link
-%define SYS_GETACL 73 ; Get an ACL Value
-%define SYS_SETACL 74 ; Set an ACL Value
-%define SYS_FINFO 75 ; Get file information
-%define SYS_SEEK 76 ; Seek to a new position in the file
-%define SYS_TELL 77 ; Return the current file position
-%define SYS_CHDIR 78 ; Change current directory
-%define SYS_GETCWD 79 ; Get current directory
-%define SYS_MOUNT 80 ; Mount a filesystem
+%define SYS_OPENCHILD 71 ; Open a child entry in a directory
+%define SYS_MKDIR 72 ; Create a new directory
+%define SYS_SYMLINK 73 ; Create a symbolic link
+%define SYS_GETACL 74 ; Get an ACL Value
+%define SYS_SETACL 75 ; Set an ACL Value
+%define SYS_FINFO 76 ; Get file information
+%define SYS_SEEK 77 ; Seek to a new position in the file
+%define SYS_TELL 78 ; Return the current file position
+%define SYS_CHDIR 79 ; Change current directory
+%define SYS_GETCWD 80 ; Get current directory
+%define SYS_MOUNT 81 ; Mount a filesystem
* \return Boolean Success
*/
extern int VFS_ReadDir(int FD, char *Dest);
+/**
+ * \brief Opens a file via an open directory
+ * \note The file to open must be a direct child of the parent
+ * \param Errno Error number
+ * \param FD Parent Directory
+ * \param Name Child name
+ * \param Mode Open mode
+ * \return File handle (same as returned from VFS_Open)
+ */
+extern int VFS_OpenChild(Uint *Errno, int FD, char *Name, Uint Mode);
#endif
ret = VFS_ReadDir( Regs->Arg1, (void*)Regs->Arg2 );
break;
+ // Open a file that is a entry in an open directory
+ case SYS_OPENCHILD:
+ if( !Syscall_ValidString(Regs->Arg2) ) {
+ err = -EINVAL;
+ ret = -1;
+ break;
+ }
+ ret = VFS_OpenChild( &err, Regs->Arg1, (char*)Regs->Arg2, Regs->Arg3);
+ break;
+
// Change Directory
case SYS_CHDIR:
if( !Syscall_ValidString(Regs->Arg1) ) {
SYS_WRITE Write to an open file
SYS_IOCTL Perform an IOCtl Call
SYS_READDIR Read from an open directory
+SYS_OPENCHILD Open a child entry in a directory
SYS_MKDIR Create a new directory
SYS_SYMLINK Create a symbolic link
SYS_GETACL Get an ACL Value
return -1;
}
+
+/**
+ * \brief Open a file from an open directory
+ */
+int VFS_OpenChild(Uint *Errno, int FD, char *Name, Uint Mode)
+{
+ tVFS_Handle *h;
+ tVFS_Node *node;
+ int i;
+
+ // Get handle
+ h = VFS_GetHandle(FD);
+ if(h == NULL) {
+ Log_Warning("VFS", "VFS_OpenChild - Invalid file handle 0x%x", FD);
+ if(Errno) *Errno = EINVAL;
+ LEAVE('i', -1);
+ return -1;
+ }
+
+ // Check for directory
+ if( !(h->Node->Flags & VFS_FFLAG_DIRECTORY) ) {
+ Log_Warning("VFS", "VFS_OpenChild - Passed handle is not a directory", FD);
+ if(Errno) *Errno = ENOTDIR;
+ LEAVE('i', -1);
+ return -1;
+ }
+
+ // Find Child
+ node = h->Node->FindDir(h->Node, Name);
+ if(!node) {
+ if(Errno) *Errno = ENOENT;
+ LEAVE('i', -1);
+ return -1;
+ }
+
+ i = 0;
+ i |= (Mode & VFS_OPENFLAG_EXEC) ? VFS_PERM_EXECUTE : 0;
+ i |= (Mode & VFS_OPENFLAG_READ) ? VFS_PERM_READ : 0;
+ i |= (Mode & VFS_OPENFLAG_WRITE) ? VFS_PERM_WRITE : 0;
+
+ // Permissions Check
+ if( !VFS_CheckACL(node, i) ) {
+ if(node->Close) node->Close( node );
+ Log_Notice("VFS", "VFS_OpenChild - Permissions Failed");
+ if(Errno) *Errno = EACCES;
+ LEAVE('i', -1);
+ return -1;
+ }
+
+ // Check for a user open
+ if(Mode & VFS_OPENFLAG_USER)
+ {
+ // Allocate Buffer
+ if( MM_GetPhysAddr( (Uint)gaUserHandles ) == 0 )
+ {
+ Uint addr, size;
+ size = CFGINT(CFG_VFS_MAXFILES) * sizeof(tVFS_Handle);
+ for(addr = 0; addr < size; addr += 0x1000)
+ MM_Allocate( (Uint)gaUserHandles + addr );
+ memset( gaUserHandles, 0, size );
+ }
+ // Get a handle
+ for(i=0;i<CFGINT(CFG_VFS_MAXFILES);i++)
+ {
+ if(gaUserHandles[i].Node) continue;
+ gaUserHandles[i].Node = node;
+ gaUserHandles[i].Position = 0;
+ gaUserHandles[i].Mode = Mode;
+ LEAVE('i', i);
+ return i;
+ }
+ }
+ else
+ {
+ // Allocate space if not already
+ if( MM_GetPhysAddr( (Uint)gaKernelHandles ) == 0 )
+ {
+ Uint addr, size;
+ size = MAX_KERNEL_FILES * sizeof(tVFS_Handle);
+ for(addr = 0; addr < size; addr += 0x1000)
+ MM_Allocate( (Uint)gaKernelHandles + addr );
+ memset( gaKernelHandles, 0, size );
+ }
+ // Get a handle
+ for(i=0;i<MAX_KERNEL_FILES;i++)
+ {
+ if(gaKernelHandles[i].Node) continue;
+ gaKernelHandles[i].Node = node;
+ gaKernelHandles[i].Position = 0;
+ gaKernelHandles[i].Mode = Mode;
+ LEAVE('x', i|VFS_KERNEL_FLAG);
+ return i|VFS_KERNEL_FLAG;
+ }
+ }
+
+ Log_Error("VFS", "VFS_OpenChild - Out of handles");
+ if(Errno) *Errno = ENFILE;
+ LEAVE('i', -1);
+ return -1;
+}
+
/**
* \fn void VFS_Close(int FD)
* \brief Closes an open file handle
// Get handle
h = VFS_GetHandle(FD);
if(h == NULL) {
- Warning("Invalid file handle passed to VFS_Close, 0x%x\n", FD);
+ Log_Warning("VFS", "Invalid file handle passed to VFS_Close, 0x%x\n", FD);
return;
}
all: $(BIN)
clean:
- $(RM) $(BIN) $(OBJ)
+ $(RM) $(BIN) $(OBJ) $(BIN).dsm
install: $(BIN)
$(xCP) $(BIN) $(DISTROOT)/Libs/
$(BIN): $(OBJ)
$(LD) $(LDFLAGS) -o $(BIN) $(OBJ)
+ @$(OBJDUMP) -d $(BIN) > $(BIN).dsm
%.o: %.c
$(CC) $(CFLAGS) -o $@ -c $<
@$(LD) $(LDFLAGS) -o $(BIN) $(OBJ)
@$(STRIP) $(BIN)
-%.ao: %.asm syscalls.inc.asm
+%.ao: %.asm syscalls.inc.asm ../../../Kernel/include/syscalls.inc.asm
@echo $(AS) -o $@
@$(AS) $(ASFLAGS) -o $@ $<
SYSCALL1 chdir, SYS_CHDIR ; char*
SYSCALL3 ioctl, SYS_IOCTL ; int, int, void*
SYSCALL4 _SysMount, SYS_MOUNT ; char*, char*, char*, char*
+
+SYSCALL3 _SysOpenChild, SYS_OPENCHILD
extern int ioctl(int fd, int id, void *data);
extern int finfo(int fd, t_sysFInfo *info, int maxacls);
extern int readdir(int fd, char *dest);
+extern int _SysOpenChild(int fd, char *name, int flags);
extern int _SysGetACL(int fd, t_sysACL *dest);
extern int _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options);