Skip to content

Commit 04d6cac

Browse files
syscalls: implement sys_link and epoll_ctl_del
Signed-off-by: Andy-Python-Programmer <[email protected]>
1 parent 77757c9 commit 04d6cac

File tree

7 files changed

+203
-11
lines changed

7 files changed

+203
-11
lines changed

aero.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,8 @@ def generate_docs(args):
397397

398398

399399
def prepare_iso(args, kernel_bin, user_bins):
400+
log_info("preparing ISO")
401+
400402
if not os.path.exists(BUILD_DIR):
401403
os.makedirs(BUILD_DIR)
402404

patches/mlibc/mlibc.patch

Lines changed: 117 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
From b4160476f4d1f02e0ea4550b66c9f9b478ab55fa Mon Sep 17 00:00:00 2001
1+
From 10e4288b75bcaa72e84cabe7af331cb95cbb1c86 Mon Sep 17 00:00:00 2001
22
From: Matt Taylor <[email protected]>
33
Date: Fri, 17 Jun 2022 15:28:34 +0100
44
Subject: [PATCH] abi-bits: add domainname to utsname
55

66
---
7-
ABI_BREAKS.md | 1 +
8-
abis/linux/utsname.h | 1 +
9-
options/glibc/generic/execinfo.cpp | 6 ++++--
10-
3 files changed, 6 insertions(+), 2 deletions(-)
7+
ABI_BREAKS.md | 1 +
8+
abis/linux/utsname.h | 1 +
9+
options/ansi/generic/stdlib-stubs.cpp | 100 ++++++++++++++++++++++----
10+
options/glibc/generic/execinfo.cpp | 6 +-
11+
4 files changed, 94 insertions(+), 14 deletions(-)
1112

1213
diff --git a/ABI_BREAKS.md b/ABI_BREAKS.md
1314
index 0cd3993b..d2a0bb7d 100644
@@ -30,6 +31,117 @@ index 2cd22265..9875a46e 100644
3031
};
3132

3233
#endif // _ABIBITS_UTSNAME_T_H
34+
diff --git a/options/ansi/generic/stdlib-stubs.cpp b/options/ansi/generic/stdlib-stubs.cpp
35+
index 375d4d72..2b4934d9 100644
36+
--- a/options/ansi/generic/stdlib-stubs.cpp
37+
+++ b/options/ansi/generic/stdlib-stubs.cpp
38+
@@ -374,18 +374,94 @@ int mblen(const char *mbs, size_t mb_limit) {
39+
return nseq.it - mbs;
40+
}
41+
42+
-int mbtowc(wchar_t *__restrict wc, const char *__restrict mbs, size_t max_size) {
43+
- mlibc::infoLogger() << "mlibc: Broken mbtowc() called" << frg::endlog;
44+
- __ensure(max_size);
45+
-
46+
- if(wc && mbs){
47+
- if(*mbs){
48+
- *wc = *mbs;
49+
- } else {
50+
- return 0; // When mbs is a null byte, return 0
51+
- }
52+
- }
53+
- return 1;
54+
+// Upper 6 state bits are a negative integer offset to bound-check next byte
55+
+// equivalent to: ( (b-0x80) | (b+offset) ) & ~0x3f
56+
+#define OOB(c, b) (((((b) >> 3) - 0x10) | (((b) >> 3) + ((int32_t)(c) >> 26))) & ~7)
57+
+
58+
+// Interval [a,b). Either a must be 80 or b must be c0, lower 3 bits clear.
59+
+#define R(a, b) ((uint32_t)((a == 0x80 ? 0x40u - b : 0u - a) << 23))
60+
+#define FAILSTATE R(0x80, 0x80)
61+
+
62+
+#define SA 0xc2u
63+
+#define SB 0xf4u
64+
+
65+
+// Arbitrary encoding for representing code units instead of characters.
66+
+#define CODEUNIT(c) (0xdfff & (signed char)(c))
67+
+#define IS_CODEUNIT(c) ((unsigned)(c)-0xdf80 < 0x80)
68+
+
69+
+#define C(x) ( x<2 ? -1 : ( R(0x80,0xc0) | x ) )
70+
+#define D(x) C((x+16))
71+
+#define E(x) ( ( x==0 ? R(0xa0,0xc0) : \
72+
+ x==0xd ? R(0x80,0xa0) : \
73+
+ R(0x80,0xc0) ) \
74+
+ | ( R(0x80,0xc0) >> 6 ) \
75+
+ | x )
76+
+#define F(x) ( ( x>=5 ? 0 : \
77+
+ x==0 ? R(0x90,0xc0) : \
78+
+ x==4 ? R(0x80,0xa0) : \
79+
+ R(0x80,0xc0) ) \
80+
+ | ( R(0x80,0xc0) >> 6 ) \
81+
+ | ( R(0x80,0xc0) >> 12 ) \
82+
+ | x )
83+
+
84+
+const uint32_t bittab[] = {
85+
+ C(0x2),C(0x3),C(0x4),C(0x5),C(0x6),C(0x7),
86+
+ C(0x8),C(0x9),C(0xa),C(0xb),C(0xc),C(0xd),C(0xe),C(0xf),
87+
+ D(0x0),D(0x1),D(0x2),D(0x3),D(0x4),D(0x5),D(0x6),D(0x7),
88+
+ D(0x8),D(0x9),D(0xa),D(0xb),D(0xc),D(0xd),D(0xe),D(0xf),
89+
+ E(0x0),E(0x1),E(0x2),E(0x3),E(0x4),E(0x5),E(0x6),E(0x7),
90+
+ E(0x8),E(0x9),E(0xa),E(0xb),E(0xc),E(0xd),E(0xe),E(0xf),
91+
+ F(0x0),F(0x1),F(0x2),F(0x3),F(0x4)
92+
+};
93+
+
94+
+// Converts a multibyte sequence to a wide character.
95+
+//
96+
+// Credits - MUSL
97+
+int mbtowc(wchar_t *__restrict wc, const char *__restrict src, size_t n) {
98+
+ unsigned c;
99+
+ const unsigned char *s = static_cast<const unsigned char *>((const void *)src);
100+
+ wchar_t dummy;
101+
+
102+
+ if (!s) return 0;
103+
+ if (!n) goto ilseq;
104+
+ if (!wc) wc = &dummy;
105+
+
106+
+ if (*s < 0x80) return !!(*wc = *s);
107+
+ if (MB_CUR_MAX == 1) return (*wc = CODEUNIT(*s)), 1;
108+
+ if (*s - SA > SB - SA) goto ilseq;
109+
+
110+
+ c = bittab[*s++ - SA];
111+
+
112+
+ // Avoid excessive checks against n: If shifting the state n-1
113+
+ // times does not clear the high bit, then the value of n is
114+
+ // insufficient to read a character.
115+
+ if (n < 4 && ((c << (6 * n - 6)) & (1U << 31))) goto ilseq;
116+
+ if (OOB(c, *s)) goto ilseq;
117+
+
118+
+ c = c << 6 | (*s++ - 0x80);
119+
+
120+
+ if (!(c & (1U << 31))) {
121+
+ *wc = c;
122+
+ return 2;
123+
+ }
124+
+
125+
+ if (*s - 0x80u >= 0x40) goto ilseq;
126+
+
127+
+ c = c << 6 | (*s++ - 0x80);
128+
+
129+
+ if (!(c & (1U << 31))) {
130+
+ *wc = c;
131+
+ return 3;
132+
+ }
133+
+
134+
+ if (*s - 0x80u >= 0x40) goto ilseq;
135+
+
136+
+ *wc = c << 6 | (*s++ - 0x80);
137+
+ return 4;
138+
+
139+
+ilseq:
140+
+ errno = EILSEQ;
141+
+ return -1;
142+
}
143+
144+
int wctomb(char *, wchar_t) {
33145
diff --git a/options/glibc/generic/execinfo.cpp b/options/glibc/generic/execinfo.cpp
34146
index 3474615e..c0081e30 100644
35147
--- a/options/glibc/generic/execinfo.cpp

src/aero_kernel/src/fs/epoll.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ impl EPoll {
4040
})
4141
}
4242

43-
/// Adds an event to the epoll instance.
43+
/// Adds an event to the interest list.
4444
///
4545
/// ## Errors
4646
/// * `EEXIST`: The event already exists at `fd`.
@@ -55,7 +55,22 @@ impl EPoll {
5555
Ok(())
5656
}
5757

58-
/// Change the settings associated with file derscriptor in the interest list to the
58+
/// Removes an event from the interest list.
59+
///
60+
/// ## Errors
61+
/// * `ENOENT`: The event does not exist at `fd`.
62+
pub fn remove_event(&self, fd: usize) -> Result<(), SyscallError> {
63+
let mut events = self.events.lock_irq();
64+
65+
if events.get(&fd).is_none() {
66+
return Err(SyscallError::ENOENT);
67+
}
68+
69+
events.remove(&fd);
70+
Ok(())
71+
}
72+
73+
/// Change the settings associated with file descriptor in the interest list to the
5974
/// new settings specified in event.
6075
///
6176
/// ## Errors

src/aero_kernel/src/fs/inode.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ pub trait INodeInterface: Send + Sync {
188188
fn poll(&self, _table: Option<&mut PollTable>) -> Result<EPollEventFlags> {
189189
Err(FileSystemError::NotSupported)
190190
}
191+
192+
fn link(&self, _name: &str, _src: INodeCacheItem) -> Result<()> {
193+
Err(FileSystemError::NotSupported)
194+
}
191195
}
192196

193197
/// Structure representing the curcial, characteristics of an inode. The metadata

src/aero_kernel/src/fs/mod.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ pub enum FileSystemError {
129129
Busy,
130130
NotDirectory,
131131
IsPipe,
132+
IsDir,
132133
Interrupted,
133134
TooSmall,
134135
InvalidPath,
@@ -150,6 +151,7 @@ impl From<FileSystemError> for SyscallError {
150151
FileSystemError::InvalidPath => Self::EINVAL,
151152
FileSystemError::NotSocket => Self::ENOTSOCK,
152153
FileSystemError::ConnectionRefused => Self::ECONNREFUSED,
154+
FileSystemError::IsDir => Self::EISDIR,
153155
}
154156
}
155157
}
@@ -219,7 +221,7 @@ pub fn lookup_path_with(
219221
mode: LookupMode,
220222
) -> Result<DirCacheItem> {
221223
// Iterate and resolve each component. For example `a`, `b`, and `c` in `a/b/c`.
222-
for component in path.components() {
224+
for (i, component) in path.components().enumerate() {
223225
match component {
224226
// Handle some special cases that might occur in a relative path.
225227
"." => continue,
@@ -250,7 +252,14 @@ pub fn lookup_path_with(
250252
if err == FileSystemError::EntryNotFound
251253
&& mode == LookupMode::Create =>
252254
{
253-
cwd = cwd.inode().touch(cwd.clone(), component)?;
255+
if i == path.components().count() - 1 {
256+
cwd = cwd.inode().touch(cwd.clone(), component)?;
257+
} else {
258+
// todo: fix this shit
259+
cwd.inode().mkdir(component)?;
260+
cwd =
261+
lookup_path_with(cwd, Path::new(component), LookupMode::None)?;
262+
}
254263
}
255264

256265
Err(err) => return Err(err),

src/aero_kernel/src/fs/ramfs.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use core::sync::atomic::{AtomicUsize, Ordering};
2626
use aero_syscall::prelude::EPollEventFlags;
2727
use aero_syscall::MMapFlags;
2828
use alloc::collections::BTreeMap;
29-
use alloc::string::String;
29+
use alloc::string::{String, ToString};
3030
use alloc::sync::{Arc, Weak};
3131

3232
use alloc::vec::Vec;
@@ -412,6 +412,34 @@ impl INodeInterface for LockedRamINode {
412412
fn weak_filesystem(&self) -> Option<Weak<dyn FileSystem>> {
413413
Some(self.0.read().filesystem.clone())
414414
}
415+
416+
fn link(&self, name: &str, src: INodeCacheItem) -> Result<()> {
417+
// ensure: The dest inode (self) is a directory.
418+
if self.metadata()?.file_type() != FileType::Directory {
419+
return Err(FileSystemError::NotDirectory);
420+
}
421+
422+
// ensure: The src inode is not a directory.
423+
if src.metadata()?.file_type() == FileType::Directory {
424+
return Err(FileSystemError::IsDir);
425+
}
426+
427+
// ensure: The dest directory does not already contain a
428+
// file with the same name.
429+
{
430+
let this = self.0.read();
431+
432+
if this.children.iter().find(|(e, _)| e == &name).is_some() {
433+
return Err(FileSystemError::EntryExists);
434+
}
435+
}
436+
437+
let mut this = self.0.write();
438+
439+
// Create the link!
440+
this.children.insert(name.to_string(), src.clone());
441+
Ok(())
442+
}
415443
}
416444

417445
/// Implementation of in-memory filesystem. (See the module-level documentation for more

src/aero_kernel/src/syscall/fs.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,11 @@ pub fn epoll_ctl(
436436
Ok(0)
437437
}
438438

439+
EPOLL_CTL_DEL => {
440+
epoll.remove_event(fd)?;
441+
Ok(0)
442+
}
443+
439444
EPOLL_CTL_MOD => {
440445
epoll.update_event(fd, event.clone())?;
441446
Ok(0)
@@ -494,8 +499,25 @@ pub fn event_fd(_initval: usize, flags: usize) -> Result<usize, SyscallError> {
494499
.open_file(entry, OpenFlags::O_RDWR)?)
495500
}
496501

502+
/// Creates a new link (also known as a hard link) to an existing
503+
/// file.
497504
#[syscall]
498505
pub fn link(src_path: &Path, dest_path: &Path) -> Result<usize, SyscallError> {
499-
log::warn!("sys_link: is a stub! (src_path={src_path:?}, dest_path={dest_path:?})");
506+
let src = fs::lookup_path(src_path)?.inode();
507+
let (dest_dir, dest_name) = dest_path.parent_and_basename();
508+
509+
let dest_dir = fs::lookup_path(dest_dir)?.inode();
510+
511+
// Cannot create a hardlink to a file on a different filesystem.
512+
//
513+
// SAFTEY: The pointers to the file system are valid since we know that there are
514+
// strong references to it.
515+
//
516+
// TODO: Should this be moved to the inode impl?
517+
if dest_dir.weak_filesystem().unwrap().as_ptr() != src.weak_filesystem().unwrap().as_ptr() {
518+
return Err(SyscallError::EINVAL);
519+
}
520+
521+
dest_dir.link(dest_name, src)?;
500522
Ok(0)
501523
}

0 commit comments

Comments
 (0)