mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-29 00:27:52 +01:00
Hacky getdents
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
/*-
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)dirent.h 8.1 (Berkeley) 6/2/93
|
||||
*/
|
||||
|
||||
#ifndef _SYS_DIRENT_H_
|
||||
#define _SYS_DIRENT_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/syslimits.h>
|
||||
|
||||
/*
|
||||
* The dirent structure defines the format of directory entries returned by
|
||||
* the getdirentries(2) system call.
|
||||
*
|
||||
* A directory entry has a struct dirent at the front of it, containing its
|
||||
* inode number, the length of the entry, and the length of the name
|
||||
* contained in the entry. These are followed by the name padded to a 4
|
||||
* byte boundary with null bytes. All names are guaranteed null terminated.
|
||||
* The maximum length of a name in a directory is MAXNAMLEN.
|
||||
*/
|
||||
|
||||
struct dirent {
|
||||
unsigned long d_fileno; /* file number of entry */
|
||||
unsigned short d_reclen; /* length of this record */
|
||||
unsigned char d_type; /* file type, see below */
|
||||
unsigned char d_namlen; /* length of string in d_name */
|
||||
char d_name[NAME_MAX + 1]; /* name must be no longer than this */
|
||||
};
|
||||
|
||||
/*
|
||||
* File types
|
||||
*/
|
||||
#define DT_UNKNOWN 0
|
||||
#define DT_FIFO 1
|
||||
#define DT_CHR 2
|
||||
#define DT_DIR 4
|
||||
#define DT_BLK 6
|
||||
#define DT_REG 8
|
||||
#define DT_LNK 10
|
||||
#define DT_SOCK 12
|
||||
|
||||
/*
|
||||
* Convert between stat structure types and directory types.
|
||||
*/
|
||||
#define IFTODT(mode) (((mode) & 0170000) >> 12)
|
||||
#define DTTOIF(dirtype) ((dirtype) << 12)
|
||||
|
||||
/*
|
||||
* The kernel defines the format of directory entries returned by
|
||||
* the getdirentries(2) system call.
|
||||
*/
|
||||
|
||||
#define d_ino d_fileno /* backward compatibility */
|
||||
|
||||
/* structure describing an open directory. */
|
||||
typedef struct _dirdesc {
|
||||
int dd_fd; /* file descriptor associated with directory */
|
||||
long dd_loc; /* offset in current buffer */
|
||||
long dd_size; /* amount of data returned by getdirentries */
|
||||
char *dd_buf; /* data buffer */
|
||||
int dd_len; /* size of data buffer */
|
||||
long dd_seek; /* magic cookie returned by getdirentries */
|
||||
long dd_rewind; /* magic cookie for rewinding */
|
||||
} DIR;
|
||||
|
||||
//#define dirfd(dirp) ((dirp)->dd_fd)
|
||||
|
||||
#endif /* !_SYS_DIRENT_H_ */
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#define SYSCALL_EXIT_ID 0
|
||||
|
||||
@@ -98,6 +99,10 @@ int _write(int file, char *ptr, int len) {
|
||||
return _do_syscall(SYSCALL_WRITE_ID, file, (uint64_t) ptr, len);
|
||||
}
|
||||
|
||||
int getdents(int fd, struct dirent *dp, int count) {
|
||||
return _do_syscall(SYSCALL_READDIR_ID, fd, (uint64_t) dp, count);
|
||||
}
|
||||
|
||||
int sleep(int seconds) {
|
||||
return _do_syscall(SYSCALL_SLEEP_ID, seconds * 1000, 0, 0);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "VMA.hpp"
|
||||
#include "syscalls_defs.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
|
||||
#include "TtyManager.hpp"
|
||||
@@ -212,6 +213,42 @@ char *syscall_sbrk(int brk) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
struct dirent {
|
||||
unsigned long d_fileno; /* file number of entry */
|
||||
unsigned short d_reclen; /* length of this record */
|
||||
unsigned char d_type; /* file type, see below */
|
||||
unsigned char d_namlen; /* length of string in d_name */
|
||||
char d_name[255 + 1]; /* name must be no longer than this */
|
||||
};
|
||||
|
||||
|
||||
int64_t syscall_getdents(int fd, struct dirent *dp, int count) {
|
||||
auto f = FDT::current()->get(fd);
|
||||
if (!f) return -1;
|
||||
|
||||
auto dir = f->dir();
|
||||
if (dir.get() == nullptr) return -1;
|
||||
|
||||
auto children = dir->children();
|
||||
|
||||
count /= sizeof(dirent);
|
||||
|
||||
if (f->pos() >= children.size()) return 0;
|
||||
|
||||
count = std::min(children.size() - f->pos(), (size_t) count);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
auto &child = children[i + f->pos()];
|
||||
dp[i].d_fileno = i + f->pos() + 1;
|
||||
strncpy(dp[i].d_name, child->name().c_str(), 255);
|
||||
dp[i].d_name[child->name().length() + 1] = '\0';
|
||||
dp[i].d_namlen = child->name().length();
|
||||
dp[i].d_reclen = sizeof(dirent);
|
||||
dp[i].d_type = child->type() == Node::DIR ? 4 : 8;
|
||||
}
|
||||
f->seek(count + f->pos());
|
||||
return count * sizeof(dirent);
|
||||
}
|
||||
|
||||
extern "C" uint64_t syscall_impl(uint64_t id_rdi, uint64_t a1_rsi, uint64_t a2_rdx, uint64_t a3_rcx) {
|
||||
assert2(are_interrupts_enabled(), "why wouldn't they be?");
|
||||
@@ -241,10 +278,13 @@ extern "C" uint64_t syscall_impl(uint64_t id_rdi, uint64_t a1_rsi, uint64_t a2_r
|
||||
case SYSCALL_SBRK_ID:
|
||||
return reinterpret_cast<uint64_t>(syscall_sbrk(static_cast<int64_t>(a1_rsi)));
|
||||
case SYSCALL_OPENDIR_ID:
|
||||
return -1;
|
||||
case SYSCALL_READDIR_ID:
|
||||
return syscall_getdents(static_cast<int64_t>(a1_rsi), reinterpret_cast<dirent *>(a2_rdx), static_cast<int64_t>(a3_rcx));
|
||||
case SYSCALL_CLOSEDIR_ID:
|
||||
case SYSCALL_MKDIR_ID:
|
||||
case SYSCALL_UNLINK_ID:
|
||||
return -1;
|
||||
case SYSCALL_PRINT_TASKS:
|
||||
return syscall_print_tasks();
|
||||
case SYSCALL_PRINT_MEM:
|
||||
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
SharedPtr<NodeFile> file() const;
|
||||
|
||||
uint64_t seek(uint64_t pos);
|
||||
uint64_t pos() { return _pos; }
|
||||
uint64_t read(char *buf, uint64_t size);
|
||||
uint64_t write(const char *buf, uint64_t size);
|
||||
uint64_t size();
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 22.03.2024.
|
||||
//
|
||||
|
||||
#ifndef FICUS_DIRENT_H
|
||||
#define FICUS_DIRENT_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdint>
|
||||
extern "C" {
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
struct dirent {
|
||||
uint64_t inode_n;
|
||||
char d_name[];
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif //FICUS_DIRENT_H
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef FICUS_SYSCALLS_DEFS_H
|
||||
#define FICUS_SYSCALLS_DEFS_H
|
||||
|
||||
// FIXME!: Don't duplicate this please
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdint>
|
||||
extern "C" {
|
||||
|
||||
Reference in New Issue
Block a user