#include #include #include #include #include #include extern "C" { int fclose(FILE* stream) { int status = close(stream->fd); if (status < 0) { int savederr = errno; free(stream); // We do not want to leak memory. man fclose(3) says that whether fclose() fails or not, any // further operation on the stream results in undefined behavior. So we are free to free the // stream. errno = savederr; // free might reset errno. We don't want that. } else { free(stream); } return status; } int fflush(FILE*) { return 0; // FIXME: Implement buffered IO. } FILE* fopen(const char* pathname, const char*) { int fd = open(pathname, O_RDONLY); // FIXME: Use the mode string. if (fd < 0) { return 0; } FILE* stream = (FILE*)malloc(sizeof(FILE)); stream->fd = fd; return stream; } size_t fread(void* buf, size_t size, size_t nmemb, FILE* stream) { ssize_t status = read(stream->fd, buf, size * nmemb); 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, // until that is implemented. return (size_t)status; } int fseek(FILE*, long, int) { NOT_IMPLEMENTED("fseek"); } long ftell(FILE*) { NOT_IMPLEMENTED("ftell"); } size_t fwrite(const void*, size_t, size_t, FILE*) { NOT_IMPLEMENTED("fwrite"); } void setbuf(FILE*, char*) { NOT_IMPLEMENTED("setbuf"); } }