Kernel: Make mkdir() accessible to userspace
This commit is contained in:
parent
18fbccafb7
commit
d2e2883a79
@ -6,7 +6,11 @@
|
|||||||
#define EBADF 9
|
#define EBADF 9
|
||||||
#define ENOMEM 12
|
#define ENOMEM 12
|
||||||
#define EFAULT 14
|
#define EFAULT 14
|
||||||
|
#define EEXIST 17
|
||||||
|
#define ENOTDIR 20
|
||||||
#define EISDIR 21
|
#define EISDIR 21
|
||||||
#define EINVAL 22
|
#define EINVAL 22
|
||||||
#define EMFILE 24
|
#define EMFILE 24
|
||||||
#define ENOSYS 38
|
#define ENOSPC 28
|
||||||
|
#define ENOSYS 38
|
||||||
|
#define ENOTSUP 95
|
@ -18,6 +18,7 @@
|
|||||||
#define SYS_fcntl 13
|
#define SYS_fcntl 13
|
||||||
#define SYS_mprotect 14
|
#define SYS_mprotect 14
|
||||||
#define SYS_clock 15
|
#define SYS_clock 15
|
||||||
|
#define SYS_mkdir 17 // 16 is reserved for fork(), which is WIP in a pull request
|
||||||
|
|
||||||
namespace Syscall
|
namespace Syscall
|
||||||
{
|
{
|
||||||
@ -41,4 +42,5 @@ void sys_seek(Context* context, int fd, long offset, int whence);
|
|||||||
void sys_exec(Context* context, const char* pathname);
|
void sys_exec(Context* context, const char* pathname);
|
||||||
void sys_fcntl(Context* context, int fd, int command, uintptr_t arg);
|
void sys_fcntl(Context* context, int fd, int command, uintptr_t arg);
|
||||||
void sys_mprotect(Context* context, void* address, size_t size, int prot);
|
void sys_mprotect(Context* context, void* address, size_t size, int prot);
|
||||||
void sys_clock(Context* context);
|
void sys_clock(Context* context);
|
||||||
|
void sys_mkdir(Context* context, const char* filename);
|
@ -132,12 +132,27 @@ int VFS::mkdir(const char* path, const char* name)
|
|||||||
if (!node)
|
if (!node)
|
||||||
{
|
{
|
||||||
kwarnln("Attempting to mkdir in %s, which does not exist", path);
|
kwarnln("Attempting to mkdir in %s, which does not exist", path);
|
||||||
return -1;
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
if (node->type != VFS_DIRECTORY)
|
||||||
|
{
|
||||||
|
kwarnln("Attempting to mkdir in %s, which is not a directory!!", path);
|
||||||
|
return -ENOTDIR;
|
||||||
}
|
}
|
||||||
if (!node->mkdir_func)
|
if (!node->mkdir_func)
|
||||||
{
|
{
|
||||||
kwarnln("Chosen node does not support mkdir()");
|
kwarnln("Chosen node does not support mkdir()");
|
||||||
return -1;
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
if (!node->find_func)
|
||||||
|
{
|
||||||
|
kwarnln("Chosen node does not support finddir()");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
if (node->find_func(node, name) != nullptr)
|
||||||
|
{
|
||||||
|
kwarnln("Already exists");
|
||||||
|
return -EEXIST;
|
||||||
}
|
}
|
||||||
return node->mkdir_func(node, name);
|
return node->mkdir_func(node, name);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "init/InitRD.h"
|
#include "init/InitRD.h"
|
||||||
#include "bootboot.h"
|
#include "bootboot.h"
|
||||||
|
#include "errno.h"
|
||||||
#include "fs/VFS.h"
|
#include "fs/VFS.h"
|
||||||
#include "io/Serial.h"
|
#include "io/Serial.h"
|
||||||
#include "log/Log.h"
|
#include "log/Log.h"
|
||||||
@ -190,23 +191,23 @@ int initrd_mkdir(VFS::Node* node, const char* name) // FIXME: Return proper erro
|
|||||||
if (total_dirs >= 32)
|
if (total_dirs >= 32)
|
||||||
{
|
{
|
||||||
kwarnln("mkdir() failed: too many directories");
|
kwarnln("mkdir() failed: too many directories");
|
||||||
return -1;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
if (node->inode > total_dirs)
|
if (node->inode > total_dirs)
|
||||||
{
|
{
|
||||||
kwarnln("mkdir() failed: invalid node");
|
kwarnln("mkdir() failed: invalid node");
|
||||||
return -1;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (!(node->type & VFS_DIRECTORY))
|
if (!(node->type & VFS_DIRECTORY))
|
||||||
{
|
{
|
||||||
kwarnln("mkdir() failed: not a directory");
|
kwarnln("mkdir() failed: not a directory");
|
||||||
return -1;
|
return -ENOTDIR;
|
||||||
}
|
}
|
||||||
InitRD::Directory& parent = dirs[node->inode];
|
InitRD::Directory& parent = dirs[node->inode];
|
||||||
if (parent.entries == INITRD_MAX_FILES_IN_DIR)
|
if (parent.entries == INITRD_MAX_FILES_IN_DIR)
|
||||||
{
|
{
|
||||||
kwarnln("mkdir() failed: parent is null");
|
kwarnln("mkdir() failed: parent is full");
|
||||||
return -1;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
uint64_t inode = total_dirs;
|
uint64_t inode = total_dirs;
|
||||||
VFS::Node& new_node = nodes[total_nodes++];
|
VFS::Node& new_node = nodes[total_nodes++];
|
||||||
|
@ -27,6 +27,7 @@ void Syscall::entry(Context* context)
|
|||||||
case SYS_fcntl: sys_fcntl(context, (int)context->rdi, (int)context->rsi, context->rdx); break;
|
case SYS_fcntl: sys_fcntl(context, (int)context->rdi, (int)context->rsi, context->rdx); break;
|
||||||
case SYS_mprotect: sys_mprotect(context, (void*)context->rdi, context->rsi, (int)context->rdx); break;
|
case SYS_mprotect: sys_mprotect(context, (void*)context->rdi, context->rsi, (int)context->rdx); break;
|
||||||
case SYS_clock: sys_clock(context); break;
|
case SYS_clock: sys_clock(context); break;
|
||||||
|
case SYS_mkdir: sys_mkdir(context, (const char*)context->rdi); break;
|
||||||
default: context->rax = -ENOSYS; break;
|
default: context->rax = -ENOSYS; break;
|
||||||
}
|
}
|
||||||
VMM::exit_syscall_context();
|
VMM::exit_syscall_context();
|
||||||
|
@ -217,4 +217,20 @@ void sys_close(Context* context, int fd)
|
|||||||
current_task->files[fd].close();
|
current_task->files[fd].close();
|
||||||
context->rax = 0;
|
context->rax = 0;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sys_mkdir(Context* context, const char* filename)
|
||||||
|
{
|
||||||
|
char* kfilename = Syscall::strdup_from_user(filename);
|
||||||
|
if (!kfilename)
|
||||||
|
{
|
||||||
|
context->rax = -EFAULT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = VFS::mkdir(kfilename);
|
||||||
|
|
||||||
|
kfree(kfilename);
|
||||||
|
|
||||||
|
context->rax = rc;
|
||||||
}
|
}
|
@ -4,16 +4,20 @@
|
|||||||
/* The last error encountered during a call to a library or system function. */
|
/* The last error encountered during a call to a library or system function. */
|
||||||
extern int errno;
|
extern int errno;
|
||||||
|
|
||||||
#define EPERM 1 // Operation not permitted
|
#define EPERM 1 // Operation not permitted
|
||||||
#define ENOENT 2 // No such file or directory
|
#define ENOENT 2 // No such file or directory
|
||||||
#define ENOEXEC 8 // Exec format error
|
#define ENOEXEC 8 // Exec format error
|
||||||
#define EBADF 9 // Bad file descriptor
|
#define EBADF 9 // Bad file descriptor
|
||||||
#define ENOMEM 12 // Cannot allocate memory
|
#define ENOMEM 12 // Cannot allocate memory
|
||||||
#define EFAULT 14 // Bad address
|
#define EFAULT 14 // Bad address
|
||||||
#define EISDIR 21 // Is a directory
|
#define EEXIST 17 // File exists
|
||||||
#define EINVAL 22 // Invalid argument
|
#define ENOTDIR 10 // Not a directory
|
||||||
#define EMFILE 24 // Too many open files
|
#define EISDIR 21 // Is a directory
|
||||||
#define EPIPE 32 // Broken pipe. Not implemented.
|
#define EINVAL 22 // Invalid argument
|
||||||
#define ENOSYS 38 // Function not implemented
|
#define EMFILE 24 // Too many open files
|
||||||
|
#define ENOSPC 28 // No space left on device
|
||||||
|
#define EPIPE 32 // Broken pipe. Not implemented.
|
||||||
|
#define ENOSYS 38 // Function not implemented
|
||||||
|
#define ENOTSUP 95 // Operation not supported.
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue
Block a user