SayoriOS  0.3.3
file_descriptors.c
1 //
2 // Created by maractus on 03.01.24.
3 //
4 
5 // NOTE: They needed for userspace apps!
6 
7 #include "sys/file_descriptors.h"
8 #include "../src/lib/libvector/include/vector.h"
9 #include "mem/vmm.h"
10 #include "io/ports.h"
11 
12 vector_t* descriptors = 0;
13 int last_descriptor_number = 0;
14 
15 void file_descriptors_init() {
16  descriptors = vector_new();
17 
18  qemu_log("File descriptors initialized");
19 }
20 
21 // WARNING: Part of system calls! So every func needs to return size_t
22 size_t file_descriptor_allocate(const char *filename, size_t mode, int *out) {
23  FILE* file = fopen_binmode(filename, mode);
24 
25  if(!file) {
26  *out = -1;
27  return 0;
28  }
29 
30  struct fd_info* inf = kcalloc(sizeof *inf, 1);
31 
32  inf->fd = last_descriptor_number++;
33  inf->file = file;
34 
35  vector_push_back(descriptors, (size_t) inf);
36 
37  *out = inf->fd;
38 
39  qemu_ok("Written to: %d", out);
40  qemu_log("allocated fd: %d", inf->fd);
41 
42  return 0;
43 }
44 
45 struct fd_info* file_descriptor_get(int descriptor_number) {
46  for(int i = 0; i < descriptors->size; i++) {
47  struct fd_info *inf = (struct fd_info *) vector_get(descriptors, i).element;
48 
49  if (inf->fd == descriptor_number) {
50  return inf;
51  }
52  }
53 
54  return NULL;
55 }
56 
57 size_t file_descriptor_read(int descriptor_number, size_t count, void* buffer) {
58  qemu_log("FD: %d; Size: %d; Buffer: %x", descriptor_number, count, buffer);
59 
60  if(descriptor_number < 0 || descriptor_number >= last_descriptor_number) {
61  qemu_err("Invalid descriptor: %d!", descriptor_number);
62  return 0;
63  }
64 
65  if(!file_descriptor_get(descriptor_number)) {
66  return 0;
67  }
68 
69  struct fd_info* inf = file_descriptor_get(descriptor_number);
70 
71  qemu_note("[%x] Read: %d bytes (buffer at: %x)", inf, count, buffer);
72 
73  fread(inf->file, count, 1, buffer);
74 
75  qemu_note("Read finished!");
76 
77  qemu_log("%s\n", buffer);
78 
79  return 0;
80 }
81 
82 size_t file_descriptor_write(int descriptor_number, size_t count, const void* buffer) {
83  qemu_log("FD: %d; Size: %d; Buffer: %x", descriptor_number, count, buffer);
84 
85  if(descriptor_number < 0 || descriptor_number >= last_descriptor_number) {
86  qemu_err("Invalid descriptor: %d!", descriptor_number);
87  return 0;
88  }
89 
90  if(!file_descriptor_get(descriptor_number)) {
91  return 0;
92  }
93 
94  struct fd_info* inf = file_descriptor_get(descriptor_number);
95 
96  qemu_note("[%x] Write: %d bytes (buffer at: %x)", inf, count, buffer);
97 
98  fwrite(inf->file, count, 1, buffer);
99 
100  return 0;
101 }
102 
103 size_t file_descriptor_close(int descriptor_number) {
104  if(descriptor_number < 0 || descriptor_number >= last_descriptor_number)
105  return 0;
106 
107  for(int i = 0; i < descriptors->size; i++) {
108  struct fd_info *inf = (struct fd_info *) vector_get(descriptors, i).element;
109 
110  if (inf->fd == descriptor_number) {
111  fclose(inf->file);
112 
113  vector_erase_nth(descriptors, i);
114 
115  kfree(inf);
116 
117  qemu_ok("Destroyed: %d", descriptor_number);
118 
119  return 0;
120  }
121  }
122 
123  qemu_err("FAILED TO DESTROY fd: %d", descriptor_number);
124 
125  return 0;
126 }
127 
128 size_t file_descriptor_seek(int descriptor_number, ssize_t value, size_t whence) {
129  /*if(descriptor_number < 0 || descriptor_number >= last_descriptor_number)
130  return;
131 
132  for(int i = 0; i < descriptors->size; i++) {
133  struct fd_info *inf = (struct fd_info *) vector_get(descriptors, i).element;
134 
135  if (inf->fd == descriptor_number) {
136  fseek(inf->file, value, whence);
137 
138  return;
139  }
140  }*/
141 
142  if(descriptor_number < 0 || descriptor_number >= last_descriptor_number) {
143  qemu_err("Invalid descriptor: %d!", descriptor_number);
144  return 0;
145  }
146 
147  if(!file_descriptor_get(descriptor_number)) {
148  return 0;
149  }
150 
151  struct fd_info* inf = file_descriptor_get(descriptor_number);
152 
153  qemu_note("[%x] Seek: Value: %x; Whence: %x", inf, value, whence);
154 
155  fseek(inf->file, value, whence);
156 
157  return 0;
158 
159 }
160 
161 size_t file_descriptor_tell(int descriptor_number, int* out) {
162  if(descriptor_number < 0 || descriptor_number >= last_descriptor_number) {
163  return 0;
164  }
165 
166  if(!file_descriptor_get(descriptor_number)) {
167  return 0;
168  }
169 
170  struct fd_info* inf = file_descriptor_get(descriptor_number);
171 
172  *out = ftell(inf->file);
173 
174  return 0;
175 }
uint32_t mode
Режим работы (0 - Обычный | 1 - Режим логирования)
Definition: bootscreen.c:23
ssize_t fseek(FILE *stream, ssize_t offset, uint8_t whence)
Установка позиции в потоке данных относительно текущей позиции
Definition: stdio.c:315
void fclose(FILE *stream)
Закончить работу с файлом
Definition: stdio.c:213
size_t fwrite(FILE *stream, size_t size, size_t count, const void *ptr)
Запись файла
Definition: stdio.c:381
int ftell(FILE *stream)
Текущая позиция считывания в файле
Definition: stdio.c:287
int fread(FILE *stream, size_t count, size_t size, void *buffer)
Чтение файла
Definition: stdio.c:250
Структура файла. Требуется для работы с VFS.
Definition: stdio.h:21
Definition: vector.h:7