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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user