libc: Implement fseek(), ftell() and rewind()

All three use the new syscall seek() (with its lseek() wrapper in unistd.h)!!
This commit is contained in:
apio 2022-10-12 15:56:03 +02:00
parent 4a5db1dca7
commit edda41a7bb
6 changed files with 43 additions and 10 deletions

View File

@ -85,6 +85,23 @@ int main()
return 1; return 1;
} }
if (fseek(config, 0, SEEK_END) < 0)
{
perror("fseek");
return 1;
}
long offset = ftell(config);
if (offset < 0)
{
perror("ftell");
return 1;
}
printf("%s is %ld bytes long\n", filename, offset);
rewind(config);
char buf[4096]; char buf[4096];
size_t nread = fread(buf, sizeof(buf), 1, config); size_t nread = fread(buf, sizeof(buf), 1, config);

View File

@ -36,7 +36,8 @@ ssize_t Descriptor::write(size_t size, const char* buffer)
int Descriptor::seek(long offset) int Descriptor::seek(long offset)
{ {
if (m_node->type != VFS_DEVICE && offset > m_node->length) if (m_node->type != VFS_DEVICE && (uint64_t)offset > m_node->length)
return -EINVAL; // FIXME: Support seeking beyond the current file's length. return -EINVAL; // FIXME: Support seeking beyond the current file's length.
m_offset = (uint64_t)offset; m_offset = (uint64_t)offset;
return 0;
} }

View File

@ -20,7 +20,7 @@ void Syscall::entry(Context* context)
case SYS_open: sys_open(context, (const char*)context->rdi, (int)context->rsi); break; case SYS_open: sys_open(context, (const char*)context->rdi, (int)context->rsi); break;
case SYS_read: sys_read(context, (int)context->rdi, context->rsi, (char*)context->rdx); break; case SYS_read: sys_read(context, (int)context->rdi, context->rsi, (char*)context->rdx); break;
case SYS_close: sys_close(context, (int)context->rdi); break; case SYS_close: sys_close(context, (int)context->rdi); break;
case SYS_seek: sys_seek(context, (int)context->rdi, (long)context->rsi, (int)context->rdx); case SYS_seek: sys_seek(context, (int)context->rdi, (long)context->rsi, (int)context->rdx); break;
default: context->rax = -ENOSYS; break; default: context->rax = -ENOSYS; break;
} }
} }

View File

@ -38,8 +38,14 @@ extern "C"
/* Reads nmemb items of size size from the file stream into buf. */ /* Reads nmemb items of size size from the file stream into buf. */
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);
int fseek(FILE*, long, int); // Not implemented. /* Moves stream's read/write offset by offset, depending on whence. */
long ftell(FILE*); // Not implemented. int fseek(FILE* stream, long offset, int whence);
/* Returns the current offset for stream. */
long ftell(FILE* stream);
/* Rewinds stream's offset to start of file. */
void rewind(FILE* stream);
/* Writes nmemb items of size size from buf into the file stream. */ /* Writes nmemb items of size size from buf into the file stream. */
size_t fwrite(const void* buf, size_t size, size_t nmemb, FILE* stream); size_t fwrite(const void* buf, size_t size, size_t nmemb, FILE* stream);

View File

@ -2,8 +2,7 @@
#define _SYS_MMAN_H #define _SYS_MMAN_H
#include <stddef.h> #include <stddef.h>
#include <sys/types.h> // for off_t
typedef unsigned long off_t;
/* Address returned by mmap when it fails. */ /* Address returned by mmap when it fails. */
#define MAP_FAILED (void*)-1 #define MAP_FAILED (void*)-1

View File

@ -67,14 +67,24 @@ extern "C"
stream->f_err = stream->f_eof = 0; stream->f_err = stream->f_eof = 0;
} }
int fseek(FILE*, long, int) int fseek(FILE* stream, long offset, int whence)
{ {
NOT_IMPLEMENTED("fseek"); long result = lseek(stream->f_fd, offset, whence);
if (result < 0) { return -1; }
return 0;
} }
long ftell(FILE*) long ftell(FILE* stream)
{ {
NOT_IMPLEMENTED("ftell"); return lseek(stream->f_fd, 0,
SEEK_CUR); // FIXME: Store the last seeked position in the file struct to avoid redundant syscalls
// maybe? We'd have to update this value in fread() and fwrite() as well...
}
void rewind(FILE* stream)
{
lseek(stream->f_fd, 0, SEEK_SET);
clearerr(stream);
} }
size_t fwrite(const void* buf, size_t size, size_t nmemb, FILE* stream) size_t fwrite(const void* buf, size_t size, size_t nmemb, FILE* stream)