Compare commits

...

7 Commits

Author SHA1 Message Date
bef9158450 Kernel, libc: Add isatty() and F_ISTTY to fcntl() 2022-10-21 18:34:31 +02:00
93207820b3 libc: Add a few errors to errno.h
As well as ino_t, which I forgot in the fstat() commit :)
2022-10-21 18:34:01 +02:00
62fa773b27 libc: Add dummy argv 2022-10-21 18:33:06 +02:00
6d7a8a0d0b libc: Add very basic strtoul()
As well as returning NULL in getenv() instead of aborting.
2022-10-21 18:32:46 +02:00
bf026d0dea libc: Add bad time() function
It's just an alias for clock(). Which is not good. But it's a stub, that's the point.
2022-10-21 18:32:01 +02:00
c8a37eaf70 libc: Add SIGINT define 2022-10-21 18:31:19 +02:00
fcf191aa7a Kernel, libc: Add fstat() 2022-10-21 18:31:09 +02:00
26 changed files with 149 additions and 8 deletions

View File

@ -24,6 +24,11 @@ struct Descriptor
m_is_open = false;
}
VFS::Node* node()
{
return m_node;
}
ssize_t read(size_t size, char* buffer);
ssize_t write(size_t size, const char* buffer);

View File

@ -30,6 +30,7 @@ namespace VFS
node_finddir find_func;
node_mkdir mkdir_func;
node_write write_func;
int tty = 0;
Node* link;
};

View File

@ -3,6 +3,7 @@
#define EPERM 1
#define ENOENT 2
#define ESRCH 3
#define EINTR 4
#define ENOEXEC 8
#define EBADF 9
#define ENOMEM 12
@ -12,6 +13,7 @@
#define EISDIR 21
#define EINVAL 22
#define EMFILE 24
#define ENOTTY 25
#define ENOSPC 28
#define ENOSYS 38
#define ENOTSUP 95

View File

@ -22,6 +22,9 @@
#define SYS_fork 17
#define SYS_waitpid 18
#define SYS_access 19
#define SYS_fstat 20
struct stat;
namespace Syscall
{
@ -48,3 +51,4 @@ void sys_mkdir(Context* context, const char* filename);
void sys_fork(Context* context);
void sys_waitpid(Context* context, long pid, int* wstatus, int options);
void sys_access(Context* context, const char* path, int amode);
void sys_fstat(Context* context, int fd, struct stat* buf);

View File

@ -13,6 +13,7 @@ VFS::Node* ConsoleDevice::create_new(const char* devname)
dev->length = 0;
dev->type = VFS_DEVICE;
dev->flags = 0;
dev->tty = 1;
strncpy(dev->name, devname, sizeof(dev->name));
return dev;
}

View File

@ -19,6 +19,7 @@ VFS::Node* KeyboardDevice::create_new(const char* devname)
dev->length = 0;
dev->type = VFS_DEVICE;
dev->flags = 0;
dev->tty = 1;
strncpy(dev->name, devname, sizeof(dev->name));
return dev;
}

View File

@ -31,6 +31,7 @@ void Syscall::entry(Context* context)
case SYS_fork: sys_fork(context); break;
case SYS_waitpid: sys_waitpid(context, (long)context->rdi, (int*)context->rsi, (int)context->rdx); break;
case SYS_access: sys_access(context, (const char*)context->rdi, (int)context->rsi); break;
case SYS_fstat: sys_fstat(context, (int)context->rdi, (struct stat*)context->rsi); break;
default: context->rax = -ENOSYS; break;
}
VMM::exit_syscall_context();

44
kernel/src/sys/stat.cpp Normal file
View File

@ -0,0 +1,44 @@
#include "fs/VFS.h"
#include "interrupts/Context.h"
#include "std/errno.h"
#include "sys/UserMemory.h"
#include "thread/Scheduler.h"
typedef unsigned long off_t;
typedef unsigned short mode_t;
typedef unsigned long ino_t;
struct stat // FIXME: This struct is quite stubbed out.
{
ino_t st_ino;
mode_t st_mode;
off_t st_size;
};
void sys_fstat(Context* context, int fd, struct stat* buf)
{
Task* current_task = Scheduler::current_task();
if (fd < 0 || fd >= TASK_MAX_FDS)
{
context->rax = -EBADF;
return;
}
Descriptor& file = current_task->files[fd];
if (!file.is_open())
{
context->rax = -EBADF;
return;
}
struct stat* kstat = obtain_user_ref(buf);
if (!kstat)
{
context->rax = -EFAULT; // FIXME: The manual doesn't say fstat can return EFAULT, but it seems logical here...
return;
}
VFS::Node* node = file.node();
kstat->st_ino = node->inode;
kstat->st_mode = (mode_t)node->type;
kstat->st_size = node->length;
release_user_ref(kstat);
context->rax = 0;
}

View File

@ -19,7 +19,8 @@
#define SEEK_CUR 1
#define SEEK_END 2
#define FNCTL_DUPFD 0
#define FCNTL_DUPFD 0
#define FCNTL_ISTTY 1
void sys_fcntl(Context* context, int fd, int command, uintptr_t arg)
{
@ -35,7 +36,7 @@ void sys_fcntl(Context* context, int fd, int command, uintptr_t arg)
return;
}
Descriptor& file = current_task->files[fd];
if (command == FNCTL_DUPFD)
if (command == FCNTL_DUPFD)
{
if ((int)arg < 0 || (int)arg >= TASK_MAX_FDS)
{
@ -53,6 +54,14 @@ void sys_fcntl(Context* context, int fd, int command, uintptr_t arg)
kdbgln("fcntl(F_DUPFD): duplicated fd %d, result is %d", fd, dupfd);
return;
}
else if (command == FCNTL_ISTTY)
{
VFS::Node* node = file.node();
if (node->tty) { context->rax = 1; }
else
context->rax = -ENOTTY;
return;
}
else
{
context->rax = -EINVAL;

View File

@ -6,6 +6,8 @@ extern _fini
extern initialize_libc
extern exit
extern __argv
global _start
_start:
; Set up end of the stack frame linked list.
@ -19,7 +21,7 @@ _start:
call _init
mov rdi, 0 ; argc = 0
mov rsi, 0 ; argv = 0
mov rsi, __argv ; Dummy argv which is equal to {NULL}
call main

View File

@ -7,6 +7,7 @@ extern int errno;
#define EPERM 1 // Operation not permitted
#define ENOENT 2 // No such file or directory
#define ESRCH 3 // No such process
#define EINTR 4 // Interrupted system call. Not implemented.
#define ENOEXEC 8 // Exec format error
#define EBADF 9 // Bad file descriptor
#define ENOMEM 12 // Cannot allocate memory
@ -16,6 +17,7 @@ extern int errno;
#define EISDIR 21 // Is a directory
#define EINVAL 22 // Invalid argument
#define EMFILE 24 // Too many open files
#define ENOTTY 25 // Inappropriate ioctl for device
#define ENOSPC 28 // No space left on device
#define EPIPE 32 // Broken pipe. Not implemented.
#define ENOSYS 38 // Function not implemented

View File

@ -10,6 +10,8 @@
/* Duplicate a file descriptor. */
#define F_DUPFD 0
/* Is a file descriptor a TTY? */
#define F_ISTTY 1
#ifdef __cplusplus
extern "C"

View File

@ -0,0 +1,8 @@
#ifndef _LUNA_VFS_H
#define _LUNA_VFS_H
#define __VFS_FILE 0x0
#define __VFS_DIRECTORY 0x1
#define __VFS_DEVICE 0x2
#endif

View File

@ -1,7 +1,9 @@
#ifndef _SIGNAL_H
#define _SIGNAL_H
typedef int sig_atomic_t; // FIXME: Implement signals (I'm trying to build bc, this header is only to satisfy it) and
// use a proper atomic integer type.
typedef int sig_atomic_t; // On the x86, writes to aligned 32-bit and 64-bit integers are always atomic. (Or that's what
// I understood)
#define SIGINT 1 // Not implemented.
#endif

View File

@ -30,6 +30,9 @@ extern "C"
/* Returns an integer (of type long long) parsed from the string str. */
long long atoll(const char* str);
/* Returns an integer (of type unsigned long) parsed from the string str. */
unsigned long strtoul(const char* str, const char** endptr, int base);
/* Not implemented. */
char* getenv(const char*);

View File

@ -1,8 +1,18 @@
#ifndef _SYS_STAT_H
#define _SYS_STAT_H
#include <luna/vfs.h>
#include <sys/types.h>
struct stat // FIXME: This struct is quite stubbed out.
{
ino_t st_ino;
mode_t st_mode;
off_t st_size;
};
#define S_ISDIR(mode) (((mode)&0xf) == __VFS_DIRECTORY)
#ifdef __cplusplus
extern "C"
{
@ -11,6 +21,9 @@ extern "C"
/* Creates a new directory at the path pathname. FIXME: For now, mode is ignored. */
int mkdir(const char* pathname, mode_t mode);
/* Returns information about the file pointed to by fd in buf. */
int fstat(int fd, struct stat* buf);
#ifdef __cplusplus
}
#endif

View File

@ -21,5 +21,6 @@
#define SYS_fork 17
#define SYS_waitpid 18
#define SYS_access 19
#define SYS_fstat 20
#endif

View File

@ -16,4 +16,7 @@ typedef long int off_t;
/* The type of a file's mode. */
typedef unsigned short mode_t;
/* The type of a filesystem inode. */
typedef unsigned long ino_t;
#endif

View File

@ -15,6 +15,9 @@ extern "C"
* get the value in seconds. */
clock_t clock(void);
/* FIXME: For now, is an alias for clock(), but in seconds. */
time_t time(time_t* tloc);
#ifdef __cplusplus
}
#endif

View File

@ -66,6 +66,9 @@ extern "C"
/* Checks if the current program can access the file or directory at path. */
int access(const char* path, int amode);
/* Checks if the file descriptor fd refers to a terminal. */
int isatty(int fd);
#ifdef __cplusplus
}
#endif

View File

@ -4,6 +4,8 @@
#include <stdlib.h>
#include <unistd.h>
__attribute__((used)) const char* __argv[] = {NULL}; // For now.
static void terminate_libc()
{
fclose(stdout);

View File

@ -46,9 +46,16 @@ extern "C"
return string_to_integer_type<long long>(str);
}
unsigned long strtoul(const char* str, const char** endptr, int base)
{
if (base != 0 && base != 10) NOT_IMPLEMENTED("strtoul with base not in (0,10)");
if (endptr) NOT_IMPLEMENTED("strtoul with non-null endptr");
return string_to_integer_type<unsigned long>(str);
}
char* getenv(const char*)
{
NOT_IMPLEMENTED("getenv");
return NULL; // Not implemented :)
}
__lc_noreturn void _Exit(int status)

View File

@ -8,4 +8,9 @@ extern "C"
{
return (int)syscall(SYS_mkdir, pathname);
}
int fstat(int fd, struct stat* buf)
{
return (int)syscall(SYS_fstat, fd, buf);
}
}

View File

@ -23,6 +23,7 @@ extern "C" long syscall(long number, ...)
case SYS_sleep: result = __luna_syscall1(number, va_arg(ap, arg)); break;
case SYS_munmap:
case SYS_access:
case SYS_fstat:
case SYS_open: {
arg arg0 = va_arg(ap, arg);
arg arg1 = va_arg(ap, arg);

View File

@ -8,4 +8,13 @@ extern "C"
{
return syscall(SYS_clock);
}
time_t time(
time_t* tloc) // Very big FIXME: This is not the time of day, this just returns the same as clock() but in
// seconds. This is definitely wrong, but I'm not implementing a whole time system right now.
{
time_t result = (time_t)(syscall(SYS_clock) / CLOCKS_PER_SEC);
if (tloc) { *tloc = result; }
return result;
}
}

View File

@ -74,4 +74,11 @@ extern "C"
{
return (int)syscall(SYS_access, path, amode);
}
int isatty(int fd)
{
int result = fcntl(fd, F_ISTTY);
if (result < 0) return 0;
return 1;
}
}