1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::io::{Read, Write, Seek, SeekFrom};
use std::path::PathBuf;
use crate::filesystem::*;

pub struct Process {
    open_files: HashMap<FileDescriptor, OpenFile>,
    fds: FileDescriptor,
}

impl Process {
    pub fn new() -> Self {
        Self {
            open_files: HashMap::new(),
            fds: 0,
        }
    }

    pub fn open(&mut self, fs: &mut FileSystem, inode: Inode) -> Result<FileDescriptor, ()> {
        for (&fd, open_file) in self.open_files.iter() {
            if open_file.file.inode == inode {
                // File is already open, return the existing FileDescriptor
                return Ok(fd);
            }
        }

        // If the file is not open, check if it exists in the filesystem
        if let Some(file) = fs.files.get(&inode) {
            let fd = self.fds;
            self.open_files.insert(
                fd,
                OpenFile {
                    file: Arc::clone(file),
                    position: 0,
                },
            );
            self.fds += 1;
            return Ok(fd);
        }

        // If the inode is not provided or the file doesn't exist, create a new file
        let new_inode = fs.create_file(vec![]);
        let new_file = fs.files.get(&new_inode).ok_or(())?;
        let new_fd = self.fds;
        self.open_files.insert(
            new_fd,
            OpenFile {
                file: Arc::clone(new_file),
                position: 0,
            },
        );
        self.fds += 1;
        Ok(new_fd)
}


    pub fn read(&mut self, fd: FileDescriptor, buf: &mut [u8]) -> Result<usize, ()> {
        let open_file = self.open_files.get_mut(&fd).ok_or(())?;
        open_file.read(buf).map_err(|_| ())
    }

    pub fn write(&mut self, fd: FileDescriptor, buf: &[u8]) -> Result<usize, ()> {
       let open_file = self.open_files.get_mut(&fd).ok_or(())?;
       open_file.write(buf).map_err(|_| ())
    }

    pub fn close(&mut self, fd: FileDescriptor) -> Result<(), ()> {
        if self.open_files.remove(&fd).is_some() {
            Ok(())
        } else {
            Err(())
        }
    }
}