libc: Implement ferror() and feof()

This commit is contained in:
apio 2022-10-11 16:57:08 +02:00
parent d25e8a43db
commit 6c51477197
3 changed files with 33 additions and 20 deletions

View File

@ -36,19 +36,13 @@ int main()
if (!config) if (!config)
{ {
perror("fopen"); perror("fopen");
// return 1; return 1;
} }
char buf[4096]; char buf[4096];
size_t nread = fread(buf, sizeof(buf), 1, config); size_t nread = fread(buf, sizeof(buf), 1, config);
if (nread == 0 && errno != 0) // FIXME: looks like our only way of checking whether a zero-read is an error or eof if (ferror(config)) { perror("fread"); }
// right now is checking errno, since fread() does not differentiate between the two,
// and feof() and ferror() are not yet implemented
{
perror("fread");
// return 1;
}
else else
{ {
buf[nread] = 0; buf[nread] = 0;
@ -58,11 +52,7 @@ int main()
printf("%s", buf); printf("%s", buf);
} }
if (fclose(config) < 0) if (fclose(config) < 0) { perror("fclose"); }
{
perror("fclose");
// return 1;
}
printf("\n\nPress any key to restart.\n"); printf("\n\nPress any key to restart.\n");

View File

@ -8,7 +8,9 @@
typedef struct typedef struct
{ {
int fd; int f_fd;
int f_eof;
int f_err;
} FILE; } FILE;
#ifdef __cplusplus #ifdef __cplusplus
@ -26,6 +28,9 @@ extern "C"
int fseek(FILE*, long, int); int fseek(FILE*, long, int);
long ftell(FILE*); long ftell(FILE*);
size_t fwrite(const void*, size_t, size_t, FILE*); size_t fwrite(const void*, size_t, size_t, FILE*);
int ferror(FILE*);
int feof(FILE*);
void clearerr(FILE*);
void setbuf(FILE*, char*); void setbuf(FILE*, char*);
int vfprintf(FILE*, const char*, va_list); int vfprintf(FILE*, const char*, va_list);
int printf(const char*, ...); int printf(const char*, ...);

View File

@ -9,7 +9,7 @@ extern "C"
{ {
int fclose(FILE* stream) int fclose(FILE* stream)
{ {
int status = close(stream->fd); int status = close(stream->f_fd);
if (status < 0) if (status < 0)
{ {
int savederr = errno; int savederr = errno;
@ -32,20 +32,38 @@ extern "C"
int fd = open(pathname, O_RDONLY); // FIXME: Use the mode string. int fd = open(pathname, O_RDONLY); // FIXME: Use the mode string.
if (fd < 0) { return 0; } if (fd < 0) { return 0; }
FILE* stream = (FILE*)malloc(sizeof(FILE)); FILE* stream = (FILE*)malloc(sizeof(FILE));
stream->fd = fd; stream->f_fd = fd;
clearerr(stream);
return stream; return stream;
} }
size_t fread(void* buf, size_t size, size_t nmemb, FILE* stream) size_t fread(void* buf, size_t size, size_t nmemb, FILE* stream)
{ {
ssize_t status = read(stream->fd, buf, size * nmemb); ssize_t status = read(stream->f_fd, buf, size * nmemb);
if (status < 0) if (status < 0)
return 0; // FIXME: The manual says that fread() does not differentiate between EOF and error, and that {
// ferror() and feof() should be called to determine such. So right now, we just mask the error, stream->f_err = 1;
// until that is implemented. return 0;
}
if (status == 0) stream->f_eof = 1;
return (size_t)status; return (size_t)status;
} }
int ferror(FILE* stream)
{
return stream->f_err;
}
int feof(FILE* stream)
{
return stream->f_eof;
}
void clearerr(FILE* stream)
{
stream->f_err = stream->f_eof = 0;
}
int fseek(FILE*, long, int) int fseek(FILE*, long, int)
{ {
NOT_IMPLEMENTED("fseek"); NOT_IMPLEMENTED("fseek");