Compare commits

...

10 Commits

17 changed files with 226 additions and 65 deletions

View File

@ -8,13 +8,13 @@ This code is experimental. Lots of things don't work, lots of it is really bad.
Make sure you have the prerequisits to build gcc, binutils and newlib, and NASM.
sudo apt-get install build-essential libgmp3-dev libmpfr-dev libisl-dev libmpc-dev texinfo nasm git wget make g++ libtool-bin pkg-config
sudo apt-get install build-essential libgmp3-dev libmpfr-dev libisl-dev libmpc-dev texinfo nasm git wget make g++ libtool-bin pkg-config flex bison m4
Download the latest toolchain builder script. This will download the source, compiler, binutils and newlib into a directory called Quinn in your home directory.
https://gitlab.com/apamment/quinn-os/-/raw/master/make_toolchain.sh
https://quinn.zapto.org/gitea/apamment/quinn-os/raw/branch/master/make_toolchain.sh
Once the toolchain has been downloaded, it will also set your path to include:
Once the toolchain has been downloaded, you will need to set your path to include:
$HOME/Quinn/cross/bin

View File

@ -78,6 +78,7 @@ uint8_t rshift;
char *cursor_save_buffer;
int cursor_save_x;
int cursor_save_y;
int cons_win_serialno = -1;
static const char keyChars_set1[] = {0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y',
'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\',
@ -202,7 +203,7 @@ void init_console() {
cursor_save_x = -1;
cursor_save_y = -1;
gui_convert_xpm(console_xpm, &con_icon);
gui_add_window(consolebuffer, "Console", 10, 35, cons_w, cons_h, con_icon, 0, console_input);
cons_win_serialno = gui_add_window(consolebuffer, "Console", 10, 35, cons_w, cons_h, con_icon, 0, console_input);
dbfree(con_icon, "init_console 2");
console_display_quinn();
@ -251,6 +252,10 @@ void putpixel_24bpp(int x, int y, uint32_t color) {
consolebuffer[where + 1] = (color >> 8) & 255; // GREEN
consolebuffer[where + 2] = (color >> 16) & 255; // RED
consolebuffer[where + 3] = (color >> 24) & 255; // ALPHA
if (cons_win_serialno != -1) {
gui_mark_window_dirty(cons_win_serialno);
}
}
void clear_screen(void) {
@ -306,6 +311,7 @@ void scroll_up(void) {
cursor_save_y--;
}
update_cursor(1);
}
void draw_char(uint32_t x, uint32_t y, char c) {
@ -892,5 +898,8 @@ void update_cursor(int restore) {
consolebuffer[where + 3] = 0xff; // RED
}
}
if (cons_win_serialno != -1) {
gui_mark_window_dirty(cons_win_serialno);
}
}
}

135
gui.c
View File

@ -71,8 +71,13 @@ uint8_t *minimizebtn = NULL;
uint8_t *closebtn = NULL;
uint8_t *wallpaper = NULL;
uint8_t all_dirty = 1;
struct ptr_vector vwindows;
int last_mouse_pos_x = 0;
int last_mouse_pos_y = 0;
int last_mouse_vis = 1;
extern int mouse_pos_x;
extern int mouse_pos_y;
@ -96,6 +101,7 @@ static void gui_window_set_focus(struct window_t *win) {
for (int i = 0; i < ptr_vector_len(&vwindows); i++) {
struct window_t *fwin = (struct window_t *)ptr_vector_get(&vwindows, i);
if (fwin->focused) {
fwin->dirty = 1;
fwin->focused = 0;
fwin->mytask->priority -= 10;
if (fwin->mytask->priority < 1) {
@ -106,8 +112,49 @@ static void gui_window_set_focus(struct window_t *win) {
win->mytask->priority += 10;
win->focused = 1;
win->dirty = 1;
}
struct rect_t {
int x, y, width, height;
};
#define MAX_DIRTY_RECTS 100
struct rect_t dirty_rects[MAX_DIRTY_RECTS];
int dirty_rect_count = 0;
void mark_dirty(int x, int y, int w, int h) {
static float percentage_dirty = 0;
if (all_dirty == 1) {
return; // No need to mark dirty if all is dirty
}
for (int i = 0; i < dirty_rect_count; i++) {
struct rect_t *rect = &dirty_rects[i];
if (x >= rect->x && x + w <= rect->x + rect->width && y >= rect->y && y + h <= rect->y + rect->height) {
return; // Already marked as dirty
}
}
if (dirty_rect_count == 0) {
percentage_dirty = 0;
}
percentage_dirty += (w * h) / (width * height);
if (percentage_dirty > 0.75) {
// if more than 75% of the screen is dirty, just mark it all dirty
dirty_rect_count = 0;
all_dirty = 1;
return;
}
if (dirty_rect_count < MAX_DIRTY_RECTS) {
dirty_rects[dirty_rect_count++] = (struct rect_t){x, y, w, h};
}
}
void init_gui(multiboot_info_t *mbinfo) {
if (mbinfo->flags & 1 << 11) {
serialnos = 0;
@ -310,8 +357,6 @@ void gui_convert_xpm(char **xpm, uint8_t **buffer) {
dbfree(theKeys, "gui convert xpm 7");
}
void gui_display_pointer() { render(backbuffer, mouseptr, 32, 32, mouse_pos_x, mouse_pos_y, width, height, 4); }
void gui_draw_char(uint8_t *buffer, uint32_t dest_width, uint32_t dest_height, uint32_t x, uint32_t y, char c, uint32_t colour) {
int cx, cy;
// int mask[8]={1,2,4,8,16,32,64,128};
@ -373,6 +418,7 @@ int gui_change_window_caption(int serialno, char *cap) {
for (i = 0; i < ptr_vector_len(&vwindows); i++) {
if (((struct window_t *)ptr_vector_get(&vwindows, i))->serialno == serialno) {
strncpy(((struct window_t *)ptr_vector_get(&vwindows, i))->name, cap, 128);
((struct window_t *)ptr_vector_get(&vwindows, i))->dirty = 1;
return 0;
}
}
@ -399,6 +445,7 @@ int gui_add_window(uint8_t *contents, char *name, int x, int y, int w, int h, ui
new_window->event_msg_count = 0;
new_window->focused = 0;
new_window->mytask = current_task;
new_window->dirty = 1;
if (contents == NULL) {
new_window->contents = (uint8_t *)dbmalloc(w * h * depth, "gui add window malloc 2");
@ -440,6 +487,15 @@ int gui_add_window(uint8_t *contents, char *name, int x, int y, int w, int h, ui
return new_window->serialno;
}
void gui_mark_window_dirty(int serialno) {
for (int j = 0; j < ptr_vector_len(&vwindows); j++) {
if (((struct window_t *)ptr_vector_get(&vwindows, j))->serialno == serialno) {
((struct window_t *)ptr_vector_get(&vwindows, j))->dirty = 1;
return;
}
}
}
void gui_destroy_window_syscall(int serialno) {
for (int j = 0; j < ptr_vector_len(&current_task->window_list); j++) {
if (((struct window_t *)ptr_vector_get(&current_task->window_list, j))->serialno == serialno) {
@ -473,10 +529,11 @@ void gui_destroy_window(int serialno) {
} else {
keyboard_set_handler(NULL);
}
all_dirty = 1;
dbfree(win->icon, "gui destroy window 1");
dbfree(win->contents, "gui destroy window 2");
dbfree(win, "gui destroy window 3");
return;
}
}
@ -544,6 +601,7 @@ int gui_blit(int wh, int x, int y, int w, int h, uint8_t *bmp) {
}
render(win->contents, bmp, w, h, x, y, win->width, win->height, 4);
win->dirty = 1;
return 1;
}
@ -679,6 +737,7 @@ void gui_proc_input() {
mouse_last_over->drag_start_x = mouse_pos_x;
mouse_last_over->drag_start_y = mouse_pos_y;
}
all_dirty = 1;
return;
}
} else {
@ -782,6 +841,7 @@ void gui_proc_input() {
return;
} else if (mouse_pos_x > mouse_over->posx + mouse_over->width - 25) {
mouse_over->minimized = 1;
all_dirty = 1;
if (mouse_over->iconx == 0 && mouse_over->icony == 0) {
gui_find_icon_space(mouse_over);
}
@ -859,6 +919,7 @@ void gui_proc_input() {
if (win->minimized) {
if (mouse_pos_x > win->iconx - 16 && mouse_pos_x < win->iconx + 72 && mouse_pos_y > win->icony - 16 && mouse_pos_y < win->icony + 72) {
win->minimized = 0;
all_dirty = 1;
gui_raise_to_top(i);
return;
}
@ -877,15 +938,19 @@ void gui_draw() {
} else {
render(backbuffer, wallpaper, 1024, 768, 0, 0, width, height, 4);
}
// draw icons
for (i = 0; i < ptr_vector_len(&vwindows); i++) {
struct window_t *win = (struct window_t *)ptr_vector_get(&vwindows, i);
if (win->minimized == 1) {
render(backbuffer, win->icon, 64, 64, win->iconx, win->icony, width, height, 4);
fill_rect(backbuffer, width, height, (48 - (strlen(win->name) * 8 / 2)) + (win->iconx - 16), win->icony + 74, strlen(win->name) * 8, 16,
sys_color.icon_title);
draw_text(backbuffer, width, height, (48 - (strlen(win->name) * 8 / 2)) + (win->iconx - 16), win->icony + 74, sys_color.icon_title_text, win->name);
if (win->dirty) {
mark_dirty((48 - (strlen(win->name) * 8 / 2)) + (win->iconx - 16) < win->iconx ? (48 - (strlen(win->name) * 8 / 2)) + (win->iconx - 16) : win->iconx, win->icony, strlen(win->name) * 8, 90);
win->dirty = 0;
}
}
}
@ -897,8 +962,18 @@ void gui_draw() {
if (!(win->flags & WIN_REQ_FLAG_NO_TITLE)) {
fill_rect(backbuffer, width, height, win->posx - 1, win->posy - 26, win->width + 2, win->height + 27, 0);
gui_drawtitlebar(backbuffer, width, height, win, win->focused);
if (win->dirty) {
mark_dirty(win->posx - 1, win->posy - 26, win->width + 2, win->height + 27);
win->dirty = 0;
}
} else {
fill_rect(backbuffer, width, height, win->posx - 1, win->posy - 1, win->width + 2, win->height + 2, 0);
if (win->dirty) {
mark_dirty(win->posx - 1, win->posy - 1, win->width + 2, win->height + 2);
win->dirty = 0;
}
}
render(backbuffer, win->contents, win->width, win->height, win->posx, win->posy, width, height, depth);
}
@ -921,9 +996,21 @@ void gui_draw_mouse() {
}
}
}
if (mouse_visible) {
gui_display_pointer();
int current_x = mouse_pos_x;
int current_y = mouse_pos_y;
if (last_mouse_vis) {
mark_dirty(last_mouse_pos_x, last_mouse_pos_y, 32, 32);
}
if (mouse_visible) {
mark_dirty(current_x, current_y, 32, 32);
render(backbuffer, mouseptr, 32, 32, current_x, current_y, width, height, 4);
last_mouse_vis = 1;
} else {
last_mouse_vis = 0;
}
last_mouse_pos_x = current_x;
last_mouse_pos_y = current_y;
}
void gui_flip() {
@ -931,7 +1018,40 @@ void gui_flip() {
gui_draw();
gui_draw_mouse();
memcpy(framebuffer, backbuffer, bytesPerLine * height);
if (all_dirty) {
all_dirty = 0;
dirty_rect_count = 0;
memcpy(framebuffer, backbuffer, bytesPerLine * height);
return;
}
// Update only the dirty regions of the screen
for (int i = 0; i < dirty_rect_count; i++) {
struct rect_t *rect = &dirty_rects[i];
if (rect->x < 0) {
rect->x = 0;
}
if (rect->y < 0) {
rect->y = 0;
}
if (rect->x + rect->width > width) {
rect->width = width - rect->x;
}
if (rect->y + rect->height > height) {
rect->height = height - rect->y;
}
if (rect->width <= 0 || rect->height <= 0) {
continue;
}
for (int y = rect->y; y < rect->y + rect->height; y++) {
memcpy(framebuffer + y * bytesPerLine + rect->x * depth,
backbuffer + y * bytesPerLine + rect->x * depth,
rect->width * depth);
}
}
// Clear dirty rectangles after updating
dirty_rect_count = 0;
}
static uint32_t blendPreMulAlpha(uint32_t p1, uint32_t p2) {
@ -1041,6 +1161,7 @@ int gui_set_wallpaper(char *data, int len) {
memcpy(wallpaper, data, len);
wallpaper_lock = 0;
all_dirty = 1;
return 1;
}

2
gui.h
View File

@ -54,6 +54,7 @@ struct window_t {
uint8_t rclick;
uint8_t mclick;
struct task_t *mytask;
uint8_t dirty;
};
extern void init_gui(multiboot_info_t *mbinfo);
@ -71,4 +72,5 @@ extern int gui_set_colour(struct gui_colour_scheme_t *colourscheme);
extern int gui_change_window_caption(int serialno, char *cap);
extern void gui_display_halt();
extern void gui_convert_xpm(char **xpm, uint8_t **buffer);
extern void gui_mark_window_dirty(int serialno);
#endif

View File

@ -266,9 +266,9 @@ static void i825xx_isr(struct regs *r) {
if (icr & ICR_TXD_LOW) {
icr &= ~(ICR_TXD_LOW);
}
if (icr)
kprintf("i825xx: unhandled interrupt received! (0x%p)\n", icr);
if (icr) {
// kprintf("i825xx: unhandled interrupt received! (0x%p)\n", icr);
}
mmio_read(i825xx_device, REG_ICR);
// mmio_write(i825xx_device, REG_IMS, ICR_RXSEQ | ICR_RXT | ICR_RXDMT | ICR_LSC | ICR_RXO);
}
@ -314,7 +314,7 @@ uint8_t i825xx_detect_eeprom(struct i825xx_device_t *net_dev) {
return eeprom_exists;
}
uint16_t e1000_dev_ids[] = {0x100e, 0x153a, 0x10ea};
uint16_t e1000_dev_ids[] = {0x100e, 0x153a, 0x10ea, 0x10d3};
struct ether_t *init_i825xx(int count) {
struct pci_device *pci_dev;
@ -323,7 +323,7 @@ struct ether_t *init_i825xx(int count) {
uint32_t i;
uint8_t found = 0;
for (int d = 0; d < 3; d++) {
for (int d = 0; d < 4; d++) {
if (pci_find_device_by_vendor(0x8086, e1000_dev_ids[d], &pci_dev, count)) {
found = 1;
break;

View File

@ -26,7 +26,7 @@ wget http://ftp.gnu.org/gnu/grub/grub-2.06.tar.xz
echo "Fetching Quinn"
cd $HOME/Quinn/src
git clone https://gitlab.com/apamment/quinn-os
git clone https://quinn.zapto.org/gitea/apamment/quinn-os.git
cd $HOME/Quinn/tools
echo "Building Tools"

View File

@ -16,7 +16,7 @@ print(@" <h3>About the webserver</h3>
<p>
Quinn is a hobby operating system for 32-bit x86 computers.
If you would like to learn more about Quinn, see:
<a href=""https://gitlab.com/apamment/quinn-os/"">https://gitlab.com/apamment/quinn-os/</a>
<a href=""https://quinn.zapto.org/"">https://quinn.zapto.org/</a>
</p>
")

View File

@ -1,7 +1,7 @@
#!/bin/bash
if [ ! -e SDL ]
then
git clone https://gitlab.com/apamment/quinn-sdl.git SDL
git clone https://quinn.zapto.org/gitea/apamment/quinn-sdl SDL
fi
cd SDL

View File

@ -6,7 +6,7 @@ fi
if [ ! -e doomgeneric ]
then
git clone https://gitlab.com/apamment/doomgeneric
git clone https://quinn.zapto.org/gitea/apamment/doomgeneric.git
fi
cd doomgeneric/doomgeneric

View File

@ -6,7 +6,7 @@ fi
if [ ! -e frotz-2.43d ]
then
git clone https://gitlab.com/apamment/frotz-2.43d
git clone https://quinn.zapto.org/gitea/apamment/frotz.git frotz-2.43d
patch -p0 < frotz-2.43d-quinn.diff
fi

View File

@ -6,7 +6,7 @@ fi
if [ ! -e my_basic ]
then
git clone https://gitlab.com/apamment/my_basic
git clone https://quinn.zapto.org/gitea/apamment/my-basic.git my_basic
fi
cd my_basic

View File

@ -6,7 +6,7 @@ fi
if [ ! -e editor ]
then
git clone https://gitlab.com/apamment/editor
git clone https://quinn.zapto.org/gitea/apamment/editor
fi
cd editor

View File

@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "quinn.h"
#include "convertxpm.h"
#include "clock.xpm"
@ -34,6 +35,9 @@ int main(int argc, char **argv) {
int window_handle;
int close_req = 0;
struct widget_t *surf;
int sleep_cntr = 0;
quinn_init();
convert_xpm(clockicon_xpm, &icon);
@ -57,20 +61,25 @@ int main(int argc, char **argv) {
surface = quinn_surface_get_surface(surf);
while (1) {
thetime = time(NULL);
time_tm = localtime(&thetime);
usleep(100000);
if (time_tm->tm_min != lastminute) {
if (sleep_cntr == 0) {
thetime = time(NULL);
time_tm = localtime(&thetime);
if (time_tm->tm_min != lastminute) {
quinn_render(window_handle, surface, bmp, 250, 250, 0, 0, 250, 250);
quinn_draw_line(window_handle, surface, 125, 125, (150 * cos(arg_sec * time_tm->tm_min - PI / 2) * 0.6) + 125, (150 * sin(arg_sec * time_tm->tm_min - PI / 2) * 0.6) + 125, 250, 250, 0xffff0000);
quinn_draw_line(window_handle, surface, 125, 125, (150 * cos(arg_hour * time_tm->tm_hour - PI / 2 + arg_min * time_tm->tm_min) * 0.3) + 125, (150 * sin(arg_hour * time_tm->tm_hour - PI / 2 + arg_min * time_tm->tm_min) * 0.3) + 125, 250, 250, 0xff0000ff);
lastminute = time_tm->tm_min;
quinn_render(window_handle, surface, bmp, 250, 250, 0, 0, 250, 250);
quinn_draw_line(window_handle, surface, 125, 125, (150 * cos(arg_sec * time_tm->tm_min - PI / 2) * 0.6) + 125, (150 * sin(arg_sec * time_tm->tm_min - PI / 2) * 0.6) + 125, 250, 250, 0xffff0000);
quinn_draw_line(window_handle, surface, 125, 125, (150 * cos(arg_hour * time_tm->tm_hour - PI / 2 + arg_min * time_tm->tm_min) * 0.3) + 125, (150 * sin(arg_hour * time_tm->tm_hour - PI / 2 + arg_min * time_tm->tm_min) * 0.3) + 125, 250, 250, 0xff0000ff);
lastminute = time_tm->tm_min;
}
sleep_cntr = 100;
} else {
sleep_cntr--;
}
if (!quinn_process(0)) {
quinn_yield();
}
quinn_process(0);
}
free(icon);
free(bmp);

View File

@ -2,6 +2,7 @@
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include "meminfo.xpm"
#include "quinn.h"
#include "convertxpm.h"
@ -111,16 +112,15 @@ void end_task(void *data) {
int main(int argc, char **argv) {
struct window_req_t *req;
int window_handle;
unsigned int lastsec;
struct mem_info mem;
char string[512];
unsigned char *icon;
time_t thetime;
int ret;
struct tm *time_tm;
unsigned char *surface;
unsigned char values[150];
int cntr = 0;
int slcntr = 0;
int task_cntr = 0;
struct widget_t *surfw;
quinn_init();
@ -148,7 +148,6 @@ int main(int argc, char **argv) {
surfw = quinn_add_surface(window_handle, 0, 20, 150, 150, NULL, NULL, NULL, NULL);
surface = quinn_surface_get_surface(surfw);
lastsec = 0;
task_list_box = quinn_add_listbox(window_handle, 155, 20, 280, 150, task_list_box_cb);
quinn_set_font(task_list_box, "disk0:/fonts/DejaVuSansMono.ttf");
@ -157,10 +156,9 @@ int main(int argc, char **argv) {
}
while (1) {
thetime = time(NULL);
time_tm = localtime(&thetime);
usleep(100000);
if (time_tm->tm_sec != lastsec) {
if (slcntr == 0) {
__asm__ volatile ("int $0x30" : "=a" (ret) : "0" (36), "b" (&mem));
values[cntr] = (unsigned char)((double)mem.used / (double)mem.total * 150.);
@ -174,7 +172,6 @@ int main(int argc, char **argv) {
quinn_draw_line(window_handle, surface, i-1, 150 - values[i-1], i, 150 - values[i], 150, 150, 0xffff0000);
}
lastsec = time_tm->tm_sec;
cntr++;
if (cntr == 150) {
memmove(&values[0], &values[1], 149);
@ -186,11 +183,11 @@ int main(int argc, char **argv) {
} else {
task_cntr--;
}
slcntr = 10;
} else {
slcntr--;
}
if (!quinn_process(0)) {
quinn_yield();
}
quinn_process(0);
}
}

View File

@ -170,6 +170,8 @@ void sched_remove_socket_from_all_tasks(struct socket_t *s) {
}
}
extern void vfs_close_file_on(struct task_t *task, int fno);
void sched_free_task(struct task_t *this_task) {
int i;
struct task_t *task;
@ -205,12 +207,19 @@ void sched_free_task(struct task_t *this_task) {
destroy_ptr_vector(&this_task->sockets);
while (ptr_vector_len(&this_task->window_list)) {
struct window_t *w = (struct window_t *)ptr_vector_del(&this_task->window_list, 0);
gui_destroy_window(w->serialno);
}
destroy_ptr_vector(&this_task->window_list);
}
for (int i = 0; i < 256; i++) {
if (this_task->filehandles[i].free == 0) {
vfs_close_file_on(this_task, i);
}
}
// threads have seperate stacks...
stack_free((char *)(this_task->kstack - KRNL_STACK_SIZE));

55
vfs.c
View File

@ -367,22 +367,23 @@ int vfs_read_file(int fileno, char *buffer, int len) {
return -1;
}
void vfs_close_file(int fno) {
void vfs_close_file_on(struct task_t *task, int fno) {
if (fno < 0 || fno >= 256) {
return;
}
if (current_task->filehandles[fno].free == 1) {
if (task->filehandles[fno].free == 1) {
return;
}
if (current_task->filehandles[fno].device == NULL) {
if (strcmp(current_task->filehandles[fno].filepath, "PIPE") == 0) {
struct quinn_pipe_t *pipe = (struct quinn_pipe_t *)current_task->filehandles[fno].fs_specific;
if (task->filehandles[fno].device == NULL) {
if (strcmp(task->filehandles[fno].filepath, "PIPE") == 0) {
struct quinn_pipe_t *pipe = (struct quinn_pipe_t *)task->filehandles[fno].fs_specific;
pipe->ref--;
if (pipe->ref == 0) {
if (pipe->ref == 0) {
for (int i = 0; i < vfs_pipe_count; i++) {
if (vfs_pipes[i] == pipe) {
for (int j = i; j < vfs_pipe_count - 1; j++) {
@ -396,35 +397,43 @@ void vfs_close_file(int fno) {
} else {
vfs_pipes = (struct quinn_pipe_t **)dbrealloc(vfs_pipes, sizeof(struct quinn_pipe_t *) * vfs_pipe_count, "pipe close");
}
if (pipe->buffer_size > 0) {
dbfree(pipe->buffer, "pipe close 1");
}
dbfree(pipe, "pipe close 3");
break;
}
}
}
task->filehandles[fno].free = 1;
free(task->filehandles[fno].filepath);
task->filehandles[fno].device = NULL;
return;
}
} else {
switch (current_task->filehandles[fno].device->fs) {
switch (task->filehandles[fno].device->fs) {
case 0:
current_task->filehandles[fno].free = 1;
current_task->filehandles[fno].info->ref--;
if (current_task->filehandles[fno].info->ref == 0) {
free(current_task->filehandles[fno].info);
task->filehandles[fno].free = 1;
task->filehandles[fno].info->ref--;
if (task->filehandles[fno].info->ref == 0) {
free(task->filehandles[fno].info);
}
free(current_task->filehandles[fno].filepath);
current_task->filehandles[fno].device = NULL;
free(task->filehandles[fno].filepath);
task->filehandles[fno].device = NULL;
break;
case 3:
if ((current_task->filehandles[fno].device->device & 0xff00) == 0x100) {
hd_sync(current_task->filehandles[fno].device->device & 0xff);
if ((task->filehandles[fno].device->device & 0xff00) == 0x100) {
hd_sync(task->filehandles[fno].device->device & 0xff);
}
current_task->filehandles[fno].info->ref--;
if (current_task->filehandles[fno].info->ref == 0) {
free(current_task->filehandles[fno].info);
task->filehandles[fno].info->ref--;
if (task->filehandles[fno].info->ref == 0) {
free(task->filehandles[fno].info);
}
free(current_task->filehandles[fno].filepath);
free(current_task->filehandles[fno].fs_specific);
current_task->filehandles[fno].free = 1;
free(task->filehandles[fno].filepath);
free(task->filehandles[fno].fs_specific);
task->filehandles[fno].free = 1;
break;
default:
break;
@ -432,6 +441,10 @@ void vfs_close_file(int fno) {
}
}
void vfs_close_file(int fno) {
vfs_close_file_on(current_task, fno);
}
void vfs_close_all() {
int i;
for (i = 0; i < 256; i++) {

1
vfs.h
View File

@ -88,6 +88,7 @@ extern void init_vfs(void);
extern struct vfs_device_t *vfs_register_device(uint32_t device, char *name, uint8_t fstype);
extern uint8_t vfs_select_device(char *name);
extern void vfs_close_file(int fno);
extern int vfs_open_file(char *path, int flags, int mode);
extern int vfs_read_file(int fileno, char *buffer, int len);
extern int vfs_write_file(int fileno, char *buffer, int len);