问题描述
通过 Hermux 使用 vproc 的 create_process_s 创建 bash 子进程并连接 PTY 时,bash 报出以下警告:
bash: cannot set terminal process group (1120): Bad file descriptor
bash: no job control in this shell
bash 可以正常使用,但无法使用 job control(Ctrl+Z、fg、bg、& 后台任务等)。
根因分析
在传统的 fork/exec 流程中,子进程执行以下步骤:
setsid() — 创建新 session,成为 session leader
open(pts_slave, O_RDWR) — session leader 打开 PTY slave 会自动获得 controlling terminal
- bash 启动后调用
tcsetpgrp() 设置前台进程组 → job control 正常工作
但在 vproc 协程路径中:
- 协程在宿主进程内运行,不是独立的 OS 进程
- 没有
setsid() 调用,协程不是 session leader
- PTY slave fd 通过参数直接传入,但没有获得 controlling terminal
- bash 调用
tcsetpgrp(fd) 失败(EBADF 或 ENOTTY),因为该 fd 不是 controlling terminal
复现方式
Hermux 中的调用序列:
// 宿主进程打开 PTY master/slave
int ptm = open("/dev/ptmx", O_RDWR | O_CLOEXEC);
char devname[64];
grantpt(ptm); unlockpt(ptm); ptsname_r(ptm, devname, sizeof(devname));
int pts = open(devname, O_RDWR);
// 创建 vproc 进程,传入 pts 作为 stdin/stdout/stderr
uint32_t session_id = vproc_ffi_create_session();
uint32_t vpid = vproc_ffi_create_process(session_id, "/bin/bash", argv, envp, pts, pts, pts);
bash 启动后立即报上述警告。
建议修复方向
vproc_ffi_create_process 内部在启动协程的 shell 时,需要:
- 在协程上下文中调用
setsid()(或等效操作)使其成为 session leader
- 在协程内重新
open(pts_slave_path) 以获得 controlling terminal(session leader 首次打开 terminal 会自动成为 controlling terminal)
- 然后执行
dup2(pts, 0/1/2) 和 exec(cmd)
或者:如果 vproc 已经支持某种方式让协程获得 controlling terminal,请告知正确的调用方式。
相关链接
问题描述
通过 Hermux 使用 vproc 的
create_process_s创建 bash 子进程并连接 PTY 时,bash 报出以下警告:bash 可以正常使用,但无法使用 job control(
Ctrl+Z、fg、bg、&后台任务等)。根因分析
在传统的 fork/exec 流程中,子进程执行以下步骤:
setsid()— 创建新 session,成为 session leaderopen(pts_slave, O_RDWR)— session leader 打开 PTY slave 会自动获得 controlling terminaltcsetpgrp()设置前台进程组 → job control 正常工作但在 vproc 协程路径中:
setsid()调用,协程不是 session leadertcsetpgrp(fd)失败(EBADF或ENOTTY),因为该 fd 不是 controlling terminal复现方式
Hermux 中的调用序列:
bash 启动后立即报上述警告。
建议修复方向
vproc_ffi_create_process内部在启动协程的 shell 时,需要:setsid()(或等效操作)使其成为 session leaderopen(pts_slave_path)以获得 controlling terminal(session leader 首次打开 terminal 会自动成为 controlling terminal)dup2(pts, 0/1/2)和exec(cmd)或者:如果 vproc 已经支持某种方式让协程获得 controlling terminal,请告知正确的调用方式。
相关链接