Add open system call

This commit is contained in:
Baptiste Wicht 2014-02-12 17:13:34 +01:00
parent b73a863ed9
commit 4193ba0ffa
9 changed files with 156 additions and 3 deletions

View File

@ -36,6 +36,8 @@ void reschedule();
void sleep_ms(pid_t pid, size_t time);
size_t register_new_handle(const std::string& path);
} //end of namespace scheduler
#endif

19
kernel/include/vfs.hpp Normal file
View File

@ -0,0 +1,19 @@
//=======================================================================
// Copyright Baptiste Wicht 2013-2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#ifndef VFS_H
#define VFS_H
//TODO Once userspace is done, integrate parts of disks.hpp here
namespace vfs {
int64_t open(const char* file);
} //end of namespace vfs
#endif

View File

@ -40,6 +40,7 @@ struct process_control_t {
scheduler::process_state state;
size_t rounds;
size_t sleep_timeout;
std::vector<std::string> handles;
};
//The Process Control Block
@ -129,7 +130,11 @@ void gc_task(){
desc.context = nullptr;
desc.brk_start = desc.brk_end = 0;
//8. Release the PCB slot
//8 Clean file handles
//TODO If not empty, probably something should be done
process.handles.clear();
//9. Release the PCB slot
process.state = scheduler::process_state::EMPTY;
}
}
@ -803,6 +808,12 @@ void scheduler::sleep_ms(pid_t pid, size_t time){
reschedule();
}
size_t scheduler::register_new_handle(const std::string& path){
pcb[current_pid].handles.push_back(path);
return pcb[current_pid].handles.size() - 1;
}
//Provided for task_switch.s
extern "C" {

View File

@ -11,6 +11,7 @@
#include "keyboard.hpp"
#include "terminal.hpp"
#include "acpi.hpp"
#include "vfs.hpp"
namespace {
@ -102,6 +103,12 @@ void sc_shutdown(interrupt::syscall_regs*){
acpi::shutdown();
}
void sc_open(interrupt::syscall_regs* regs){
auto file = reinterpret_cast<char*>(regs->rbx);
regs->rax = vfs::open(file);
}
} //End of anonymous namespace
void system_call_entry(interrupt::syscall_regs* regs){
@ -164,6 +171,10 @@ void system_call_entry(interrupt::syscall_regs* regs){
sc_shutdown(regs);
break;
case 300:
sc_open(regs);
break;
case 0x666:
//TODO Do something with return code
scheduler::kill_current_process();

58
kernel/src/vfs.cpp Normal file
View File

@ -0,0 +1,58 @@
//=======================================================================
// Copyright Baptiste Wicht 2013-2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#include <errors.hpp>
#include <string.hpp>
#include <algorithms.hpp>
#include "vfs.hpp"
#include "scheduler.hpp"
#include "fat32.hpp"
#include "disks.hpp"
int64_t vfs::open(const char* file_path){
if(!disks::mounted_partition() || !disks::mounted_disk()){
return -std::ERROR_NOTHING_MOUNTED;
}
std::string file(file_path);
if(file.empty()){
return -std::ERROR_INVALID_FILE_PATH;
}
if(file[0] != '/'){
return -std::ERROR_INVALID_FILE_PATH;
}
auto parts = std::split(file, '/');
if(parts.empty()){
return -std::ERROR_INVALID_FILE_PATH;
}
auto last = parts.back();
parts.pop_back();
//TODO file search should be done entirely by the file system
auto files = fat32::ls(*disks::mounted_disk(), *disks::mounted_partition(), parts);
for(auto& f : files){
if(f.file_name == file){
if(f.directory){
return -std::ERROR_DIRECTORY;
}
return scheduler::register_new_handle(file);
}
}
return -std::ERROR_NOT_EXISTS;
}

View File

@ -8,11 +8,18 @@
#ifndef ERRORS_H
#define ERRORS_H
#include <types.hpp>
//TODO Rename this namespace
namespace std {
//TODO Use an enum
constexpr const size_t ERROR_NOT_EXISTS = 1;
constexpr const size_t ERROR_NOT_EXECUTABLE = 2;
constexpr const size_t ERROR_FAILED_EXECUTION = 3;
constexpr const size_t ERROR_NOTHING_MOUNTED = 4;
constexpr const size_t ERROR_INVALID_FILE_PATH = 5;
constexpr const size_t ERROR_DIRECTORY = 6;
inline const char* error_message(size_t error){
switch(error){
@ -22,6 +29,12 @@ inline const char* error_message(size_t error){
return "The file is not an executable";
case ERROR_FAILED_EXECUTION:
return "Execution failed";
case ERROR_NOTHING_MOUNTED:
return "Nothing is mounted";
case ERROR_INVALID_FILE_PATH:
return "The file path is not valid";
case ERROR_DIRECTORY:
return "The file is a directory";
default:
return "Unknonwn error";
}

17
tlib/include/file.hpp Normal file
View File

@ -0,0 +1,17 @@
//=======================================================================
// Copyright Baptiste Wicht 2013-2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#ifndef USER_SYSTEM_HPP
#define USER_SYSTEM_HPP
#include <types.hpp>
#include <expected.hpp>
#include <string.hpp>
std::expected<size_t> open(const char* file);
#endif

22
tlib/src/file.cpp Normal file
View File

@ -0,0 +1,22 @@
//=======================================================================
// Copyright Baptiste Wicht 2013-2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#include <file.hpp>
std::expected<size_t> open(const char* file){
int64_t fd;
asm volatile("mov rax, 300; mov rbx, %[path]; int 50; mov %[fd], rax"
: [fd] "=m" (fd)
: [path] "g" (reinterpret_cast<size_t>(file))
: "rax", "rbx");
if(fd < 0){
return std::make_expected_from_error<size_t, size_t>(-fd);
} else {
return std::make_expected<size_t>(fd);
}
}

View File

@ -332,13 +332,13 @@ size_t digits(N number){
}
template<typename Char>
std::vector<std::basic_string<Char>> split(const std::basic_string<Char>& s){
std::vector<std::basic_string<Char>> split(const std::basic_string<Char>& s, char sep = ' '){
std::vector<std::basic_string<Char>> parts;
std::basic_string<Char> current(s.size());
for(char c : s){
if(c == ' ' && !current.empty()){
if(c == sep && !current.empty()){
parts.push_back(current);
current.clear();
} else {