-
Notifications
You must be signed in to change notification settings - Fork 27
/
main.n
109 lines (89 loc) · 2.32 KB
/
main.n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import path
import syscall
import libc_temp
import dirent_temp
import syscall_temp
import strings_temp
fn args():[string] {
return std_args()
}
// read current exe path by read link /proc/self/exe
fn exe():string {
var buf = vec_new<u8>(4096, 0)
var len = syscall.readlink('/proc/self/exe', buf)
buf = buf.slice(0, len)
return buf as string
}
fn dirs_sort([string] dirs) {
var n = dirs.len()
for int i = 0; i < n-1; i+=1 {
for int j = 0; j < n-i-1; j+=1 {
if dirs[j] > dirs[j+1] {
(dirs[j], dirs[j+1]) = (dirs[j+1], dirs[j])
}
}
}
}
// unsafe ptr
// The order of return is uncertain
fn listdir(string path):[string] {
[string] result = []
var dir = opendir(path.ref())
if dir == 0 {
throw 'opendir failed: ' + libc_strerror()
}
for true {
// raw_ptr 可以接收 null 或者具体的指针值,可以通过 *语法解构原始值
raw_ptr<dirent_t> entry = readdir(dir)
if entry == null {
break
}
// dirent_t dirent = *entry
var name = libc_string_new(entry.name as void_ptr)
if name == '.' || name == '..' {
continue
}
result.push(name)
}
dirs_sort(result)
return result
}
// use strings.split(dir, '/')
// join and syscall.mkdir(dir, mode)
fn mkdirs(string dir, u32 mode) {
if dir == '' {
throw 'dir is empty'
}
if path.exists(dir) {
return
}
// path not found will create
var parent_dir = path.dir(dir)
mkdirs(parent_dir, mode)
// parent dir is create, will create dir
syscall.mkdir(dir, mode)
}
// use remove file
fn remove(string full_path) {
if !path.exists(full_path) {
return
}
syscall.unlink(full_path)
}
fn rmdir(string dir, bool recursive) {
if !recursive {
return syscall.rmdir(dir)
}
var list = listdir(dir)
for item in list {
var fullpath = path.join(dir, item)
if path.isdir(fullpath) {
rmdir(fullpath, true) // 递归删除其中的所有文件
} else {
// rm file 可能存在权限不足的错误,暂时不做错误判断,直接跳过即可
remove(fullpath) catch err {}
}
}
// sub already remove, remove self
syscall.rmdir(dir)
}