You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C语言中如何通过fork+exec启动bash并解决终端接管及权限报错问题?

问题解决

1. 初始版本bash无法接管前台的问题

你原来的代码核心问题有两个:

  • fork后父进程直接退出,新启动的bash变成孤儿进程被init接管,默认在后台运行
  • 你没有把当前终端的前台进程组权限交给新的bash进程

不需要内核模块,用户态完全可以解决,修改逻辑如下:

  • 父进程fork后调用waitpid()阻塞等待子bash进程退出,不要直接返回
  • 子进程执行execl前先调用tcsetpgrp(STDIN_FILENO, getpid())获取终端前台控制权

2. 更新后代码的报错问题

setpgid报错

你调用setpgid(0,0)前没有创建新会话,进程还属于原来父shell的会话组,无法直接修改进程组归属,需要先执行以下操作:

  • 调用signal(SIGTTOU, SIG_IGN)忽略SIGTTOU信号,否则操作终端前台进程组时会触发信号导致进程停止
  • 先调用setsid()创建新会话,让当前进程成为会话首进程,之后再执行setpgid和tcsetpgrp操作

非root用户下setuid、chdir报错

你要切换到其他用户身份、修改终端所有者、进入其他用户的home目录,都需要root权限才能操作,你需要给编译后的可执行文件设置suid root权限:

chown root:root 你的可执行文件名
chmod u+s 你的可执行文件名

注意:设置suid root后程序会以root身份启动,你必须做好密码校验逻辑避免权限泄露。你现有代码里setgid放在setuid前面的顺序是对的,没有root权限这两个调用必然失败。

3. /dev/chardev写入无权限问题

文件系统层面的0666权限只控制文件系统调用的准入,你遇到的权限报错大概率是字符设备驱动内部做了权限校验,比如write接口里判断当前进程的uid是不是root,即使你文件权限开了0666也会被驱动拦截。你需要修改字符设备驱动代码,去掉uid校验逻辑,或者调整校验规则允许目标用户写入。

内容的提问来源于stack exchange,提问作者Ori

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 09:24:03