Kernel: Remove offset from OpenFileDescriptor
This is now handled on the libc side. There might be reasons to have it in kernel side, but for simplicity's sake I'm moving it to libc for now :)
This commit is contained in:
parent
5248a3fe48
commit
1cf7ef3de6
|
@ -25,7 +25,7 @@ namespace LibELF
|
||||||
|
|
||||||
TRY(data.resize(st.st_size));
|
TRY(data.resize(st.st_size));
|
||||||
|
|
||||||
TRY(Kernel::Process::current().read(fd, data.data(), data.size()));
|
TRY(Kernel::Process::current().read(fd, data.data(), 0, data.size()));
|
||||||
|
|
||||||
elf = new ELF(BAN::move(data));
|
elf = new ELF(BAN::move(data));
|
||||||
ASSERT(elf);
|
ASSERT(elf);
|
||||||
|
|
|
@ -153,9 +153,13 @@ irq 13
|
||||||
irq 14
|
irq 14
|
||||||
irq 15
|
irq 15
|
||||||
|
|
||||||
|
// arguments in RAX, RBX, RCX, RDX, RSI, RDI
|
||||||
|
// System V ABI: RDI, RSI, RDX, RCX, R8, R9
|
||||||
.global syscall_asm
|
.global syscall_asm
|
||||||
syscall_asm:
|
syscall_asm:
|
||||||
pushaq
|
pushaq
|
||||||
|
movq %rsi, %r8
|
||||||
|
movq %rdi, %r9
|
||||||
movq %rax, %rdi
|
movq %rax, %rdi
|
||||||
movq %rbx, %rsi
|
movq %rbx, %rsi
|
||||||
xchgq %rcx, %rdx
|
xchgq %rcx, %rdx
|
||||||
|
|
|
@ -41,16 +41,15 @@ namespace Kernel
|
||||||
pid_t pid() const { return m_pid; }
|
pid_t pid() const { return m_pid; }
|
||||||
|
|
||||||
BAN::ErrorOr<int> open(BAN::StringView, int);
|
BAN::ErrorOr<int> open(BAN::StringView, int);
|
||||||
BAN::ErrorOr<void> close(int);
|
BAN::ErrorOr<void> close(int fd);
|
||||||
BAN::ErrorOr<size_t> read(int, void*, size_t);
|
BAN::ErrorOr<size_t> read(int fd, void* buffer, size_t offset, size_t count);
|
||||||
BAN::ErrorOr<size_t> write(int, const void*, size_t);
|
BAN::ErrorOr<size_t> write(int fd, const void* buffer, size_t offset, size_t count);
|
||||||
BAN::ErrorOr<void> creat(BAN::StringView, mode_t);
|
BAN::ErrorOr<void> creat(BAN::StringView name, mode_t);
|
||||||
BAN::ErrorOr<void> seek(int, size_t);
|
|
||||||
|
|
||||||
BAN::ErrorOr<void> fstat(int, stat*);
|
BAN::ErrorOr<void> fstat(int fd, stat*);
|
||||||
BAN::ErrorOr<void> stat(BAN::StringView, stat*);
|
BAN::ErrorOr<void> stat(BAN::StringView path, stat*);
|
||||||
|
|
||||||
BAN::ErrorOr<void> mount(BAN::StringView, BAN::StringView);
|
BAN::ErrorOr<void> mount(BAN::StringView source, BAN::StringView target);
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::Vector<BAN::String>> read_directory_entries(int);
|
BAN::ErrorOr<BAN::Vector<BAN::String>> read_directory_entries(int);
|
||||||
|
|
||||||
|
@ -78,7 +77,6 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
BAN::RefPtr<Inode> inode;
|
BAN::RefPtr<Inode> inode;
|
||||||
BAN::String path;
|
BAN::String path;
|
||||||
size_t offset = 0;
|
|
||||||
uint8_t flags = 0;
|
uint8_t flags = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,21 +5,20 @@
|
||||||
#define SYS_WRITE 3
|
#define SYS_WRITE 3
|
||||||
#define SYS_TERMID 4
|
#define SYS_TERMID 4
|
||||||
#define SYS_CLOSE 5
|
#define SYS_CLOSE 5
|
||||||
#define SYS_SEEK 6
|
#define SYS_OPEN 6
|
||||||
#define SYS_OPEN 7
|
#define SYS_ALLOC 7
|
||||||
#define SYS_ALLOC 8
|
#define SYS_FREE 8
|
||||||
#define SYS_FREE 9
|
|
||||||
|
|
||||||
|
#include <kernel/Attributes.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename T1 = void*, typename T2 = void*, typename T3 = void*>
|
ALWAYS_INLINE long syscall(int syscall, uintptr_t arg1 = 0, uintptr_t arg2 = 0, uintptr_t arg3 = 0, uintptr_t arg4 = 0, uintptr_t arg5 = 0)
|
||||||
inline long syscall(int syscall, T1 arg1 = nullptr, T2 arg2 = nullptr, T3 arg3 = nullptr)
|
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
asm volatile("int $0x80" : "=a"(ret) : "a"(syscall), "b"((uintptr_t)arg1), "c"((uintptr_t)arg2), "d"((uintptr_t)arg3) : "memory");
|
asm volatile("int $0x80" : "=a"(ret) : "a"(syscall), "b"((uintptr_t)arg1), "c"((uintptr_t)arg2), "d"((uintptr_t)arg3), "S"((uintptr_t)arg4), "D"((uintptr_t)arg5) : "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::Vector<uint8_t> file_data;
|
BAN::Vector<uint8_t> file_data;
|
||||||
TRY(file_data.resize(st.st_size));
|
TRY(file_data.resize(st.st_size));
|
||||||
TRY(Process::current().read(fd, file_data.data(), st.st_size));
|
TRY(Process::current().read(fd, file_data.data(), 0, st.st_size));
|
||||||
|
|
||||||
if (file_data.size() < 4)
|
if (file_data.size() < 4)
|
||||||
return BAN::Error::from_error_code(ErrorCode::Font_FileTooSmall);
|
return BAN::Error::from_error_code(ErrorCode::Font_FileTooSmall);
|
||||||
|
|
|
@ -202,7 +202,6 @@ namespace Kernel
|
||||||
auto& open_file_description = m_open_files[fd];
|
auto& open_file_description = m_open_files[fd];
|
||||||
open_file_description.inode = file.inode;
|
open_file_description.inode = file.inode;
|
||||||
open_file_description.path = BAN::move(file.canonical_path);
|
open_file_description.path = BAN::move(file.canonical_path);
|
||||||
open_file_description.offset = 0;
|
|
||||||
open_file_description.flags = flags;
|
open_file_description.flags = flags;
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
|
@ -217,7 +216,7 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> Process::read(int fd, void* buffer, size_t count)
|
BAN::ErrorOr<size_t> Process::read(int fd, void* buffer, size_t offset, size_t count)
|
||||||
{
|
{
|
||||||
OpenFileDescription open_fd_copy;
|
OpenFileDescription open_fd_copy;
|
||||||
|
|
||||||
|
@ -229,18 +228,10 @@ namespace Kernel
|
||||||
|
|
||||||
if (!(open_fd_copy.flags & O_RDONLY))
|
if (!(open_fd_copy.flags & O_RDONLY))
|
||||||
return BAN::Error::from_errno(EBADF);
|
return BAN::Error::from_errno(EBADF);
|
||||||
size_t n_read = TRY(open_fd_copy.inode->read(open_fd_copy.offset, buffer, count));
|
return TRY(open_fd_copy.inode->read(offset, buffer, count));
|
||||||
open_fd_copy.offset += n_read;
|
|
||||||
|
|
||||||
m_lock.lock();
|
|
||||||
MUST(validate_fd(fd));
|
|
||||||
open_file_description(fd) = open_fd_copy;
|
|
||||||
m_lock.unlock();
|
|
||||||
|
|
||||||
return n_read;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> Process::write(int fd, const void* buffer, size_t count)
|
BAN::ErrorOr<size_t> Process::write(int fd, const void* buffer, size_t offset, size_t count)
|
||||||
{
|
{
|
||||||
OpenFileDescription open_fd_copy;
|
OpenFileDescription open_fd_copy;
|
||||||
|
|
||||||
|
@ -252,16 +243,7 @@ namespace Kernel
|
||||||
|
|
||||||
if (!(open_fd_copy.flags & O_WRONLY))
|
if (!(open_fd_copy.flags & O_WRONLY))
|
||||||
return BAN::Error::from_errno(EBADF);
|
return BAN::Error::from_errno(EBADF);
|
||||||
size_t n_written = TRY(open_fd_copy.inode->write(open_fd_copy.offset, buffer, count));
|
return TRY(open_fd_copy.inode->write(offset, buffer, count));
|
||||||
open_fd_copy.offset += n_written;
|
|
||||||
|
|
||||||
{
|
|
||||||
LockGuard _(m_lock);
|
|
||||||
MUST(validate_fd(fd));
|
|
||||||
open_file_description(fd) = open_fd_copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return n_written;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> Process::creat(BAN::StringView path, mode_t mode)
|
BAN::ErrorOr<void> Process::creat(BAN::StringView path, mode_t mode)
|
||||||
|
@ -282,11 +264,11 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> Process::mount(BAN::StringView partition, BAN::StringView path)
|
BAN::ErrorOr<void> Process::mount(BAN::StringView source, BAN::StringView target)
|
||||||
{
|
{
|
||||||
auto absolute_partition = TRY(absolute_path_of(partition));
|
auto absolute_source = TRY(absolute_path_of(source));
|
||||||
auto absolute_path = TRY(absolute_path_of(path));
|
auto absolute_target = TRY(absolute_path_of(target));
|
||||||
TRY(VirtualFileSystem::get().mount(absolute_partition, absolute_path));
|
TRY(VirtualFileSystem::get().mount(absolute_source, absolute_target));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,15 +307,7 @@ namespace Kernel
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> Process::seek(int fd, size_t offset)
|
// FIXME: This whole API has to be rewritten
|
||||||
{
|
|
||||||
LockGuard _(m_lock);
|
|
||||||
TRY(validate_fd(fd));
|
|
||||||
auto& open_fd = open_file_description(fd);
|
|
||||||
open_fd.offset = offset;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::Vector<BAN::String>> Process::read_directory_entries(int fd)
|
BAN::ErrorOr<BAN::Vector<BAN::String>> Process::read_directory_entries(int fd)
|
||||||
{
|
{
|
||||||
OpenFileDescription open_fd_copy;
|
OpenFileDescription open_fd_copy;
|
||||||
|
@ -344,15 +318,7 @@ namespace Kernel
|
||||||
open_fd_copy = open_file_description(fd);
|
open_fd_copy = open_file_description(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = TRY(open_fd_copy.inode->read_directory_entries(open_fd_copy.offset));
|
return TRY(open_fd_copy.inode->read_directory_entries(0));
|
||||||
open_fd_copy.offset++;
|
|
||||||
|
|
||||||
m_lock.lock();
|
|
||||||
MUST(validate_fd(fd));
|
|
||||||
open_file_description(fd) = open_fd_copy;
|
|
||||||
m_lock.unlock();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::String> Process::working_directory() const
|
BAN::ErrorOr<BAN::String> Process::working_directory() const
|
||||||
|
|
|
@ -22,14 +22,14 @@ namespace Kernel
|
||||||
static void TTY_PRINT(Args&&... args)
|
static void TTY_PRINT(Args&&... args)
|
||||||
{
|
{
|
||||||
BAN::String message = BAN::String::formatted(BAN::forward<Args>(args)...);
|
BAN::String message = BAN::String::formatted(BAN::forward<Args>(args)...);
|
||||||
MUST(Process::current().write(STDOUT_FILENO, message.data(), message.size()));
|
MUST(Process::current().write(STDOUT_FILENO, message.data(), 0, message.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
static void TTY_PRINTLN(Args&&... args)
|
static void TTY_PRINTLN(Args&&... args)
|
||||||
{
|
{
|
||||||
TTY_PRINT(BAN::forward<Args>(args)...);
|
TTY_PRINT(BAN::forward<Args>(args)...);
|
||||||
MUST(Process::current().write(STDOUT_FILENO, "\n", 1));
|
MUST(Process::current().write(STDOUT_FILENO, "\n", 0, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto s_default_prompt = "\\[\e[32m\\]user\\[\e[m\\]:\\[\e[34m\\]\\w\\[\e[m\\]# "sv;
|
static auto s_default_prompt = "\\[\e[32m\\]user\\[\e[m\\]:\\[\e[34m\\]\\w\\[\e[m\\]# "sv;
|
||||||
|
@ -112,7 +112,7 @@ namespace Kernel
|
||||||
|
|
||||||
void Shell::run()
|
void Shell::run()
|
||||||
{
|
{
|
||||||
auto getch = [this] { uint8_t ch; MUST(Process::current().read(STDIN_FILENO, &ch, 1)); return ch; };
|
auto getch = [this] { uint8_t ch; MUST(Process::current().read(STDIN_FILENO, &ch, 0, 1)); return ch; };
|
||||||
|
|
||||||
MUST(m_buffer.push_back(""sv));
|
MUST(m_buffer.push_back(""sv));
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ namespace Kernel
|
||||||
while ((current.back() & 0xC0) == 0x80)
|
while ((current.back() & 0xC0) == 0x80)
|
||||||
current.pop_back();
|
current.pop_back();
|
||||||
current.pop_back();
|
current.pop_back();
|
||||||
MUST(Process::current().write(STDOUT_FILENO, "\b \b", 3));
|
MUST(Process::current().write(STDOUT_FILENO, "\b \b", 0, 3));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ namespace Kernel
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MUST(Process::current().write(STDOUT_FILENO, &ch, 1));
|
MUST(Process::current().write(STDOUT_FILENO, &ch, 0, 1));
|
||||||
|
|
||||||
if (ch != '\n')
|
if (ch != '\n')
|
||||||
{
|
{
|
||||||
|
@ -556,8 +556,12 @@ argument_done:
|
||||||
BAN::ScopeGuard buffer_guard([buffer] { delete[] buffer; });
|
BAN::ScopeGuard buffer_guard([buffer] { delete[] buffer; });
|
||||||
ASSERT(buffer);
|
ASSERT(buffer);
|
||||||
|
|
||||||
while (size_t n_read = TRY(Process::current().read(fd, buffer, buffer_size)))
|
size_t offset = 0;
|
||||||
|
while (size_t n_read = TRY(Process::current().read(fd, buffer, offset, buffer_size)))
|
||||||
|
{
|
||||||
TTY_PRINT("{}", BAN::StringView(buffer, n_read));
|
TTY_PRINT("{}", BAN::StringView(buffer, n_read));
|
||||||
|
offset += n_read;
|
||||||
|
}
|
||||||
TTY_PRINTLN("");
|
TTY_PRINTLN("");
|
||||||
}
|
}
|
||||||
else if (arguments.front() == "stat")
|
else if (arguments.front() == "stat")
|
||||||
|
@ -635,7 +639,7 @@ argument_done:
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
size_t n_read = TRY(Process::current().read(fd, buffer, buffer_size));
|
size_t n_read = TRY(Process::current().read(fd, buffer, total_read, buffer_size));
|
||||||
if (n_read == 0)
|
if (n_read == 0)
|
||||||
break;
|
break;
|
||||||
for (size_t j = 0; j < n_read; j++)
|
for (size_t j = 0; j < n_read; j++)
|
||||||
|
|
|
@ -10,17 +10,17 @@ namespace Kernel
|
||||||
Process::current().exit();
|
Process::current().exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
long sys_read(int fd, void* buffer, size_t size)
|
long sys_read(int fd, void* buffer, size_t offset, size_t size)
|
||||||
{
|
{
|
||||||
auto res = Process::current().read(fd, buffer, size);
|
auto res = Process::current().read(fd, buffer, offset, size);
|
||||||
if (res.is_error())
|
if (res.is_error())
|
||||||
return -res.error().get_error_code();
|
return -res.error().get_error_code();
|
||||||
return res.value();
|
return res.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
long sys_write(int fd, const void* buffer, size_t size)
|
long sys_write(int fd, const void* buffer, size_t offset, size_t size)
|
||||||
{
|
{
|
||||||
auto res = Process::current().write(fd, buffer, size);
|
auto res = Process::current().write(fd, buffer, offset, size);
|
||||||
if (res.is_error())
|
if (res.is_error())
|
||||||
return -res.error().get_error_code();
|
return -res.error().get_error_code();
|
||||||
return res.value();
|
return res.value();
|
||||||
|
@ -34,14 +34,6 @@ namespace Kernel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_seek(int fd, long offset)
|
|
||||||
{
|
|
||||||
auto res = Process::current().seek(fd, offset);
|
|
||||||
if (res.is_error())
|
|
||||||
return -res.error().get_error_code();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sys_termid(char* buffer)
|
void sys_termid(char* buffer)
|
||||||
{
|
{
|
||||||
Process::current().termid(buffer);
|
Process::current().termid(buffer);
|
||||||
|
@ -68,12 +60,14 @@ namespace Kernel
|
||||||
Process::current().free(ptr);
|
Process::current().free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" long cpp_syscall_handler(int syscall, void* arg1, void* arg2, void* arg3)
|
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5)
|
||||||
{
|
{
|
||||||
Thread::current().set_in_syscall(true);
|
Thread::current().set_in_syscall(true);
|
||||||
|
|
||||||
asm volatile("sti");
|
asm volatile("sti");
|
||||||
|
|
||||||
|
(void)arg5;
|
||||||
|
|
||||||
long ret = 0;
|
long ret = 0;
|
||||||
switch (syscall)
|
switch (syscall)
|
||||||
{
|
{
|
||||||
|
@ -81,28 +75,25 @@ namespace Kernel
|
||||||
sys_exit();
|
sys_exit();
|
||||||
break;
|
break;
|
||||||
case SYS_READ:
|
case SYS_READ:
|
||||||
ret = sys_read((int)(uintptr_t)arg1, arg2, (size_t)(uintptr_t)arg3);
|
ret = sys_read((int)arg1, (void*)arg2, (size_t)arg3, (size_t)arg4);
|
||||||
break;
|
break;
|
||||||
case SYS_WRITE:
|
case SYS_WRITE:
|
||||||
ret = sys_write((int)(uintptr_t)arg1, arg2, (size_t)(uintptr_t)arg3);
|
ret = sys_write((int)arg1, (const void*)arg2, (size_t)arg3, (size_t)arg4);
|
||||||
break;
|
break;
|
||||||
case SYS_TERMID:
|
case SYS_TERMID:
|
||||||
sys_termid((char*)arg1);
|
sys_termid((char*)arg1);
|
||||||
break;
|
break;
|
||||||
case SYS_CLOSE:
|
case SYS_CLOSE:
|
||||||
ret = sys_close((int)(uintptr_t)arg1);
|
ret = sys_close((int)arg1);
|
||||||
break;
|
|
||||||
case SYS_SEEK:
|
|
||||||
ret = sys_seek((int)(uintptr_t)arg1, (long)arg2);
|
|
||||||
break;
|
break;
|
||||||
case SYS_OPEN:
|
case SYS_OPEN:
|
||||||
ret = sys_open((const char*)arg1, (int)(uintptr_t)arg2);
|
ret = sys_open((const char*)arg1, (int)arg2);
|
||||||
break;
|
break;
|
||||||
case SYS_ALLOC:
|
case SYS_ALLOC:
|
||||||
ret = sys_alloc((size_t)arg1);
|
ret = sys_alloc((size_t)arg1);
|
||||||
break;
|
break;
|
||||||
case SYS_FREE:
|
case SYS_FREE:
|
||||||
sys_free(arg1);
|
sys_free((void*)arg1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Kernel::panic("Unknown syscall {}", syscall);
|
Kernel::panic("Unknown syscall {}", syscall);
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace Kernel
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
Input::KeyEvent event;
|
Input::KeyEvent event;
|
||||||
ASSERT(MUST(Process::current().read(fd, &event, sizeof(event))) == sizeof(event));
|
ASSERT(MUST(Process::current().read(fd, &event, 0, sizeof(event))) == sizeof(event));
|
||||||
TTY::current()->on_key(event);
|
TTY::current()->on_key(event);
|
||||||
}
|
}
|
||||||
}, nullptr
|
}, nullptr
|
||||||
|
|
|
@ -76,7 +76,7 @@ int fflush(FILE* file)
|
||||||
if (file->buffer_index == 0)
|
if (file->buffer_index == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (syscall(SYS_WRITE, file->fd, file->buffer, file->buffer_index) < 0)
|
if (syscall(SYS_WRITE, file->fd, file->buffer, file->offset, file->buffer_index) < 0)
|
||||||
{
|
{
|
||||||
file->error = true;
|
file->error = true;
|
||||||
return EOF;
|
return EOF;
|
||||||
|
@ -92,7 +92,7 @@ int fgetc(FILE* file)
|
||||||
return EOF;
|
return EOF;
|
||||||
|
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
long ret = syscall(SYS_READ, file->fd, &c, 1);
|
long ret = syscall(SYS_READ, file->fd, &c, file->offset, 1);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
|
@ -235,7 +235,7 @@ size_t fread(void* buffer, size_t size, size_t nitems, FILE* file)
|
||||||
{
|
{
|
||||||
if (file->eof || nitems * size == 0)
|
if (file->eof || nitems * size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
long ret = syscall(SYS_READ, file->fd, buffer, size * nitems);
|
long ret = syscall(SYS_READ, file->fd, buffer, file->offset, size * nitems);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
file->error = true;
|
file->error = true;
|
||||||
|
@ -260,7 +260,13 @@ int fseek(FILE* file, long offset, int whence)
|
||||||
|
|
||||||
int fseeko(FILE* file, off_t offset, int whence)
|
int fseeko(FILE* file, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
if (whence == SEEK_CUR)
|
if (offset < 0)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (whence == SEEK_CUR && offset <= file->offset)
|
||||||
file->offset += offset;
|
file->offset += offset;
|
||||||
else if (whence == SEEK_SET)
|
else if (whence == SEEK_SET)
|
||||||
file->offset = offset;
|
file->offset = offset;
|
||||||
|
@ -275,16 +281,6 @@ int fseeko(FILE* file, off_t offset, int whence)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file->offset < 0)
|
|
||||||
{
|
|
||||||
file->offset -= offset;
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (syscall(SYS_SEEK, file->fd, file->offset))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
file->eof = false;
|
file->eof = false;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -31,22 +31,24 @@ long syscall(long syscall, ...)
|
||||||
{
|
{
|
||||||
int fd = va_arg(args, int);
|
int fd = va_arg(args, int);
|
||||||
void* buffer = va_arg(args, void*);
|
void* buffer = va_arg(args, void*);
|
||||||
|
size_t offset = va_arg(args, size_t);
|
||||||
size_t bytes = va_arg(args, size_t);
|
size_t bytes = va_arg(args, size_t);
|
||||||
ret = Kernel::syscall(SYS_READ, fd, buffer, bytes);
|
ret = Kernel::syscall(SYS_READ, fd, (uintptr_t)buffer, offset, bytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SYS_WRITE:
|
case SYS_WRITE:
|
||||||
{
|
{
|
||||||
int fd = va_arg(args, int);
|
int fd = va_arg(args, int);
|
||||||
const char* string = va_arg(args, const char*);
|
const char* string = va_arg(args, const char*);
|
||||||
|
size_t offset = va_arg(args, size_t);
|
||||||
size_t bytes = va_arg(args, size_t);
|
size_t bytes = va_arg(args, size_t);
|
||||||
ret = Kernel::syscall(SYS_WRITE, fd, string, bytes);
|
ret = Kernel::syscall(SYS_WRITE, fd, (uintptr_t)string, offset, bytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SYS_TERMID:
|
case SYS_TERMID:
|
||||||
{
|
{
|
||||||
char* buffer = va_arg(args, char*);
|
char* buffer = va_arg(args, char*);
|
||||||
ret = Kernel::syscall(SYS_TERMID, buffer);
|
ret = Kernel::syscall(SYS_TERMID, (uintptr_t)buffer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SYS_CLOSE:
|
case SYS_CLOSE:
|
||||||
|
@ -55,18 +57,11 @@ long syscall(long syscall, ...)
|
||||||
ret = Kernel::syscall(SYS_CLOSE, fd);
|
ret = Kernel::syscall(SYS_CLOSE, fd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SYS_SEEK:
|
|
||||||
{
|
|
||||||
int fd = va_arg(args, int);
|
|
||||||
long offset = va_arg(args, long);
|
|
||||||
ret = Kernel::syscall(SYS_SEEK, fd, offset);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SYS_OPEN:
|
case SYS_OPEN:
|
||||||
{
|
{
|
||||||
const char* path = va_arg(args, const char*);
|
const char* path = va_arg(args, const char*);
|
||||||
int oflags = va_arg(args, int);
|
int oflags = va_arg(args, int);
|
||||||
ret = Kernel::syscall(SYS_OPEN, path, oflags);
|
ret = Kernel::syscall(SYS_OPEN, (uintptr_t)path, oflags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SYS_ALLOC:
|
case SYS_ALLOC:
|
||||||
|
@ -78,7 +73,7 @@ long syscall(long syscall, ...)
|
||||||
case SYS_FREE:
|
case SYS_FREE:
|
||||||
{
|
{
|
||||||
void* ptr = va_arg(args, void*);
|
void* ptr = va_arg(args, void*);
|
||||||
ret = Kernel::syscall(SYS_FREE, ptr);
|
ret = Kernel::syscall(SYS_FREE, (uintptr_t)ptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,35 +1,30 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define N 1024
|
#define ERROR(msg) { perror(msg); return 1; }
|
||||||
|
#define BUF_SIZE 1024
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
for (int i = 0; i <= 10; i++)
|
FILE* fp = fopen("/usr/include/stdio.h", "r");
|
||||||
{
|
if (fp == NULL)
|
||||||
int** ptrs = malloc(N * sizeof(int*));
|
ERROR("fopen");
|
||||||
if (ptrs == NULL)
|
|
||||||
{
|
|
||||||
perror("malloc");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
for (int j = 0; j < N; j++)
|
|
||||||
{
|
|
||||||
ptrs[j] = malloc(sizeof(int));
|
|
||||||
if (ptrs[j] == NULL)
|
|
||||||
{
|
|
||||||
perror("malloc");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
*ptrs[j] = j;
|
|
||||||
putchar('0' + *ptrs[j] % 10);
|
|
||||||
}
|
|
||||||
putchar('\n');
|
|
||||||
|
|
||||||
for (int j = 0; j < N; j++)
|
char* buffer = malloc(BUF_SIZE);
|
||||||
free(ptrs[j]);
|
if (buffer == NULL)
|
||||||
free(ptrs);
|
ERROR("malloc");
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
size_t n_read = fread(buffer, 1, BUF_SIZE - 1, fp);
|
||||||
|
if (n_read == 0)
|
||||||
|
break;
|
||||||
|
buffer[n_read] = '\0';
|
||||||
|
printf("%s", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue