代码拉取完成,页面将自动刷新
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
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。