gpt4 book ai didi

c - 伪终端问题(Mac/Linux): SIGTTOU & Inappropriate ioctl

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:37:11 26 4
gpt4 key购买 nike

我正在开发一个伪终端库。该代码是用 C 代码实现的,该代码由基于 Web 的终端使用。只要我不使用 sudo 或登录,代码就可以工作。

这是我在 Mac 上运行服务器时遇到的错误:

sh-3.2$ sudo ls
Password:
[1]+ Stopped(SIGTTOU)
sh-3.2$

以上适用于 Linux:

$ sudo ls
readme.txt

但是,我在 Linux 上使用 sudo bash 得到以下结果:

$ sudo bash
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
]0;root@ubuntu: /tmproot@ubuntu:/tmp#

注意:上面的工作,但我没有工作控制权。

我可能忘记在终端上设置一些控制位,但谷歌并没有帮助找到它。另外,你知道有什么好书很详细地解释了伪终端管理。

我有 setsid 调用,但我没有使用 openpty。打开 pty 时我使用以下代码:

static int createPty(lua_State* L, char* ttyName, int* pty)
{
*pty = getpt();
if (*pty < 0 || grantpt(*pty) < 0 || unlockpt(*pty) < 0)
return lDoErr(L,"Cannot open PTY: %s",strerror(errno));
if(ptsname_r(*pty, ttyName, PTY_NAME_SIZE-1))
return lDoErr(L,"ptsname_r: %s",strerror(errno));
return 0;
}

我已经编辑了下面的代码并且这段代码有效。我的第一个版本不起作用的原因是我试图创建两个 PTY channel 。我希望能够区分 stdout 和 stderr,但 Linux 内核不允许多次调用 TIOCSCTTY。

static int
childOpenTTY(const char* ttyName)
{
struct termios termbuf;
int fd=open(ttyName, O_RDWR);
if(fd < 0)
doClientError("open %s: %s",ttyName, strerror(errno));
tcsetpgrp(fd, getpid());
ioctl(fd,TIOCSCTTY,NULL);
tcgetattr(fd, &termbuf);
cfmakeraw(&termbuf); /* turn off NL to CR/NL mapping on output. */
tcsetattr(fd, TCSANOW, &termbuf);
return fd;
}

if( (ret = createPty(L, ttyName, &te->pty)) != 0)
return ret;
if ((te->pid = zzbafork()) < 0)
return lDoErr(L,"fork: %s",strerror(errno));
if(te->pid == 0)
{ /* Child process */
static const char efmt[]={"Cannot set '%s' (dup2 err)"};
int fd;
if(setsid() < 0) /* make new process group */
doClientError("setsid: %s",strerror(errno));
fd=childOpenTTY(ttyName);
if(dup2(fd, STDIN_FILENO) != STDIN_FILENO)
doClientError(efmt,"stdin");
if(dup2(fd, STDOUT_FILENO) != STDOUT_FILENO)
doClientError(efmt,"stdout");
if(dup2(fd, STDERR_FILENO) != STDERR_FILENO)
doClientError(efmt,"stderr");
if(fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != STDERR_FILENO)
close(fd);
execve(cmd, (char**)cmdArgv, environ);
/* execve should not return, unless error exec cmd */
doClientError("Executing %s failed: %s",cmd,strerror(errno));
}

最佳答案

很难确定,因为此处没有显示实际代码,但我怀疑您遇到了 POSIX 样式的“ session ”管理。您需要执行 setsid 调用,然后打开 pty(从端),使其成为控制终端。 openptylogin_tty 例程为您完成低级垃圾工作;你在用那些吗?

关于c - 伪终端问题(Mac/Linux): SIGTTOU & Inappropriate ioctl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15529761/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com