CeDOS - Commit 54eeaed5

Implemented lseek and tell, improved stdio
Celina Sophie Kalus
Fri, 24 Nov 2023 00:11:41 +0100
10 files changed, 161 insertions(+), 20 deletions(-)
M include/cedos/fat.hinclude/cedos/fat.h

@@ -10,6 +10,7 @@ int FAT_dir_next(file_t *file, int index, char *fname_buffer);

int FAT_openat(file_t *root, file_t *handle, const char *fname, int flags); uint32_t FAT_read(file_t *file, uint8_t *buffer, uint32_t count); off_t FAT_lseek(file_t *file, off_t offset, int whence); +off_t FAT_tell(file_t *file); extern file_operations_t FAT_fops;
M include/cedos/file.hinclude/cedos/file.h

@@ -23,6 +23,7 @@ file_operations_t *fops;

uint32_t stdio_id; uint32_t fat_cluster; fpos_t pos; + size_t size; }; struct file_operations {

@@ -32,6 +33,7 @@ int (*read)(file_t *file, char *buffer, uint32_t size);

int (*write)(file_t *file, char *buffer, uint32_t size); int (*dir_next)(file_t *file, int index, char *fname_buffer); off_t (*lseek)(file_t *file, off_t offset, int whence); + off_t (*tell)(file_t *file); }; int file_init();

@@ -39,6 +41,7 @@ int file_open(const char *pathname, int flags);

int file_openat(int fd, const char *fname, int flags); int file_read(int fd, char *buffer, uint32_t size); off_t file_lseek(int fd, off_t offset, int whence); +off_t file_tell(int fd); int file_write(int fd, char *buffer, uint32_t size); int file_dir_next(int fd, int index, char *fname_buffer);
M src/kernel/fat.csrc/kernel/fat.c

@@ -13,7 +13,8 @@ FAT_openat, /* openat */

FAT_read, /* read */ NULL, /* write */ FAT_dir_next, /* dir_next */ - FAT_lseek /* lseek */ + FAT_lseek, /* lseek */ + FAT_tell /* tell */ }; typedef struct {

@@ -222,6 +223,7 @@

if (strcmp(buffer, fname) == 0) { // file found handle->pos = 0; + handle->size = file_size; handle->fops = &FAT_fops; handle->fat_cluster = first_cluster; return 0;

@@ -232,10 +234,15 @@

uint32_t FAT_read(file_t *file, uint8_t *buffer, uint32_t count) { uint16_t cluster = file->fat_cluster; fpos_t offset = file->pos; + size_t file_size = file->size; uint32_t size = 0; uint32_t cluster_size = boot_sect->bytes_per_sect * boot_sect->sect_per_cluster; uint8_t *cluster_buffer = os_kernel_malloc(cluster_size); + + if (offset + count > file_size) { + count = file_size - offset; + } while (offset >= cluster_size) { cluster = FAT_next_cluster(cluster);

@@ -280,4 +287,8 @@ // to be implemented

} else { kpanic("Wrong whence!"); } +} + +off_t FAT_tell(file_t *file) { + return file->pos; }
M src/kernel/file.csrc/kernel/file.c

@@ -91,7 +91,7 @@ file_t *file = get_process_local_file(fd);

if (file->fops->read == NULL) { return -1; } - file->fops->read(file, buffer, size); + return file->fops->read(file, buffer, size); } int file_write(int fd, char *buffer, uint32_t size) {

@@ -116,4 +116,12 @@

if (file->fops->lseek == NULL) { return -1; } return file->fops->lseek(file, offset, whence); +} + +off_t file_tell(int fd) { + file_t *file = get_process_local_file(fd); + + if (file->fops->tell == NULL) { return -1; } + + return file->fops->tell(file); }
M src/kernel/syscall.csrc/kernel/syscall.c

@@ -18,7 +18,9 @@ sched_wait,

file_open, graphics_set_mode, hard_reset, - file_dir_next + file_dir_next, + file_lseek, + file_tell }; extern void syscall_interrupt(void);
M src/libcedos/cedos.csrc/libcedos/cedos.c

@@ -32,6 +32,18 @@ interrupt(0x30, res, 1, fd, buffer, size);

return res; } +int sc_file_lseek(int fd, uint32_t offset, int whence) { + volatile uint32_t res = 0; + interrupt(0x30, res, 10, fd, offset, whence); + return res; +} + +int sc_file_tell(int fd) { + volatile uint32_t res = 0; + interrupt(0x30, res, 11, fd, 0, 0); + return res; +} + int process_spawn(const char *fname, const char *args) { volatile uint32_t res = 0; interrupt(0x30, res, 4, fname, args, 0);
M src/libcedos/include/cedos.hsrc/libcedos/include/cedos.h

@@ -17,6 +17,8 @@

int sc_file_read(int fd, char *buffer, uint32_t size); int sc_file_write(int fd, char *buffer, uint32_t size); int sc_file_open(char *buffer, uint32_t flags); +int sc_file_lseek(int fd, uint32_t offset, int whence); +int sc_file_tell(int fd); void hard_reset();
M src/libcedos/include/stdio.hsrc/libcedos/include/stdio.h

@@ -1,6 +1,36 @@

#ifndef STDIO_H #define STDIO_H +#include <stdarg.h> +#include <stddef.h> +typedef struct { int unused; } FILE; + +#define stdin (FILE*)(0) +#define stdout (FILE*)(1) +#define stderr (FILE*)(1) + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +#define EOF (-1) + +FILE* fopen(const char*, const char*); + +int fputc ( int character, FILE * stream ); +int fputs ( const char * str, FILE * stream ); + +int fgetc ( FILE * stream ); +char * fgets ( char * str, int num, FILE * stream ); + +size_t fread(void*, size_t, size_t, FILE*); +size_t fwrite(const void*, size_t, size_t, FILE*); + +int sprintf ( char * str, const char * format, ... ); +int fprintf(FILE*, const char*, ...); int printf(const char *fmt, ...); + +int fseek(FILE*, long, int); +long ftell(FILE*); #endif
M src/libcedos/stdio.csrc/libcedos/stdio.c

@@ -7,13 +7,82 @@

char user_numeric[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; char user_hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; +FILE* fopen(const char* filename, const char* mode) { + return (FILE*)(sc_file_open(filename, NULL)); +} + +size_t fread(void* buffer, size_t size, size_t count, FILE* file) { + return sc_file_read((int)(file), buffer, size * count); +} + +size_t fwrite(const void* buffer, size_t size, size_t count, FILE* file) { + return sc_file_write((int)(file), buffer, size * count); +} + +int fputc ( int character, FILE * stream ) { + int retval; + char c = character; + retval = fwrite(&c, 1, 1, stream); + + if (retval == 1) { + return (int)(c); + } else { + return EOF; + } +} + +int fgetc ( FILE * stream ) { + int retval; + char c = 0; + retval = fread(&c, 1, 1, stream); + + if (retval == 1) { + return (int)(c); + } else { + return EOF; + } +} + +int fputs ( const char * str, FILE * stream ) { + int i = 0; + + while (str[i] != 0 && str[i] != '\n') { i++; } + + fwrite(str, 1, i, stream); + + return i; +} + +char * fgets ( char * str, int num, FILE * stream ) { + int i = 0; + + while (i < num) { + str[i] = fgetc(stream); + if (str[i] == '\n' || str[i] == EOF) { break; } + i++; + } + + return i + 1; +} + +int sprintf ( char * str, const char * format, ... ); +int fprintf(FILE*, const char*, ...); +int printf(const char *fmt, ...); + +int fseek(FILE*, long, int); +long ftell(FILE*); + int print(char *buffer, int num) { - return sc_file_write(0, buffer, num); + return fwrite(buffer, sizeof(char), num, stdout); } int read_char(char *buffer, int num) { return sc_file_read(1, buffer, num); +} + +void print_char(char c) { + print(&c, 1); } /*void print_hex_char(uint8_t c) {

@@ -103,10 +172,6 @@ int size = sprint_hex_char(c, buffer);

print(buffer, size); } -void print_char(char c) { - print(&c, 1); -} - int printf(const char *fmt, ...) { va_list args; va_start(args, fmt);

@@ -142,4 +207,13 @@ }

fmt++; } -}+} + +int fprintf(FILE*, const char*, ...); +FILE* fopen(const char*, const char*); + +int fseek(FILE*, long, int); +long ftell(FILE*); + +size_t fread(void*, size_t, size_t, FILE*); +size_t fwrite(const void*, size_t, size_t, FILE*);
M src/shell/cat.csrc/shell/cat.c

@@ -3,23 +3,21 @@ #include "stdio.h"

#include <stdint.h> +#define BUFFER_SIZE 1024 + void main(char *args) { - int fd = sc_file_open(args, 0); + FILE* file = fopen(args, "r"); - if (fd < 0) { + if (file == NULL) { printf("Could not find file: %s\n", args); return; } - char *buffer = (void*)(0x2000000); - - int size = sc_file_read(fd, buffer, -1); + char buffer[BUFFER_SIZE]; - while (size > 0) { - int chunk = 256; - if (size < chunk) { chunk = size; } - sc_file_write(0, buffer, chunk); - size -= chunk; - buffer += chunk; + while (1) { + int size = fread(buffer, 1, 1024, file); + if (size == 0) { break; } + fwrite(buffer, 1, size, stdout); } }