Compare commits
9 Commits
f6e783ea45
...
b67011c626
Author | SHA1 | Date | |
---|---|---|---|
b67011c626 | |||
0f47f59364 | |||
2f46e46aa4 | |||
80ab982fe4 | |||
53a4b3b85e | |||
12cf37d0a7 | |||
e764647133 | |||
b1fcfd0d74 | |||
e67ef7778c |
@ -14,14 +14,20 @@ struct Descriptor
|
|||||||
return m_can_read && m_is_open;
|
return m_can_read && m_is_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool can_write()
|
||||||
|
{
|
||||||
|
return m_can_write && m_is_open;
|
||||||
|
}
|
||||||
|
|
||||||
void close()
|
void close()
|
||||||
{
|
{
|
||||||
m_is_open = false;
|
m_is_open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t read(size_t size, char* buffer);
|
ssize_t read(size_t size, char* buffer);
|
||||||
|
ssize_t write(size_t size, const char* buffer);
|
||||||
|
|
||||||
void open(VFS::Node* node, bool can_read);
|
void open(VFS::Node* node, bool can_read, bool can_write);
|
||||||
|
|
||||||
Descriptor(const Descriptor& other);
|
Descriptor(const Descriptor& other);
|
||||||
Descriptor();
|
Descriptor();
|
||||||
@ -29,6 +35,7 @@ struct Descriptor
|
|||||||
private:
|
private:
|
||||||
bool m_is_open;
|
bool m_is_open;
|
||||||
bool m_can_read;
|
bool m_can_read;
|
||||||
|
bool m_can_write;
|
||||||
VFS::Node* m_node;
|
VFS::Node* m_node;
|
||||||
uint64_t m_offset;
|
uint64_t m_offset;
|
||||||
};
|
};
|
@ -14,6 +14,7 @@ namespace VFS
|
|||||||
struct Node;
|
struct Node;
|
||||||
|
|
||||||
typedef ssize_t (*node_read)(Node*, size_t, size_t, char*);
|
typedef ssize_t (*node_read)(Node*, size_t, size_t, char*);
|
||||||
|
typedef ssize_t (*node_write)(Node*, size_t, size_t, const char*);
|
||||||
typedef Node* (*node_finddir)(Node*, const char*);
|
typedef Node* (*node_finddir)(Node*, const char*);
|
||||||
typedef int (*node_mkdir)(Node*, const char*);
|
typedef int (*node_mkdir)(Node*, const char*);
|
||||||
|
|
||||||
@ -27,10 +28,12 @@ namespace VFS
|
|||||||
node_read read_func;
|
node_read read_func;
|
||||||
node_finddir find_func;
|
node_finddir find_func;
|
||||||
node_mkdir mkdir_func;
|
node_mkdir mkdir_func;
|
||||||
|
node_write write_func;
|
||||||
Node* link;
|
Node* link;
|
||||||
};
|
};
|
||||||
|
|
||||||
ssize_t read(Node* node, size_t offset, size_t length, char* buffer);
|
ssize_t read(Node* node, size_t offset, size_t length, char* buffer);
|
||||||
|
ssize_t write(Node* node, size_t offset, size_t length, const char* buffer);
|
||||||
int mkdir(const char* path, const char* name); // FIXME: Support deducing this via a single path.
|
int mkdir(const char* path, const char* name); // FIXME: Support deducing this via a single path.
|
||||||
|
|
||||||
void mount_root(Node* root);
|
void mount_root(Node* root);
|
||||||
|
9
kernel/include/fs/devices/Console.h
Normal file
9
kernel/include/fs/devices/Console.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "fs/VFS.h"
|
||||||
|
|
||||||
|
namespace ConsoleDevice
|
||||||
|
{
|
||||||
|
VFS::Node* create_new();
|
||||||
|
|
||||||
|
ssize_t write(VFS::Node* node, size_t offset, size_t size, const char* buffer);
|
||||||
|
}
|
@ -24,7 +24,7 @@ namespace Syscall
|
|||||||
void sys_exit(Context* context, int status);
|
void sys_exit(Context* context, int status);
|
||||||
void sys_yield(Context* context);
|
void sys_yield(Context* context);
|
||||||
void sys_sleep(Context* context, uint64_t ms);
|
void sys_sleep(Context* context, uint64_t ms);
|
||||||
void sys_write(Context* context, const char* addr, size_t size);
|
void sys_write(Context* context, int fd, size_t size, const char* addr);
|
||||||
void sys_paint(Context* context, uint64_t x, uint64_t y, uint64_t w, uint64_t h, uint64_t col);
|
void sys_paint(Context* context, uint64_t x, uint64_t y, uint64_t w, uint64_t h, uint64_t col);
|
||||||
void sys_rand(Context* context);
|
void sys_rand(Context* context);
|
||||||
void sys_getversion(Context* context, char* buffer, size_t max);
|
void sys_getversion(Context* context, char* buffer, size_t max);
|
||||||
|
@ -5,13 +5,15 @@ Descriptor::Descriptor() : m_is_open(false)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Descriptor::Descriptor(const Descriptor& other)
|
Descriptor::Descriptor(const Descriptor& other)
|
||||||
: m_is_open(other.m_is_open), m_can_read(other.m_can_read), m_node(other.m_node), m_offset(other.m_offset)
|
: m_is_open(other.m_is_open), m_can_read(other.m_can_read), m_can_write(other.m_can_write), m_node(other.m_node),
|
||||||
|
m_offset(other.m_offset)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Descriptor::open(VFS::Node* node, bool can_read)
|
void Descriptor::open(VFS::Node* node, bool can_read, bool can_write)
|
||||||
{
|
{
|
||||||
m_can_read = can_read;
|
m_can_read = can_read;
|
||||||
|
m_can_write = can_write;
|
||||||
m_node = node;
|
m_node = node;
|
||||||
m_offset = 0;
|
m_offset = 0;
|
||||||
m_is_open = true;
|
m_is_open = true;
|
||||||
@ -23,3 +25,10 @@ ssize_t Descriptor::read(size_t size, char* buffer)
|
|||||||
m_offset += result;
|
m_offset += result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t Descriptor::write(size_t size, const char* buffer)
|
||||||
|
{
|
||||||
|
ssize_t result = VFS::write(m_node, m_offset, size, buffer);
|
||||||
|
m_offset += result;
|
||||||
|
return result;
|
||||||
|
}
|
@ -26,12 +26,30 @@ ssize_t VFS::read(Node* node, size_t offset, size_t length, char* buffer)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
kdbgln("read(): node %s (inode %ld), offset %zd, %zd bytes, into %p", node->name, node->inode, offset, length,
|
|
||||||
(void*)buffer);
|
|
||||||
|
|
||||||
return node->read_func(node, offset, length, buffer);
|
return node->read_func(node, offset, length, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t VFS::write(Node* node, size_t offset, size_t length, const char* buffer)
|
||||||
|
{
|
||||||
|
if (!node)
|
||||||
|
{
|
||||||
|
kwarnln("write() failed: trying to write to nullptr");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (node->type == VFS_DIRECTORY)
|
||||||
|
{
|
||||||
|
kwarnln("write() failed: is a directory");
|
||||||
|
return -EISDIR;
|
||||||
|
}
|
||||||
|
if (!node->write_func)
|
||||||
|
{
|
||||||
|
kwarnln("write() failed: the chosen node doesn't support writing");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node->write_func(node, offset, length, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
void VFS::mount_root(Node* root)
|
void VFS::mount_root(Node* root)
|
||||||
{
|
{
|
||||||
if (!root)
|
if (!root)
|
||||||
@ -92,15 +110,12 @@ VFS::Node* VFS::resolve_path(const char* filename, Node* root)
|
|||||||
}
|
}
|
||||||
if (child->flags & VFS_MOUNTPOINT)
|
if (child->flags & VFS_MOUNTPOINT)
|
||||||
{
|
{
|
||||||
kdbgln("Current node (%s, inode=%ld) is a mountpoint, resolving actual node", child->name,
|
|
||||||
child->inode);
|
|
||||||
if (!child->link)
|
if (!child->link)
|
||||||
{
|
{
|
||||||
kwarnln("Current node's link is null");
|
kwarnln("Current node's link is null");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
child = child->link;
|
child = child->link;
|
||||||
kdbgln("Resolved to %s (inode %ld)", child->name, child->inode);
|
|
||||||
}
|
}
|
||||||
current_node = child;
|
current_node = child;
|
||||||
kfree(buffer);
|
kfree(buffer);
|
||||||
|
25
kernel/src/fs/devices/Console.cpp
Normal file
25
kernel/src/fs/devices/Console.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "fs/devices/Console.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "render/TextRenderer.h"
|
||||||
|
#include "std/stdio.h"
|
||||||
|
#include "std/stdlib.h"
|
||||||
|
#include "std/string.h"
|
||||||
|
|
||||||
|
VFS::Node* ConsoleDevice::create_new()
|
||||||
|
{
|
||||||
|
VFS::Node* dev = new VFS::Node;
|
||||||
|
dev->write_func = ConsoleDevice::write;
|
||||||
|
dev->inode = 0;
|
||||||
|
dev->length = 0;
|
||||||
|
dev->type = VFS_FILE;
|
||||||
|
dev->flags = 0;
|
||||||
|
strncpy(dev->name, "console", sizeof(dev->name));
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t ConsoleDevice::write(VFS::Node* node, size_t, size_t size, const char* buffer)
|
||||||
|
{
|
||||||
|
if (!node) return -1;
|
||||||
|
TextRenderer::write(buffer, size);
|
||||||
|
return (ssize_t)size;
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
#include "fs/devices/DeviceFS.h"
|
#include "fs/devices/DeviceFS.h"
|
||||||
|
#include "fs/devices/Console.h"
|
||||||
#include "fs/devices/Version.h"
|
#include "fs/devices/Version.h"
|
||||||
#include "std/stdlib.h"
|
#include "std/stdlib.h"
|
||||||
#include "std/string.h"
|
#include "std/string.h"
|
||||||
@ -21,6 +22,7 @@ VFS::Node* DeviceFS::get()
|
|||||||
strncpy(devfs_root->name, "dev", sizeof(devfs_root->name));
|
strncpy(devfs_root->name, "dev", sizeof(devfs_root->name));
|
||||||
|
|
||||||
devfs_files[devfs_file_count++] = VersionDevice::create_new();
|
devfs_files[devfs_file_count++] = VersionDevice::create_new();
|
||||||
|
devfs_files[devfs_file_count++] = ConsoleDevice::create_new();
|
||||||
return devfs_root;
|
return devfs_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ VFS::Node* VersionDevice::create_new()
|
|||||||
dev->inode = 0;
|
dev->inode = 0;
|
||||||
dev->length = strlen(moon_version()) + 5;
|
dev->length = strlen(moon_version()) + 5;
|
||||||
dev->type = VFS_FILE;
|
dev->type = VFS_FILE;
|
||||||
|
dev->flags = 0;
|
||||||
strncpy(dev->name, "version", sizeof(dev->name));
|
strncpy(dev->name, "version", sizeof(dev->name));
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
@ -20,7 +21,6 @@ ssize_t VersionDevice::read(VFS::Node* node, size_t offset, size_t size, char* b
|
|||||||
if (!node) return -1;
|
if (!node) return -1;
|
||||||
if (offset > node->length) return -1;
|
if (offset > node->length) return -1;
|
||||||
if (offset + size > node->length) { size = node->length - offset; }
|
if (offset + size > node->length) { size = node->length - offset; }
|
||||||
if (offset > 0) return -1;
|
|
||||||
snprintf(buffer, size + 1, "moon %s", moon_version()); // FIXME: Support offseting this read
|
snprintf(buffer, size + 1, "moon %s", moon_version()); // FIXME: Support offseting this read
|
||||||
return (ssize_t)size;
|
return (ssize_t)size;
|
||||||
}
|
}
|
@ -18,7 +18,7 @@ void Syscall::entry(Context* context)
|
|||||||
sys_sleep(context, context->rdi);
|
sys_sleep(context, context->rdi);
|
||||||
break;
|
break;
|
||||||
case SYS_write: // sys_write
|
case SYS_write: // sys_write
|
||||||
sys_write(context, (const char*)context->rdi, context->rsi);
|
sys_write(context, (int)context->rdi, context->rsi, (const char*)context->rdx);
|
||||||
break;
|
break;
|
||||||
case SYS_paint: sys_paint(context, context->rdi, context->rsi, context->rdx, context->r10, context->r8); break;
|
case SYS_paint: sys_paint(context, context->rdi, context->rsi, context->rdx, context->r10, context->r8); break;
|
||||||
case SYS_rand: sys_rand(context); break;
|
case SYS_rand: sys_rand(context); break;
|
||||||
|
@ -8,12 +8,44 @@
|
|||||||
#include "thread/Scheduler.h"
|
#include "thread/Scheduler.h"
|
||||||
#include "thread/Task.h"
|
#include "thread/Task.h"
|
||||||
|
|
||||||
|
#define OPEN_READ 1
|
||||||
|
#define OPEN_WRITE 2
|
||||||
|
|
||||||
#define STDIO_FAIL(function, error) kwarnln("%s failed with %s", #function, #error)
|
#define STDIO_FAIL(function, error) kwarnln("%s failed with %s", #function, #error)
|
||||||
|
|
||||||
void sys_write(Context* context, const char* addr, size_t size)
|
void sys_write(Context* context, int fd, size_t size, const char* addr)
|
||||||
{
|
{
|
||||||
context->rax = size;
|
if (!addr)
|
||||||
TextRenderer::write(addr, size);
|
{
|
||||||
|
STDIO_FAIL(write, EINVAL);
|
||||||
|
context->rax = -EINVAL; // FIXME: This should probably return EFAULT.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fd >= TASK_MAX_FDS || fd < 0)
|
||||||
|
{
|
||||||
|
kwarnln("file descriptor %d is outside the valid range", fd);
|
||||||
|
STDIO_FAIL(write, EBADF);
|
||||||
|
context->rax = -EBADF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Task* current_task = Scheduler::current_task();
|
||||||
|
if (!current_task->files[fd].is_open())
|
||||||
|
{
|
||||||
|
kwarnln("file descriptor %d is not open", fd);
|
||||||
|
STDIO_FAIL(write, EBADF);
|
||||||
|
context->rax = -EBADF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!current_task->files[fd].can_write())
|
||||||
|
{
|
||||||
|
kwarnln("file descriptor %d is not open for writing", fd);
|
||||||
|
STDIO_FAIL(write, EBADF);
|
||||||
|
context->rax = -EBADF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ssize_t result = current_task->files[fd].write(size, addr);
|
||||||
|
context->rax = (size_t)result;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_open(Context* context, const char* filename, int flags)
|
void sys_open(Context* context, const char* filename, int flags)
|
||||||
@ -24,12 +56,14 @@ void sys_open(Context* context, const char* filename, int flags)
|
|||||||
{
|
{
|
||||||
if (!current_task->files[fd].is_open()) break;
|
if (!current_task->files[fd].is_open()) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd == TASK_MAX_FDS)
|
if (fd == TASK_MAX_FDS)
|
||||||
{
|
{
|
||||||
STDIO_FAIL(open, EMFILE);
|
STDIO_FAIL(open, EMFILE);
|
||||||
context->rax = -EMFILE;
|
context->rax = -EMFILE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VFS::Node* node = VFS::resolve_path(filename);
|
VFS::Node* node = VFS::resolve_path(filename);
|
||||||
if (!node)
|
if (!node)
|
||||||
{
|
{
|
||||||
@ -37,9 +71,23 @@ void sys_open(Context* context, const char* filename, int flags)
|
|||||||
context->rax = -ENOENT;
|
context->rax = -ENOENT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
kdbgln("open(): opening %s, allocated file descriptor %d", filename, fd);
|
|
||||||
current_task->files[fd].open(node,
|
bool can_read = (flags & OPEN_READ) > 0;
|
||||||
(bool)flags); // FIXME: Implement more flags. (right now, 1 is can_read, 0 is not)
|
bool can_write = (flags & OPEN_WRITE) > 0;
|
||||||
|
if (!can_read && !can_write)
|
||||||
|
{
|
||||||
|
STDIO_FAIL(open, EINVAL);
|
||||||
|
context->rax = -EINVAL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
kdbgln("open(): opening %s %s, allocated file descriptor %d", filename,
|
||||||
|
(can_read && can_write) ? "rw"
|
||||||
|
: can_read ? "r-"
|
||||||
|
: "-w",
|
||||||
|
fd);
|
||||||
|
|
||||||
|
current_task->files[fd].open(node, can_read, can_write);
|
||||||
context->rax = fd;
|
context->rax = fd;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ section .text
|
|||||||
extern _init
|
extern _init
|
||||||
extern main
|
extern main
|
||||||
extern _fini
|
extern _fini
|
||||||
|
extern initialize_libc
|
||||||
extern exit
|
extern exit
|
||||||
|
|
||||||
global _start
|
global _start
|
||||||
@ -13,6 +14,8 @@ _start:
|
|||||||
push rbp ; rbp=0
|
push rbp ; rbp=0
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
|
|
||||||
|
call initialize_libc
|
||||||
|
|
||||||
call _init
|
call _init
|
||||||
|
|
||||||
mov rdi, 0 ; argc = 0
|
mov rdi, 0 ; argc = 0
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#define _FCNTL_H
|
#define _FCNTL_H
|
||||||
|
|
||||||
#define O_RDONLY 1
|
#define O_RDONLY 1
|
||||||
|
#define O_WRONLY 2
|
||||||
|
#define O_RDWR 3
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
|
@ -13,13 +13,15 @@ typedef struct
|
|||||||
int f_err;
|
int f_err;
|
||||||
} FILE;
|
} FILE;
|
||||||
|
|
||||||
|
extern FILE* __stderr;
|
||||||
|
extern FILE* __stdout;
|
||||||
|
#define stderr __stderr
|
||||||
|
#define stdout __stdout
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern FILE* stderr;
|
|
||||||
#define stderr stderr
|
|
||||||
int fclose(FILE*);
|
int fclose(FILE*);
|
||||||
int fflush(FILE*);
|
int fflush(FILE*);
|
||||||
FILE* fopen(const char*, const char*);
|
FILE* fopen(const char*, const char*);
|
||||||
|
@ -16,6 +16,7 @@ extern "C"
|
|||||||
unsigned int sleep(unsigned int);
|
unsigned int sleep(unsigned int);
|
||||||
|
|
||||||
ssize_t read(int, void*, size_t);
|
ssize_t read(int, void*, size_t);
|
||||||
|
ssize_t write(int, const void*, size_t);
|
||||||
int close(int);
|
int close(int);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
FILE* __stderr;
|
||||||
|
FILE* __stdout;
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
int fclose(FILE* stream)
|
int fclose(FILE* stream)
|
||||||
@ -29,7 +32,7 @@ extern "C"
|
|||||||
|
|
||||||
FILE* fopen(const char* pathname, const char*)
|
FILE* fopen(const char* pathname, const char*)
|
||||||
{
|
{
|
||||||
int fd = open(pathname, O_RDONLY); // FIXME: Use the mode string.
|
int fd = open(pathname, O_RDWR); // FIXME: Use the mode string.
|
||||||
if (fd < 0) { return 0; }
|
if (fd < 0) { return 0; }
|
||||||
FILE* stream = (FILE*)malloc(sizeof(FILE));
|
FILE* stream = (FILE*)malloc(sizeof(FILE));
|
||||||
stream->f_fd = fd;
|
stream->f_fd = fd;
|
||||||
@ -74,9 +77,16 @@ extern "C"
|
|||||||
NOT_IMPLEMENTED("ftell");
|
NOT_IMPLEMENTED("ftell");
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t fwrite(const void*, size_t, size_t, FILE*)
|
size_t fwrite(const void* buf, size_t size, size_t nmemb, FILE* stream)
|
||||||
{
|
{
|
||||||
NOT_IMPLEMENTED("fwrite");
|
ssize_t status = write(stream->f_fd, buf, size * nmemb);
|
||||||
|
if (status < 0)
|
||||||
|
{
|
||||||
|
stream->f_err = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (status == 0) stream->f_eof = 1;
|
||||||
|
return (size_t)status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setbuf(FILE*, char*)
|
void setbuf(FILE*, char*)
|
||||||
|
14
libs/libc/src/init.cpp
Normal file
14
libs/libc/src/init.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
extern "C" void initialize_libc()
|
||||||
|
{
|
||||||
|
__stderr = fopen("/dev/console", "rw");
|
||||||
|
if (!stderr) exit(errno);
|
||||||
|
__stdout = fopen("/dev/console", "rw");
|
||||||
|
if (!stdout) exit(errno);
|
||||||
|
clearerr(__stderr);
|
||||||
|
clearerr(__stdout);
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
#include <luna.h>
|
#include <luna.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
@ -20,7 +21,7 @@ extern "C"
|
|||||||
|
|
||||||
noreturn void __luna_abort(const char* message)
|
noreturn void __luna_abort(const char* message)
|
||||||
{
|
{
|
||||||
syscall(SYS_write, message, strlen(message));
|
fwrite(message, strlen(message), 1, stdout);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -306,8 +306,7 @@ extern "C"
|
|||||||
{
|
{
|
||||||
int vprintf(const char* format, va_list ap)
|
int vprintf(const char* format, va_list ap)
|
||||||
{
|
{
|
||||||
return internal_printf(
|
return vfprintf(stdout, format, ap);
|
||||||
format, [](const char* s) { syscall(SYS_write, s, strlen(s)); }, -1, ap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int vsprintf(char* str, const char* format, va_list ap)
|
int vsprintf(char* str, const char* format, va_list ap)
|
||||||
@ -352,23 +351,23 @@ extern "C"
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
int written = vprintf(format, ap);
|
int written = vfprintf(stdout, format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fprintf(FILE*, const char* format, ...) // FIXME: Make fprintf print to the selected file instead of stdout.
|
int fprintf(FILE* stream, const char* format, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
int written = vprintf(format, ap);
|
int written = vfprintf(stream, format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vfprintf(FILE*, const char* format,
|
int vfprintf(FILE* stream, const char* format, va_list ap)
|
||||||
va_list ap) // FIXME: Make vfprintf print to the selected file instead of stdout.
|
|
||||||
{
|
{
|
||||||
return vprintf(format, ap);
|
return internal_printf(
|
||||||
|
format, [&](const char* s) { fwrite(s, strlen(s), 1, stream); }, -1, ap);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,9 +10,9 @@ extern "C"
|
|||||||
{
|
{
|
||||||
int puts(const char* s)
|
int puts(const char* s)
|
||||||
{
|
{
|
||||||
long nwritten = syscall(SYS_write, s, strlen(s));
|
long nwritten = fwrite(s, strlen(s), 1, stdout);
|
||||||
if (nwritten < 0) return -1;
|
if (nwritten < 0) return -1;
|
||||||
nwritten += syscall(SYS_write, "\n", 1);
|
nwritten += fwrite("\n", 1, 1, stdout);
|
||||||
return (int)nwritten;
|
return (int)nwritten;
|
||||||
}
|
}
|
||||||
void perror(const char* s) // FIXME: Print to stderr, whenever we have an stderr.
|
void perror(const char* s) // FIXME: Print to stderr, whenever we have an stderr.
|
||||||
|
@ -37,7 +37,6 @@ extern "C"
|
|||||||
case SYS_exit:
|
case SYS_exit:
|
||||||
case SYS_close:
|
case SYS_close:
|
||||||
case SYS_sleep: result = __luna_syscall1(number, va_arg(ap, arg)); break;
|
case SYS_sleep: result = __luna_syscall1(number, va_arg(ap, arg)); break;
|
||||||
case SYS_write:
|
|
||||||
case SYS_munmap:
|
case SYS_munmap:
|
||||||
case SYS_open:
|
case SYS_open:
|
||||||
case SYS_getversion: {
|
case SYS_getversion: {
|
||||||
@ -46,6 +45,7 @@ extern "C"
|
|||||||
result = __luna_syscall2(number, arg0, arg1);
|
result = __luna_syscall2(number, arg0, arg1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SYS_write:
|
||||||
case SYS_read:
|
case SYS_read:
|
||||||
case SYS_mmap: {
|
case SYS_mmap: {
|
||||||
arg arg0 = va_arg(ap, arg);
|
arg arg0 = va_arg(ap, arg);
|
||||||
@ -80,6 +80,11 @@ extern "C"
|
|||||||
return syscall(SYS_read, fd, count, buf); // yes, our read() syscall is in the wrong order.
|
return syscall(SYS_read, fd, count, buf); // yes, our read() syscall is in the wrong order.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t write(int fd, const void* buf, size_t count)
|
||||||
|
{
|
||||||
|
return syscall(SYS_write, fd, count, buf); // yes, our read() syscall is in the wrong order.
|
||||||
|
}
|
||||||
|
|
||||||
int close(int fd)
|
int close(int fd)
|
||||||
{
|
{
|
||||||
return (int)syscall(SYS_close, fd);
|
return (int)syscall(SYS_close, fd);
|
||||||
|
Loading…
Reference in New Issue
Block a user