Quick and dirty file api

This commit is contained in:
flysand7 2023-07-28 00:49:53 +11:00
parent dbd10db051
commit 5e177fae50
8 changed files with 162 additions and 33 deletions

View File

@ -123,10 +123,8 @@ try:
ciabatta_header.write('\n')
ciabatta_header.write('// This file is AUTO-GENERATED by library.json\n')
ciabatta_header.write('\n')
# Write includes
for include in library_config['includes']:
ciabatta_header.write(f'#include <{include}>\n')
ciabatta_header.write('\n')
# Write main include
ciabatta_header.write('#include <cia-def.h>\n')
# Write platform includes
platform_config = None
for platform in library_config['platforms']:
@ -138,10 +136,14 @@ try:
include_path = os.path.join(platform_config['path'], include)
ciabatta_header.write(f'#include "{include_path}"\n')
ciabatta_header.write(f'#include "{target}/tinyrt-iface.h"\n')
ciabatta_header.write(f'#include "tinyrt.h"\n')
ciabatta_header.write(f'#include <tinyrt.h>\n')
for tinyrt_source in platform_config['tinyrt']:
ciabatta_header.write(f'#include "{target}/{tinyrt_source}"\n')
# Write API includes
# Write module includes
for include in library_config['includes']:
ciabatta_header.write(f'#include <{include}>\n')
ciabatta_header.write('\n')
# Write module sources
ciabatta_header.write('\n')
for api in library_config['apis']:
api_name = api['name']

25
include/stdio.h Normal file
View File

@ -0,0 +1,25 @@
#pragma once
#include <cia-def.h>
#include <tinyrt.h>
typedef u64 size_t;
typedef struct FILE FILE;
struct FILE {
_RT_File rt_file;
};
#define EOF (-1)
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
FILE *fopen(const char *restrict filename, const char *restrict mode);
int fgetc(FILE *file);
int fputc(int c, FILE *file);
size_t fread(void *restrict buf, size_t size, size_t count, FILE *restrict file);
size_t fwrite(void const *restrict buf, size_t size, size_t count, FILE *restrict file);
int fclose(FILE *file);

View File

@ -50,16 +50,20 @@ static _RT_Status _rt_deinit();
#endif
// File API
#if _RT_API_FILE == 1
struct _RT_File typedef _RT_File;
struct _RT_File {
union {
void *handle;
u64 fd;
};
i32 flags;
struct _RT_File typedef _RT_File;
struct _RT_File {
union {
void *handle;
u64 fd;
};
static _RT_Status _rt_file_open(_RT_File *file, char *name, int flags);
i32 flags;
};
#if _RT_API_FILE == 1
static _RT_File _rt_file_stdin;
static _RT_File _rt_file_stdout;
static _RT_File _rt_file_stderr;
static _RT_Status _rt_file_std_handles_init();
static _RT_Status _rt_file_open(_RT_File *file, char const *name, int flags);
static _RT_Status _rt_file_read(u64 size, void *buffer, _RT_File *from, u64 *out_bytes_read);
static _RT_Status _rt_file_write(_RT_File *to, u64 size, void *buffer, u64 *out_bytes_written);
static _RT_Status _rt_file_close(_RT_File *file);

View File

@ -0,0 +1,85 @@
FILE *stdin;
FILE *stdout;
FILE *stderr;
// TODO: memory allocation
static FILE _files[64];
static int _files_cnt = 0;
static void _fileapi_init() {
_rt_file_std_handles_init();
stdin = &_files[_files_cnt++];
stdin->rt_file = _rt_file_stdin;
stdout = &_files[_files_cnt++];
stdout->rt_file = _rt_file_stdout;
stderr = &_files[_files_cnt++];
stderr->rt_file = _rt_file_stderr;
}
FILE *fopen(char const *restrict filename, char const *restrict mode) {
_RT_File rt_file;
int flags = 0;
while(*mode) {
if(*mode == 'r') flags |= _RT_FILE_READ;
if(*mode == 'w') flags |= _RT_FILE_WRITE;
// TODO: other flags
mode += 1;
}
_RT_Status status = _rt_file_open(&rt_file, filename, flags);
if(status != _RT_STATUS_OK) {
return NULL;
}
FILE *file = &_files[_files_cnt];
_files_cnt += 1;
file->rt_file = rt_file;
return file;
}
int fgetc(FILE *file) {
int c = 0;
u64 bytes_read;
_RT_Status status = _rt_file_read(1, &c, &file->rt_file, &bytes_read);
if(status == _RT_STATUS_FILE_EOF) {
return EOF;
}
else if(status != _RT_STATUS_OK) {
return EOF;
}
return c;
}
int fputc(int c, FILE *file) {
u64 bytes_written;
_RT_Status status = _rt_file_write(&file->rt_file, 1, &c, &bytes_written);
if(status != _RT_STATUS_OK) {
return EOF;
}
return c;
}
size_t fread(void *restrict buf, size_t size, size_t count, FILE *restrict file) {
u64 bytes_read;
_RT_Status status = _rt_file_read(size*count, buf, &file->rt_file, &bytes_read);
if(status != _RT_STATUS_OK) {
return 0;
}
return bytes_read / size;
}
size_t fwrite(void const *restrict buf, size_t size, size_t count, FILE *restrict file) {
u64 bytes_written;
_RT_Status status = _rt_file_write(&file->rt_file, size*count, (void *)buf, &bytes_written);
if(status != _RT_STATUS_OK) {
return 0;
}
return bytes_written / size;
}
int fclose(FILE *file) {
_RT_Status status = _rt_file_close(&file->rt_file);
if(status != _RT_STATUS_OK) {
return EOF;
}
return 0;
}

View File

@ -24,8 +24,8 @@
// this module will not be included in the final build
includes: [
"cia-def.h",
"stdlib.h"
"stdlib.h",
"stdio.h",
],
platforms: [
@ -60,6 +60,16 @@ apis: [
"rt_api_program",
]
},
{
name: "stdlib_file",
path: "impl/stdlib-file",
includes: [
"file.c"
],
reqs: [
"rt_api_file"
]
}
]
// END

View File

@ -10,6 +10,8 @@ void __stack_chk_fail(void) {
syscall_exit(1);
}
static void _fileapi_init();
void __libc_start_main(
int (*main)(int, char**, char**),
int argc, char **argv,
@ -21,6 +23,7 @@ void __libc_start_main(
// Get the envp
char **envp = argv + (argc + 1);
init(argc, argv, envp);
_fileapi_init();
main(argc, argv, envp);
fini();
// glibc bug

View File

@ -1,7 +1,20 @@
// See src/tinyrt.h file for the interface this file implements
static _RT_Status _rt_file_open(_RT_File *file, char *name, int _rt_flags) {
static _RT_File _rt_file_stdin;
static _RT_File _rt_file_stderr;
static _RT_Status _rt_file_std_handles_init() {
_rt_file_stdin.fd = 0;
_rt_file_stdin.flags = _RT_FILE_READ;
_rt_file_stdout.fd = 1;
_rt_file_stdout.flags = _RT_FILE_WRITE;
_rt_file_stderr.fd = 2;
_rt_file_stdout.flags = _RT_FILE_WRITE;
return _RT_STATUS_OK;
}
static _RT_Status _rt_file_open(_RT_File *file, char const *name, int _rt_flags) {
if((_rt_flags & 0x3) == 0) {
return _RT_ERROR_BAD_PARAM;
}

View File

@ -1,22 +1,9 @@
#include <cia-def.h>
#define STDOUT_FILENO 1
#define SYS_write 1
static __inline i64 __syscall3(i64 n, i64 a1, i64 a2, i64 a3) {
i64 ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
"d"(a3) : "rcx", "r11", "memory");
return ret;
}
static inline i64 syscall_write(u32 fd, char const *buf, u64 count) {
return __syscall3(SYS_write, (i64)fd, (i64)buf, (u64)count);
}
#include <stdio.h>
int main(int argc, char **argv, char **envp) {
char string[] = "Hello, world!\n";
syscall_write(STDOUT_FILENO, string, sizeof string);
fwrite(string, 1, sizeof string-1, stdout);
return 0;
}