libc: Implement fopen, fclose, fread, feof, ferror, and clearerr
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
apio 2023-03-12 10:23:08 +01:00
parent c0a7f6776f
commit 5c0104111d
Signed by: apio
GPG Key ID: B8A7D06E42258954
2 changed files with 86 additions and 4 deletions

View File

@ -8,10 +8,13 @@
typedef struct
{
int __unused;
int _fd;
int _err;
int _eof;
} FILE;
#define SEEK_SET 0
#define EOF -1
extern FILE* stderr;
#define stderr stderr
@ -23,15 +26,29 @@ extern "C"
int fflush(FILE*);
FILE* fopen(const char*, const char*);
int fclose(FILE*);
/* Opens a file and binds a stream to it. */
FILE* fopen(const char* path, const char* mode);
/* Closes a file and frees up its stream. */
int fclose(FILE* stream);
/* Reads arbitrarily sized items from a stream. */
size_t fread(void* buf, size_t size, size_t nmemb, FILE* stream);
size_t fread(void*, size_t, size_t, FILE*);
size_t fwrite(const void*, size_t, size_t, FILE*);
int fseek(FILE*, long, int);
long ftell(FILE*);
/* Returns whether the error indicator was set in stream. */
int ferror(FILE* stream);
/* Returns whether the end-of-file indicator was set in stream. */
int feof(FILE* stream);
/* Clears the error and end-of-file indicators in stream. */
void clearerr(FILE* stream);
void setbuf(FILE*, char*);
int fprintf(FILE*, const char*, ...);

View File

@ -1,7 +1,9 @@
#define _LUNA_SYSTEM_ERROR_EXTENSIONS
#include <bits/errno-return.h>
#include <fcntl.h>
#include <luna/Format.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>
@ -16,6 +18,69 @@ extern "C"
__errno_return(rc, int);
}
FILE* fopen(const char* path, const char*)
{
// FIXME: Parse the mode string.
int fd = open(path, 0);
if (fd < 0) return nullptr;
FILE* f = (FILE*)malloc(sizeof(FILE));
if (!f)
{
close(fd);
return nullptr;
}
f->_fd = fd;
clearerr(f);
return f;
}
int fclose(FILE* stream)
{
if (close(stream->_fd) < 0) return EOF;
free(stream);
return 0;
}
size_t fread(void* buf, size_t size, size_t nmemb, FILE* stream)
{
if (size * nmemb == 0) return 0;
ssize_t nread = read(stream->_fd, buf, size * nmemb);
if (nread < 0)
{
stream->_err = 1;
return 0;
}
else if (nread == 0)
{
stream->_eof = 1;
return 0;
}
else
return (size_t)nread / size;
}
int ferror(FILE* stream)
{
return stream->_err;
}
int feof(FILE* stream)
{
return stream->_eof;
}
void clearerr(FILE* stream)
{
stream->_eof = stream->_err = 0;
}
int vsnprintf(char* buf, size_t max, const char* format, va_list ap)
{
return (int)vstring_format(buf, max, format, ap);