Complete procfs

This commit is contained in:
Baptiste Wicht 2016-08-07 18:13:02 +02:00
parent 9248ee3750
commit ae41dbfa8c
2 changed files with 135 additions and 9 deletions

View File

@ -27,6 +27,10 @@ struct file {
//File system specific
size_t location;
size_t position;
file(){};
file(std::string file_name, bool directory, bool hidden, bool system, uint64_t size)
: file_name(file_name), directory(directory), hidden(hidden), system(system), size(size) {};
};
} //end of namespace vfs

View File

@ -13,11 +13,63 @@
#include "fs/procfs.hpp"
#include "scheduler.hpp"
#include "logging.hpp"
namespace {
const scheduler::process_control_t* pcb = nullptr;
std::vector<vfs::file> standard_contents;
//TODO Move into tstl
uint64_t atoui(const std::string& s){
uint64_t value = 0;
uint64_t mul = 1;
for(size_t i = s.size(); i > 0; --i){
auto c = s[i - 1];
if(c < '0' || c > '9'){
return value;
}
value += mul * (c - '0');
mul *= 10;
}
return value;
}
size_t read(const std::string& value, char* buffer, size_t count, size_t offset, size_t& read){
if(offset > value.size()){
return std::ERROR_INVALID_OFFSET;
}
read = std::min(count, value.size() - offset);
std::copy_n(buffer, value.c_str() + offset, read);
return 0;
}
std::string get_value(uint64_t pid, const std::string& name){
auto& process = pcb[pid];
if(name == "pid"){
return std::to_string(process.process.pid);
} else if(name == "ppid"){
return std::to_string(process.process.ppid);
} else if(name == "state"){
return std::to_string(static_cast<uint8_t>(process.state));
} else if(name == "system"){
return process.process.system ? "true" : "false";
} else if(name == "priority"){
return std::to_string(process.process.priority);
} else {
return "";
}
}
} //end of anonymous namespace
void procfs::set_pcb(const scheduler::process_control_t* pcb_ptr){
@ -25,7 +77,11 @@ void procfs::set_pcb(const scheduler::process_control_t* pcb_ptr){
}
procfs::procfs_file_system::procfs_file_system(std::string mp) : mount_point(mp) {
//Nothing to init
standard_contents.emplace_back("pid", false, false, false, 0);
standard_contents.emplace_back("ppid", false, false, false, 0);
standard_contents.emplace_back("state", false, false, false, 0);
standard_contents.emplace_back("system", false, false, false, 0);
standard_contents.emplace_back("priority", false, false, false, 0);
}
procfs::procfs_file_system::~procfs_file_system(){
@ -33,6 +89,7 @@ procfs::procfs_file_system::~procfs_file_system(){
}
size_t procfs::procfs_file_system::get_file(const std::vector<std::string>& file_path, vfs::file& f){
// Access the root folder
if(file_path.empty()){
f.file_name = "/";
f.directory = true;
@ -43,23 +100,85 @@ size_t procfs::procfs_file_system::get_file(const std::vector<std::string>& file
return 0;
}
if(file_path.size() == 1){
//TODO
auto i = atoui(file_path[0]);
// Check the pid folder
if(i >= scheduler::MAX_PROCESS){
return std::ERROR_NOT_EXISTS;
}
auto& process = pcb[i];
if(process.state == scheduler::process_state::EMPTY){
return std::ERROR_NOT_EXISTS;
}
// Access a pid folder
if(file_path.size() == 1){
f.file_name = file_path[0];
f.directory = true;
f.hidden = false;
f.system = false;
f.size = 0;
return 0;
}
// Access a file directly
if(file_path.size() == 2){
auto value = get_value(i, file_path[1]);
if(value.size()){
f.file_name = file_path[1];
f.directory = false;
f.hidden = false;
f.system = false;
f.size = value.size();
return 0;
} else {
return std::ERROR_NOT_EXISTS;
}
}
// There are no more levels
return std::ERROR_NOT_EXISTS;
}
size_t procfs::procfs_file_system::read(const std::vector<std::string>& file_path, char* buffer, size_t count, size_t offset, size_t& read){
//Cannot access the root for reading
//Cannot access the root nor the pid directores for reading
if(file_path.size() < 2){
return std::ERROR_PERMISSION_DENIED;
}
if(file_path.size() == 2){
auto i = atoui(file_path[0]);
if(i >= scheduler::MAX_PROCESS){
return std::ERROR_NOT_EXISTS;
}
auto& process = pcb[i];
if(process.state == scheduler::process_state::EMPTY){
return std::ERROR_NOT_EXISTS;
}
auto value = get_value(i, file_path[1]);
if(value.size()){
return ::read(value, buffer, count, offset, read);
} else {
return std::ERROR_NOT_EXISTS;
}
}
return std::ERROR_NOT_EXISTS;
}
size_t procfs::procfs_file_system::ls(const std::vector<std::string>& file_path, std::vector<vfs::file>& contents){
logging::logf(logging::log_level::DEBUG, "procfs ls %u\n", file_path.size());
if(file_path.size() == 0){
for(size_t i = 0; i < scheduler::MAX_PROCESS; ++i){
auto& process = pcb[i];
@ -67,23 +186,26 @@ size_t procfs::procfs_file_system::ls(const std::vector<std::string>& file_path,
if(process.state != scheduler::process_state::EMPTY){
vfs::file f;
f.file_name = std::to_string(process.process.pid);
f.directory = false;
f.directory = true;
f.hidden = false;
f.system = false;
f.size = 0;
contents.emplace_back(std::move(f));
}
}
}
//No subfolder support
if(file_path.size() > 0){
return std::ERROR_NOT_EXISTS;
}
return 0;
}
if(file_path.size() == 1){
contents = standard_contents;
return 0;
}
//No more subfolder support
return std::ERROR_NOT_EXISTS;
}
size_t procfs::procfs_file_system::statfs(statfs_info& file){
file.total_size = 0;
file.free_size = 0;