Start implementing read and write support in tmpfs
write seems to work fine, read just hangs there, waiting.
This commit is contained in:
parent
046065c533
commit
42efc21110
@ -1,4 +1,4 @@
|
|||||||
C_APPS := init sh uname uptime hello ps ls args cat stat su session date mkdir screen
|
C_APPS := init sh uname uptime hello ps ls args cat stat su session date mkdir screen touch write
|
||||||
CXX_APPS := hello-cpp
|
CXX_APPS := hello-cpp
|
||||||
|
|
||||||
APPS_DIR := $(LUNA_ROOT)/apps
|
APPS_DIR := $(LUNA_ROOT)/apps
|
||||||
|
22
apps/src/touch.c
Normal file
22
apps/src/touch.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s [directory]\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd = creat(argv[1], 0755);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
perror("creat");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
75
apps/src/write.c
Normal file
75
apps/src/write.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static char* echoing_fgets(char* buf, size_t size, FILE* stream)
|
||||||
|
{
|
||||||
|
char* s = buf;
|
||||||
|
memset(buf, 0, size);
|
||||||
|
size_t oldsize = size;
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
int c = fgetc(stream);
|
||||||
|
if (c == EOF)
|
||||||
|
{
|
||||||
|
if (ferror(stream)) return NULL;
|
||||||
|
if (feof(stream))
|
||||||
|
{
|
||||||
|
if (s != buf) return s;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if ((char)c == '\b')
|
||||||
|
{
|
||||||
|
if (size != oldsize)
|
||||||
|
{
|
||||||
|
buf--;
|
||||||
|
size++;
|
||||||
|
putchar('\b');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size--;
|
||||||
|
*buf = (char)c;
|
||||||
|
buf++;
|
||||||
|
putchar((char)c);
|
||||||
|
if ((char)c == '\n') return s;
|
||||||
|
}
|
||||||
|
*buf = 0;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s [directory]\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd = open(argv[1], O_WRONLY | O_CREAT | O_APPEND, 0755);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
perror("open");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* fp = fdopen(fd, "a");
|
||||||
|
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
echoing_fgets(buf, BUFSIZ, stdin);
|
||||||
|
|
||||||
|
fputs(buf, fp);
|
||||||
|
if (ferror(fp))
|
||||||
|
{
|
||||||
|
perror("fputs");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
@ -12,5 +12,7 @@ namespace TmpFS
|
|||||||
int mkdir(VFS::Node* node, const char* name, mode_t mode);
|
int mkdir(VFS::Node* node, const char* name, mode_t mode);
|
||||||
|
|
||||||
ssize_t read(VFS::Node* node, size_t offset, size_t length, char* buffer);
|
ssize_t read(VFS::Node* node, size_t offset, size_t length, char* buffer);
|
||||||
ssize_t write(VFS::Node* node, size_t offset, size_t length, char* buffer);
|
ssize_t write(VFS::Node* node, size_t offset, size_t length, const char* buffer);
|
||||||
|
|
||||||
|
VFS::Node* create(VFS::Node* node, const char* name, mode_t mode, uid_t uid, gid_t gid);
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "utils/Result.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -25,6 +26,7 @@ namespace VFS
|
|||||||
typedef Node* (*node_readdir)(Node*, long);
|
typedef Node* (*node_readdir)(Node*, long);
|
||||||
typedef uintptr_t (*node_mmap)(Node*, uintptr_t, size_t, int, off_t);
|
typedef uintptr_t (*node_mmap)(Node*, uintptr_t, size_t, int, off_t);
|
||||||
typedef long (*node_ioctl)(Node*, int, uintptr_t);
|
typedef long (*node_ioctl)(Node*, int, uintptr_t);
|
||||||
|
typedef Node* (*node_create)(Node*, const char*, mode_t, uid_t, gid_t);
|
||||||
|
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
@ -49,6 +51,7 @@ namespace VFS
|
|||||||
node_block block_func;
|
node_block block_func;
|
||||||
node_mmap mmap_func;
|
node_mmap mmap_func;
|
||||||
node_ioctl ioctl_func;
|
node_ioctl ioctl_func;
|
||||||
|
node_create create_func;
|
||||||
Node* link;
|
Node* link;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,11 +63,14 @@ namespace VFS
|
|||||||
int do_mkdir(const char* path, const char* name, int uid, int gid, mode_t mode);
|
int do_mkdir(const char* path, const char* name, int uid, int gid, mode_t mode);
|
||||||
int do_mkdir(const char* pathname, int uid, int gid, mode_t mode);
|
int do_mkdir(const char* pathname, int uid, int gid, mode_t mode);
|
||||||
|
|
||||||
|
Result<Node*> create(const char* pathname, mode_t mode, uid_t uid, gid_t gid);
|
||||||
|
|
||||||
int would_block(Node* node);
|
int would_block(Node* node);
|
||||||
|
|
||||||
void mount_root(Node* root);
|
void mount_root(Node* root);
|
||||||
|
|
||||||
Node* resolve_path(const char* filename, Node* root = nullptr);
|
Node* resolve_path(const char* filename, Node* root = nullptr);
|
||||||
|
Node* resolve_parent(const char* filename, Node* root = nullptr);
|
||||||
|
|
||||||
bool exists(const char* pathname);
|
bool exists(const char* pathname);
|
||||||
|
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
|
#define MODULE "tmpfs"
|
||||||
|
|
||||||
#include "fs/TmpFS.h"
|
#include "fs/TmpFS.h"
|
||||||
|
#include "log/Log.h"
|
||||||
|
#include "memory/MemoryManager.h"
|
||||||
|
#include "misc/utils.h"
|
||||||
#include "std/errno.h"
|
#include "std/errno.h"
|
||||||
#include "std/string.h"
|
#include "std/string.h"
|
||||||
#include "utils/Dynamic.h"
|
#include "utils/Dynamic.h"
|
||||||
@ -8,7 +13,7 @@ namespace TmpFS
|
|||||||
{
|
{
|
||||||
struct File
|
struct File
|
||||||
{
|
{
|
||||||
char* ptr;
|
void* ptr;
|
||||||
uint64_t pages;
|
uint64_t pages;
|
||||||
uint64_t length;
|
uint64_t length;
|
||||||
};
|
};
|
||||||
@ -26,9 +31,30 @@ Dynamic<TmpFS::File> tmpfs_files;
|
|||||||
|
|
||||||
extern uint64_t clock_now();
|
extern uint64_t clock_now();
|
||||||
|
|
||||||
|
static bool resize_file(TmpFS::File& file, size_t new_size)
|
||||||
|
{
|
||||||
|
size_t pages = Utilities::get_blocks_from_size(PAGE_SIZE, new_size);
|
||||||
|
if (pages > file.pages) // resize only if we need a bigger chunk of memory
|
||||||
|
{
|
||||||
|
auto rc = MemoryManager::get_pages(pages, MAP_READ_WRITE);
|
||||||
|
if (rc.has_error()) return false;
|
||||||
|
void* new_ptr = rc.release_value();
|
||||||
|
if (file.ptr)
|
||||||
|
{
|
||||||
|
memcpy(new_ptr, file.ptr, file.length);
|
||||||
|
MemoryManager::release_pages(file.ptr, file.pages);
|
||||||
|
}
|
||||||
|
file.pages = pages;
|
||||||
|
file.ptr = new_ptr;
|
||||||
|
}
|
||||||
|
file.length = new_size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
VFS::Node* TmpFS::get()
|
VFS::Node* TmpFS::get()
|
||||||
{
|
{
|
||||||
if (tmpfs_root) return tmpfs_root;
|
if (tmpfs_root) return tmpfs_root;
|
||||||
|
kinfoln("initializing tmpfs instance");
|
||||||
tmpfs_root = new VFS::Node;
|
tmpfs_root = new VFS::Node;
|
||||||
tmpfs_root->length = 0;
|
tmpfs_root->length = 0;
|
||||||
tmpfs_root->inode = 0;
|
tmpfs_root->inode = 0;
|
||||||
@ -36,6 +62,7 @@ VFS::Node* TmpFS::get()
|
|||||||
tmpfs_root->find_func = TmpFS::finddir;
|
tmpfs_root->find_func = TmpFS::finddir;
|
||||||
tmpfs_root->readdir_func = TmpFS::readdir;
|
tmpfs_root->readdir_func = TmpFS::readdir;
|
||||||
tmpfs_root->mkdir_func = TmpFS::mkdir;
|
tmpfs_root->mkdir_func = TmpFS::mkdir;
|
||||||
|
tmpfs_root->create_func = TmpFS::create;
|
||||||
tmpfs_root->mode = 0777;
|
tmpfs_root->mode = 0777;
|
||||||
tmpfs_root->uid = tmpfs_root->gid = 0;
|
tmpfs_root->uid = tmpfs_root->gid = 0;
|
||||||
tmpfs_root->atime = tmpfs_root->ctime = tmpfs_root->mtime = clock_now();
|
tmpfs_root->atime = tmpfs_root->ctime = tmpfs_root->mtime = clock_now();
|
||||||
@ -53,6 +80,7 @@ VFS::Node* TmpFS::finddir(VFS::Node* node, const char* filename)
|
|||||||
if (!node) return nullptr;
|
if (!node) return nullptr;
|
||||||
if (node->inode >= tmpfs_dirs.size()) return nullptr;
|
if (node->inode >= tmpfs_dirs.size()) return nullptr;
|
||||||
auto& dir = tmpfs_dirs[node->inode];
|
auto& dir = tmpfs_dirs[node->inode];
|
||||||
|
kdbgln("searching for '%s' in '%s'", filename, node->name);
|
||||||
for (size_t i = 0; i < dir.files.size(); i++)
|
for (size_t i = 0; i < dir.files.size(); i++)
|
||||||
{
|
{
|
||||||
if (!strncmp(dir.files[i]->name, filename, sizeof(dir.files[i]->name))) return dir.files[i];
|
if (!strncmp(dir.files[i]->name, filename, sizeof(dir.files[i]->name))) return dir.files[i];
|
||||||
@ -67,6 +95,7 @@ VFS::Node* TmpFS::readdir(VFS::Node* node, long offset)
|
|||||||
auto& dir = tmpfs_dirs[node->inode];
|
auto& dir = tmpfs_dirs[node->inode];
|
||||||
if (offset < 0) return nullptr;
|
if (offset < 0) return nullptr;
|
||||||
if ((size_t)offset >= dir.files.size()) return nullptr;
|
if ((size_t)offset >= dir.files.size()) return nullptr;
|
||||||
|
kdbgln("reading offset %ld in '%s'", offset, node->name);
|
||||||
return dir.files[offset];
|
return dir.files[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +109,7 @@ int TmpFS::mkdir(VFS::Node* node, const char* name, mode_t mode)
|
|||||||
new_node->find_func = TmpFS::finddir;
|
new_node->find_func = TmpFS::finddir;
|
||||||
new_node->readdir_func = TmpFS::readdir;
|
new_node->readdir_func = TmpFS::readdir;
|
||||||
new_node->mkdir_func = TmpFS::mkdir;
|
new_node->mkdir_func = TmpFS::mkdir;
|
||||||
|
new_node->create_func = TmpFS::create;
|
||||||
new_node->length = 0;
|
new_node->length = 0;
|
||||||
new_node->type = VFS_DIRECTORY;
|
new_node->type = VFS_DIRECTORY;
|
||||||
new_node->mode = mode;
|
new_node->mode = mode;
|
||||||
@ -93,5 +123,64 @@ int TmpFS::mkdir(VFS::Node* node, const char* name, mode_t mode)
|
|||||||
// object. Thus our changes to the parent would be erased as soon as we exit this function.
|
// object. Thus our changes to the parent would be erased as soon as we exit this function.
|
||||||
ensure(tmpfs_dirs.push({{}})); // FIXME: Handle OOM instead of panicking
|
ensure(tmpfs_dirs.push({{}})); // FIXME: Handle OOM instead of panicking
|
||||||
node->length++;
|
node->length++;
|
||||||
|
kdbgln("created directory '%s' in '%s' (which now has %lu entries), mode %o", name, node->name, node->length, mode);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VFS::Node* TmpFS::create(VFS::Node* node, const char* name, mode_t mode, uid_t uid, gid_t gid)
|
||||||
|
{
|
||||||
|
if (node->inode >= tmpfs_dirs.size()) return nullptr;
|
||||||
|
if (!(node->type & VFS_DIRECTORY)) return nullptr;
|
||||||
|
auto& parent = tmpfs_dirs[node->inode];
|
||||||
|
VFS::Node* new_node = new VFS::Node;
|
||||||
|
new_node->inode = tmpfs_files.size();
|
||||||
|
new_node->length = 0;
|
||||||
|
new_node->read_func = TmpFS::read;
|
||||||
|
new_node->write_func = TmpFS::write;
|
||||||
|
new_node->type = VFS_FILE;
|
||||||
|
new_node->mode = mode;
|
||||||
|
new_node->uid = uid;
|
||||||
|
new_node->gid = gid;
|
||||||
|
new_node->atime = new_node->ctime = new_node->mtime = clock_now();
|
||||||
|
strncpy(new_node->name, name, sizeof(new_node->name));
|
||||||
|
ensure(parent.files.push(
|
||||||
|
new_node)); // We have to push the new node to the parent BEFORE we push the directory object to the list of
|
||||||
|
// tmpfs directories. This is crucial, since pushing to the list of tmpfs directories could relocate
|
||||||
|
// said list, where the parent object is stored, while we would still be using the old parent
|
||||||
|
// object. Thus our changes to the parent would be erased as soon as we exit this function.
|
||||||
|
ensure(tmpfs_files.push({nullptr, 0, 0})); // FIXME: Handle OOM instead of panicking
|
||||||
|
node->length++;
|
||||||
|
kdbgln("created file '%s' in '%s' (which now has %lu entries), mode %o", name, node->name, node->length, mode);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t TmpFS::read(VFS::Node* node, size_t offset, size_t length, char* buffer)
|
||||||
|
{
|
||||||
|
kdbgln("got to read()");
|
||||||
|
if (!node) return -1;
|
||||||
|
if (node->inode >= tmpfs_files.size()) return -1;
|
||||||
|
File& file = tmpfs_files[node->inode];
|
||||||
|
size_t old_len = length;
|
||||||
|
if (offset > file.length) return -1;
|
||||||
|
if (offset + length > file.length) { length = file.length - offset; }
|
||||||
|
kdbgln("reading %zu bytes from '%s' at offset %zu (requested length was %zu)", length, node->name, offset, old_len);
|
||||||
|
memcpy(buffer, (void*)((uintptr_t)file.ptr + offset), length);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t TmpFS::write(VFS::Node* node, size_t offset, size_t length, const char* buffer)
|
||||||
|
{
|
||||||
|
if (!node) return -1;
|
||||||
|
if (node->inode >= tmpfs_files.size()) return -1;
|
||||||
|
File& file = tmpfs_files[node->inode];
|
||||||
|
size_t new_length = file.length;
|
||||||
|
if (offset + length > file.length) new_length = offset + length;
|
||||||
|
if (new_length != file.length)
|
||||||
|
{
|
||||||
|
if (!resize_file(file, new_length)) return -ENOMEM;
|
||||||
|
node->length = new_length;
|
||||||
|
}
|
||||||
|
kdbgln("writing %zu bytes to '%s' at offset %zu", length, node->name, offset);
|
||||||
|
memcpy((void*)((uintptr_t)file.ptr + offset), buffer, length);
|
||||||
|
return length;
|
||||||
}
|
}
|
@ -129,6 +129,14 @@ VFS::Node* VFS::resolve_path(const char* filename, Node* root)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VFS::Node* VFS::resolve_parent(const char* filename, Node* root)
|
||||||
|
{
|
||||||
|
char* dir = better_dirname(filename);
|
||||||
|
auto* result = resolve_path(dir, root);
|
||||||
|
kfree(dir);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int VFS::mkdir(const char* path, const char* name)
|
int VFS::mkdir(const char* path, const char* name)
|
||||||
{
|
{
|
||||||
Node* node = resolve_path(path, vfs_root);
|
Node* node = resolve_path(path, vfs_root);
|
||||||
@ -236,6 +244,38 @@ int VFS::do_mkdir(const char* pathname, int uid, int gid, mode_t mode)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<VFS::Node*> VFS::create(const char* pathname, mode_t mode, uid_t uid, gid_t gid)
|
||||||
|
{
|
||||||
|
VFS::Node* parent = VFS::resolve_parent(pathname);
|
||||||
|
if (!parent) return {ENOENT};
|
||||||
|
if (parent->type != VFS_DIRECTORY)
|
||||||
|
{
|
||||||
|
kwarnln("Attempting to create %s, parent is not a directory", pathname);
|
||||||
|
return {ENOTDIR};
|
||||||
|
}
|
||||||
|
if (!parent->create_func)
|
||||||
|
{
|
||||||
|
kwarnln("Chosen node does not support create()");
|
||||||
|
return {ENOTSUP}; // FIXME: Probably EROFS.
|
||||||
|
}
|
||||||
|
if (!parent->find_func)
|
||||||
|
{
|
||||||
|
kwarnln("Chosen node does not support finddir()");
|
||||||
|
return {ENOTSUP};
|
||||||
|
}
|
||||||
|
if (!can_write(parent, uid, gid)) return {EACCES};
|
||||||
|
char* child = better_basename(pathname);
|
||||||
|
if (parent->find_func(parent, child))
|
||||||
|
{
|
||||||
|
kwarnln("Already exists");
|
||||||
|
kfree(child);
|
||||||
|
return {EEXIST};
|
||||||
|
}
|
||||||
|
VFS::Node* child_node = parent->create_func(parent, child, mode, uid, gid);
|
||||||
|
kfree(child);
|
||||||
|
return child_node;
|
||||||
|
}
|
||||||
|
|
||||||
bool VFS::exists(const char* pathname)
|
bool VFS::exists(const char* pathname)
|
||||||
{
|
{
|
||||||
return resolve_path(pathname) != nullptr;
|
return resolve_path(pathname) != nullptr;
|
||||||
|
@ -115,6 +115,28 @@ static int internal_printf(const char* format, PutString put_string_callback, ss
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'o': {
|
||||||
|
if (is_unsigned_long || is_long)
|
||||||
|
{
|
||||||
|
char result[25];
|
||||||
|
ultoa(va_arg(ap, uint64_t), result, 8);
|
||||||
|
if (buffer_insert_index + strlen(result) > 1024) flush_buffer();
|
||||||
|
memcpy(buffer + buffer_insert_index, result, strlen(result));
|
||||||
|
buffer_insert_index += strlen(result);
|
||||||
|
if (buffer_insert_index == 1024) flush_buffer();
|
||||||
|
is_unsigned_long = is_long = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char result[25];
|
||||||
|
utoa(va_arg(ap, uint32_t), result, 8);
|
||||||
|
if (buffer_insert_index + strlen(result) > 1024) flush_buffer();
|
||||||
|
memcpy(buffer + buffer_insert_index, result, strlen(result));
|
||||||
|
buffer_insert_index += strlen(result);
|
||||||
|
if (buffer_insert_index == 1024) flush_buffer();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'u': {
|
case 'u': {
|
||||||
if (is_unsigned_long || is_long)
|
if (is_unsigned_long || is_long)
|
||||||
{
|
{
|
||||||
|
@ -50,6 +50,8 @@ void sys_fork(Context* context)
|
|||||||
child->gid = parent->gid;
|
child->gid = parent->gid;
|
||||||
child->egid = parent->egid;
|
child->egid = parent->egid;
|
||||||
|
|
||||||
|
child->umask = parent->umask;
|
||||||
|
|
||||||
child->regs.rax = 0;
|
child->regs.rax = 0;
|
||||||
context->rax = child->id;
|
context->rax = child->id;
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ void sys_write(Context* context, int fd, size_t size, const char* addr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_open(Context* context, const char* filename, int flags, mode_t) // FIXME: mode is not used.
|
void sys_open(Context* context, const char* filename, int flags, mode_t mode)
|
||||||
{
|
{
|
||||||
Task* current_task = Scheduler::current_task();
|
Task* current_task = Scheduler::current_task();
|
||||||
int fd = current_task->alloc_fd();
|
int fd = current_task->alloc_fd();
|
||||||
@ -182,9 +182,21 @@ void sys_open(Context* context, const char* filename, int flags, mode_t) // FIXM
|
|||||||
if (!node)
|
if (!node)
|
||||||
{
|
{
|
||||||
bool create = (flags & OPEN_CREATE) > 0;
|
bool create = (flags & OPEN_CREATE) > 0;
|
||||||
if (create) kwarnln("FIXME: open(O_CREAT) is not implemented");
|
if (create)
|
||||||
|
{
|
||||||
|
mode = mode & (~current_task->umask);
|
||||||
|
auto rc = VFS::create(kfilename, mode, current_task->euid, current_task->egid);
|
||||||
|
if (rc.has_error()) context->rax = -rc.error();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
kinfoln("Created file %s with mode %o, uid %d and gid %d", kfilename, mode, current_task->euid,
|
||||||
|
current_task->egid);
|
||||||
|
node = rc.release_value();
|
||||||
|
goto do_open;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { context->rax = -ENOENT; }
|
||||||
kfree(kfilename);
|
kfree(kfilename);
|
||||||
context->rax = -ENOENT;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -199,6 +211,8 @@ void sys_open(Context* context, const char* filename, int flags, mode_t) // FIXM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_open:
|
||||||
|
|
||||||
bool can_read = (flags & OPEN_READ) > 0;
|
bool can_read = (flags & OPEN_READ) > 0;
|
||||||
bool can_write = (flags & OPEN_WRITE) > 0;
|
bool can_write = (flags & OPEN_WRITE) > 0;
|
||||||
if (!can_read && !can_write)
|
if (!can_read && !can_write)
|
||||||
@ -210,7 +224,7 @@ void sys_open(Context* context, const char* filename, int flags, mode_t) // FIXM
|
|||||||
|
|
||||||
if (can_read && !VFS::can_read(node, current_task->euid, current_task->egid))
|
if (can_read && !VFS::can_read(node, current_task->euid, current_task->egid))
|
||||||
{
|
{
|
||||||
kwarnln("open failed because process with uid %d and gid %d couldn't open file %s with mode %d for reading",
|
kwarnln("open failed because process with uid %d and gid %d couldn't open file %s with mode %o for reading",
|
||||||
current_task->euid, current_task->egid, kfilename, node->mode);
|
current_task->euid, current_task->egid, kfilename, node->mode);
|
||||||
kfree(kfilename);
|
kfree(kfilename);
|
||||||
context->rax = -EACCES;
|
context->rax = -EACCES;
|
||||||
@ -219,7 +233,7 @@ void sys_open(Context* context, const char* filename, int flags, mode_t) // FIXM
|
|||||||
|
|
||||||
if (can_write && !VFS::can_write(node, current_task->euid, current_task->egid))
|
if (can_write && !VFS::can_write(node, current_task->euid, current_task->egid))
|
||||||
{
|
{
|
||||||
kwarnln("open failed because process with uid %d and gid %d couldn't open file %s with mode %d for writing",
|
kwarnln("open failed because process with uid %d and gid %d couldn't open file %s with mode %o for writing",
|
||||||
current_task->euid, current_task->egid, kfilename, node->mode);
|
current_task->euid, current_task->egid, kfilename, node->mode);
|
||||||
kfree(kfilename);
|
kfree(kfilename);
|
||||||
context->rax = -EACCES;
|
context->rax = -EACCES;
|
||||||
|
@ -198,6 +198,7 @@ long Scheduler::load_user_task(const char* filename)
|
|||||||
new_task->user_task = true;
|
new_task->user_task = true;
|
||||||
new_task->regs.rip = image->entry;
|
new_task->regs.rip = image->entry;
|
||||||
new_task->image = image;
|
new_task->image = image;
|
||||||
|
new_task->umask = 0;
|
||||||
new_task->allocated_stack = (uint64_t)MemoryManager::get_pages_at(0x100000, TASK_PAGES_IN_STACK,
|
new_task->allocated_stack = (uint64_t)MemoryManager::get_pages_at(0x100000, TASK_PAGES_IN_STACK,
|
||||||
MAP_READ_WRITE | MAP_USER | MAP_AS_OWNED_BY_TASK)
|
MAP_READ_WRITE | MAP_USER | MAP_AS_OWNED_BY_TASK)
|
||||||
.release_value(); // FIXME: Propagate errors.
|
.release_value(); // FIXME: Propagate errors.
|
||||||
|
Loading…
Reference in New Issue
Block a user