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:
parent
4a5db1dca7
commit
edda41a7bb
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user