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;
}
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];
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)
{
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.
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_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_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;
}
}

View File

@ -38,8 +38,14 @@ extern "C"
/* 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);
int fseek(FILE*, long, int); // Not implemented.
long ftell(FILE*); // Not implemented.
/* Moves stream's read/write offset by offset, depending on whence. */
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. */
size_t fwrite(const void* buf, size_t size, size_t nmemb, FILE* stream);

View File

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

View File

@ -67,14 +67,24 @@ extern "C"
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)