Compare commits
7 Commits
0720b3245b
...
bef9158450
Author | SHA1 | Date | |
---|---|---|---|
bef9158450 | |||
93207820b3 | |||
62fa773b27 | |||
6d7a8a0d0b | |||
bf026d0dea | |||
c8a37eaf70 | |||
fcf191aa7a |
@ -24,6 +24,11 @@ struct Descriptor
|
|||||||
m_is_open = false;
|
m_is_open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VFS::Node* node()
|
||||||
|
{
|
||||||
|
return m_node;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
ssize_t write(size_t size, const char* buffer);
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ namespace VFS
|
|||||||
node_finddir find_func;
|
node_finddir find_func;
|
||||||
node_mkdir mkdir_func;
|
node_mkdir mkdir_func;
|
||||||
node_write write_func;
|
node_write write_func;
|
||||||
|
int tty = 0;
|
||||||
Node* link;
|
Node* link;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#define EPERM 1
|
#define EPERM 1
|
||||||
#define ENOENT 2
|
#define ENOENT 2
|
||||||
#define ESRCH 3
|
#define ESRCH 3
|
||||||
|
#define EINTR 4
|
||||||
#define ENOEXEC 8
|
#define ENOEXEC 8
|
||||||
#define EBADF 9
|
#define EBADF 9
|
||||||
#define ENOMEM 12
|
#define ENOMEM 12
|
||||||
@ -12,6 +13,7 @@
|
|||||||
#define EISDIR 21
|
#define EISDIR 21
|
||||||
#define EINVAL 22
|
#define EINVAL 22
|
||||||
#define EMFILE 24
|
#define EMFILE 24
|
||||||
|
#define ENOTTY 25
|
||||||
#define ENOSPC 28
|
#define ENOSPC 28
|
||||||
#define ENOSYS 38
|
#define ENOSYS 38
|
||||||
#define ENOTSUP 95
|
#define ENOTSUP 95
|
@ -22,6 +22,9 @@
|
|||||||
#define SYS_fork 17
|
#define SYS_fork 17
|
||||||
#define SYS_waitpid 18
|
#define SYS_waitpid 18
|
||||||
#define SYS_access 19
|
#define SYS_access 19
|
||||||
|
#define SYS_fstat 20
|
||||||
|
|
||||||
|
struct stat;
|
||||||
|
|
||||||
namespace Syscall
|
namespace Syscall
|
||||||
{
|
{
|
||||||
@ -47,4 +50,5 @@ void sys_clock(Context* context);
|
|||||||
void sys_mkdir(Context* context, const char* filename);
|
void sys_mkdir(Context* context, const char* filename);
|
||||||
void sys_fork(Context* context);
|
void sys_fork(Context* context);
|
||||||
void sys_waitpid(Context* context, long pid, int* wstatus, int options);
|
void sys_waitpid(Context* context, long pid, int* wstatus, int options);
|
||||||
void sys_access(Context* context, const char* path, int amode);
|
void sys_access(Context* context, const char* path, int amode);
|
||||||
|
void sys_fstat(Context* context, int fd, struct stat* buf);
|
||||||
|
@ -13,6 +13,7 @@ VFS::Node* ConsoleDevice::create_new(const char* devname)
|
|||||||
dev->length = 0;
|
dev->length = 0;
|
||||||
dev->type = VFS_DEVICE;
|
dev->type = VFS_DEVICE;
|
||||||
dev->flags = 0;
|
dev->flags = 0;
|
||||||
|
dev->tty = 1;
|
||||||
strncpy(dev->name, devname, sizeof(dev->name));
|
strncpy(dev->name, devname, sizeof(dev->name));
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ VFS::Node* KeyboardDevice::create_new(const char* devname)
|
|||||||
dev->length = 0;
|
dev->length = 0;
|
||||||
dev->type = VFS_DEVICE;
|
dev->type = VFS_DEVICE;
|
||||||
dev->flags = 0;
|
dev->flags = 0;
|
||||||
|
dev->tty = 1;
|
||||||
strncpy(dev->name, devname, sizeof(dev->name));
|
strncpy(dev->name, devname, sizeof(dev->name));
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,8 @@ void Syscall::entry(Context* context)
|
|||||||
case SYS_fork: sys_fork(context); break;
|
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_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_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;
|
default: context->rax = -ENOSYS; break;
|
||||||
}
|
}
|
||||||
VMM::exit_syscall_context();
|
VMM::exit_syscall_context();
|
||||||
}
|
}
|
||||||
|
44
kernel/src/sys/stat.cpp
Normal file
44
kernel/src/sys/stat.cpp
Normal 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;
|
||||||
|
}
|
@ -19,7 +19,8 @@
|
|||||||
#define SEEK_CUR 1
|
#define SEEK_CUR 1
|
||||||
#define SEEK_END 2
|
#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)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
Descriptor& file = current_task->files[fd];
|
Descriptor& file = current_task->files[fd];
|
||||||
if (command == FNCTL_DUPFD)
|
if (command == FCNTL_DUPFD)
|
||||||
{
|
{
|
||||||
if ((int)arg < 0 || (int)arg >= TASK_MAX_FDS)
|
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);
|
kdbgln("fcntl(F_DUPFD): duplicated fd %d, result is %d", fd, dupfd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (command == FCNTL_ISTTY)
|
||||||
|
{
|
||||||
|
VFS::Node* node = file.node();
|
||||||
|
if (node->tty) { context->rax = 1; }
|
||||||
|
else
|
||||||
|
context->rax = -ENOTTY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context->rax = -EINVAL;
|
context->rax = -EINVAL;
|
||||||
|
@ -6,6 +6,8 @@ extern _fini
|
|||||||
extern initialize_libc
|
extern initialize_libc
|
||||||
extern exit
|
extern exit
|
||||||
|
|
||||||
|
extern __argv
|
||||||
|
|
||||||
global _start
|
global _start
|
||||||
_start:
|
_start:
|
||||||
; Set up end of the stack frame linked list.
|
; Set up end of the stack frame linked list.
|
||||||
@ -19,7 +21,7 @@ _start:
|
|||||||
call _init
|
call _init
|
||||||
|
|
||||||
mov rdi, 0 ; argc = 0
|
mov rdi, 0 ; argc = 0
|
||||||
mov rsi, 0 ; argv = 0
|
mov rsi, __argv ; Dummy argv which is equal to {NULL}
|
||||||
|
|
||||||
call main
|
call main
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ extern int errno;
|
|||||||
#define EPERM 1 // Operation not permitted
|
#define EPERM 1 // Operation not permitted
|
||||||
#define ENOENT 2 // No such file or directory
|
#define ENOENT 2 // No such file or directory
|
||||||
#define ESRCH 3 // No such process
|
#define ESRCH 3 // No such process
|
||||||
|
#define EINTR 4 // Interrupted system call. Not implemented.
|
||||||
#define ENOEXEC 8 // Exec format error
|
#define ENOEXEC 8 // Exec format error
|
||||||
#define EBADF 9 // Bad file descriptor
|
#define EBADF 9 // Bad file descriptor
|
||||||
#define ENOMEM 12 // Cannot allocate memory
|
#define ENOMEM 12 // Cannot allocate memory
|
||||||
@ -16,6 +17,7 @@ extern int errno;
|
|||||||
#define EISDIR 21 // Is a directory
|
#define EISDIR 21 // Is a directory
|
||||||
#define EINVAL 22 // Invalid argument
|
#define EINVAL 22 // Invalid argument
|
||||||
#define EMFILE 24 // Too many open files
|
#define EMFILE 24 // Too many open files
|
||||||
|
#define ENOTTY 25 // Inappropriate ioctl for device
|
||||||
#define ENOSPC 28 // No space left on device
|
#define ENOSPC 28 // No space left on device
|
||||||
#define EPIPE 32 // Broken pipe. Not implemented.
|
#define EPIPE 32 // Broken pipe. Not implemented.
|
||||||
#define ENOSYS 38 // Function not implemented
|
#define ENOSYS 38 // Function not implemented
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
/* Duplicate a file descriptor. */
|
/* Duplicate a file descriptor. */
|
||||||
#define F_DUPFD 0
|
#define F_DUPFD 0
|
||||||
|
/* Is a file descriptor a TTY? */
|
||||||
|
#define F_ISTTY 1
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
|
8
libs/libc/include/luna/vfs.h
Normal file
8
libs/libc/include/luna/vfs.h
Normal 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
|
@ -1,7 +1,9 @@
|
|||||||
#ifndef _SIGNAL_H
|
#ifndef _SIGNAL_H
|
||||||
#define _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
|
typedef int sig_atomic_t; // On the x86, writes to aligned 32-bit and 64-bit integers are always atomic. (Or that's what
|
||||||
// use a proper atomic integer type.
|
// I understood)
|
||||||
|
|
||||||
|
#define SIGINT 1 // Not implemented.
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -30,6 +30,9 @@ extern "C"
|
|||||||
/* Returns an integer (of type long long) parsed from the string str. */
|
/* Returns an integer (of type long long) parsed from the string str. */
|
||||||
long long atoll(const char* 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. */
|
/* Not implemented. */
|
||||||
char* getenv(const char*);
|
char* getenv(const char*);
|
||||||
|
|
||||||
|
@ -1,8 +1,18 @@
|
|||||||
#ifndef _SYS_STAT_H
|
#ifndef _SYS_STAT_H
|
||||||
#define _SYS_STAT_H
|
#define _SYS_STAT_H
|
||||||
|
|
||||||
|
#include <luna/vfs.h>
|
||||||
#include <sys/types.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
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@ -11,6 +21,9 @@ extern "C"
|
|||||||
/* Creates a new directory at the path pathname. FIXME: For now, mode is ignored. */
|
/* Creates a new directory at the path pathname. FIXME: For now, mode is ignored. */
|
||||||
int mkdir(const char* pathname, mode_t mode);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,5 +21,6 @@
|
|||||||
#define SYS_fork 17
|
#define SYS_fork 17
|
||||||
#define SYS_waitpid 18
|
#define SYS_waitpid 18
|
||||||
#define SYS_access 19
|
#define SYS_access 19
|
||||||
|
#define SYS_fstat 20
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -16,4 +16,7 @@ typedef long int off_t;
|
|||||||
/* The type of a file's mode. */
|
/* The type of a file's mode. */
|
||||||
typedef unsigned short mode_t;
|
typedef unsigned short mode_t;
|
||||||
|
|
||||||
|
/* The type of a filesystem inode. */
|
||||||
|
typedef unsigned long ino_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -15,6 +15,9 @@ extern "C"
|
|||||||
* get the value in seconds. */
|
* get the value in seconds. */
|
||||||
clock_t clock(void);
|
clock_t clock(void);
|
||||||
|
|
||||||
|
/* FIXME: For now, is an alias for clock(), but in seconds. */
|
||||||
|
time_t time(time_t* tloc);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -66,6 +66,9 @@ extern "C"
|
|||||||
/* Checks if the current program can access the file or directory at path. */
|
/* Checks if the current program can access the file or directory at path. */
|
||||||
int access(const char* path, int amode);
|
int access(const char* path, int amode);
|
||||||
|
|
||||||
|
/* Checks if the file descriptor fd refers to a terminal. */
|
||||||
|
int isatty(int fd);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
__attribute__((used)) const char* __argv[] = {NULL}; // For now.
|
||||||
|
|
||||||
static void terminate_libc()
|
static void terminate_libc()
|
||||||
{
|
{
|
||||||
fclose(stdout);
|
fclose(stdout);
|
||||||
|
@ -46,9 +46,16 @@ extern "C"
|
|||||||
return string_to_integer_type<long long>(str);
|
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*)
|
char* getenv(const char*)
|
||||||
{
|
{
|
||||||
NOT_IMPLEMENTED("getenv");
|
return NULL; // Not implemented :)
|
||||||
}
|
}
|
||||||
|
|
||||||
__lc_noreturn void _Exit(int status)
|
__lc_noreturn void _Exit(int status)
|
||||||
|
@ -8,4 +8,9 @@ extern "C"
|
|||||||
{
|
{
|
||||||
return (int)syscall(SYS_mkdir, pathname);
|
return (int)syscall(SYS_mkdir, pathname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fstat(int fd, struct stat* buf)
|
||||||
|
{
|
||||||
|
return (int)syscall(SYS_fstat, fd, buf);
|
||||||
|
}
|
||||||
}
|
}
|
@ -23,6 +23,7 @@ extern "C" long syscall(long number, ...)
|
|||||||
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_munmap:
|
case SYS_munmap:
|
||||||
case SYS_access:
|
case SYS_access:
|
||||||
|
case SYS_fstat:
|
||||||
case SYS_open: {
|
case SYS_open: {
|
||||||
arg arg0 = va_arg(ap, arg);
|
arg arg0 = va_arg(ap, arg);
|
||||||
arg arg1 = va_arg(ap, arg);
|
arg arg1 = va_arg(ap, arg);
|
||||||
|
@ -8,4 +8,13 @@ extern "C"
|
|||||||
{
|
{
|
||||||
return syscall(SYS_clock);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
@ -74,4 +74,11 @@ extern "C"
|
|||||||
{
|
{
|
||||||
return (int)syscall(SYS_access, path, amode);
|
return (int)syscall(SYS_access, path, amode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int isatty(int fd)
|
||||||
|
{
|
||||||
|
int result = fcntl(fd, F_ISTTY);
|
||||||
|
if (result < 0) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user