1 Star 16 Fork 1

nature-lang/parker

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
util.n 3.75 KB
一键复制 编辑 原始数据 按行查看 历史
weiwenhao 提交于 2023-09-15 11:03 +08:00 . feat: first commit
import os
import fmt
import parker.cgroup
import libc_temp
import path
import time
import syscall
import parker.log as *
string charset = 'abcdefghijklmnopqrstuvwxyz0123456789'
fn arg_version():bool {
var args = os.args()
// 没有参数
if args.len == 1 {
return true
}
if args.len == 2 && (args[1] == '-v' || args[1] == '--version') {
return true
}
return false
}
fn arg_verbose():bool {
var flag = syscall.get_env('PARKER_VERBOSE')
return flag != ''
}
// 从 exe_path 中提取完整的数据
fn extract_tgz(string exe_path):[u8] {
var fd = syscall.open(exe_path, syscall.O_RDONLY, 0666)
syscall.seek(fd, -16, syscall.SEEK_END)
var size_buf = vec<u8>{len=16}
var len = syscall.read(fd, size_buf)
if len != size_buf.len {
syscall.close(fd)
throw fmt.sprintf('read fd len %d exception', len)
}
var size_str = size_buf as string
// atoi
var size = strtol(size_str.ref(), 0, 10)
if size == 0 {
throw 'extract tgz size is zero'
}
logf('read tgz tail 16 size=%d success', size)
syscall.seek(fd, -16 - size, syscall.SEEK_END)
// read result
var result = vec<u8>{len=size}
len = syscall.read(fd, result)
if len != size {
throw fmt.sprintf('read fd result len %d != size %d', len, size)
}
// close fd
syscall.close(fd)
return result
}
// 在 workdir 创建 mount 空间
fn mount_ns(string workdir) {
syscall.unshare(syscall.CLONE_NEWNS)
// mount /
syscall.mount('none', '/', '', syscall.MS_REC|syscall.MS_PRIVATE, "")
// mount("tmpfs", workdir, "tmpfs", 0, NULL)
syscall.mount('tmpfs', workdir, 'tmpfs', 0, '')
}
fn read_target(string workdir):string {
var target_path = path.join(workdir, '.target_name')
var fd = syscall.open(target_path, syscall.O_RDONLY, 0)
var target_buf = vec<u8>{len=1024}
var len = syscall.read(fd, target_buf)
target_buf = target_buf.slice(0, len)
var target_name = target_buf as string
return path.join(workdir, target_name)
}
fn run_target(cgroup.cgroup_t cg, string target_path):int {
// - fork 默认继承父进程的 mount ns
// - fork, 父进程直接返回 pid 即可
var pid = syscall.fork()
if pid > 0 {
// parent
return pid
}
// pdeathsig
// 1 = PR_SET_PDEATHSIG
// 9 = SIGKILL
var result = prctl(1, 9, 0, 0, 0)
if result == -1 {
throw fmt.sprintf('set pdeathsig err=%s', libc_strerror())
}
// 读取当前进程 id
pid = syscall.getpid()
logf('fork success, current is child, pid is %d', pid)
// 将 pid 注册到 cgroup 中
cg.register(pid)
// run target with all args and env
var args = os.args()
// args[0] 是 proc/:pid/comm, 这里替换成 target name
var target_name = path.base(target_path)
args[0] = target_name
// 通过 exec 进行进程启动
syscall.exec(target_path, args, syscall.get_envs())
logf('exec cannot execute it here')
return 0 // 正常不会执行到这里了
}
// 创建一个能够拦截所有信号且非阻塞的 fd
fn sig_notify():int {
var mask_ptr = new sigset_t // ptr<sigset_t>
// 注册所有信号
if sigfillset(mask_ptr) == -1 {
throw libc_strerror()
}
// 0 = SIG_BLOCK
if (sigprocmask(0, mask_ptr, null) == -1) {
throw libc_strerror()
}
var sigfd = signalfd(-1, mask_ptr, 2048)
if sigfd == -1 {
throw libc_strerror()
}
return sigfd as int
}
fn rand_letter(int len):string {
var result = vec<u8>{len=len}
srand(time.now().timestamp() as u32)
for i,v in result {
int char_index = rand() % charset.len
result[i] = charset[char_index]
}
return result as string
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
其他
1
https://gitee.com/nature-lang/parker.git
git@gitee.com:nature-lang/parker.git
nature-lang
parker
parker
master

搜索帮助