我编写了一个小的ncurses工具来运行应用程序。我想要实现的是,在按下回车键并成功创建新进程后,我想退出我的ncurses应用程序并关闭终端。
我用termite -e my_app
运行我的应用程序(每个其他具有-e选项的终端模拟器也应该没问题)。在my_app退出后,终端可能会关闭,但我不能让父母退出。
我尝试将exit(0)
添加到标记有注释的代码中的位置,但在这种情况下,我无法再打开应用程序(我猜它会在其父级退出时立即退出)。
我也试过直接使用exec,没有分叉。但在这种情况下,作为my_app的父级的终端模拟器及其替换将继续运行,直到应用程序退出。
static void
handle_enter (enum mode mode, char *buf, struct appdata *appdata, int i)
{
pid_t pid;
if (mode == EXEC)
{
if (i == -1)
return;
if (strcmp (buf, appdata[i].name) == 0)
{
pid = fork();
if (pid < 0)
report_run_error ("Could not fork", NULL);
else if (pid == 0)
{
execvp (appdata[i].args[0], appdata[i].args);
report_run_error ("Could not run: %s", appdata[i].name);
}
/* tried exit here */
}
else
return;
}
}
答案 0 :(得分:0)
发生了什么,my_app正在关闭,向其子节点发送SIGHUP,其中包括分叉进程。当分叉进程获得SIGHUP时,它会将它转发给它的子进程,其中包括exec程序,所以它也会死掉。
听起来你想要类似于nohup的东西,它不响应SIGHUP,或内置的shell,&#34; disown&#34;,它有效地选择不向执行官发送SIGHUP&#39 ; d退出处理。
最简单的事情就是
a)在调用execvp之前调用signal(SIGHUP,SIG_IGN),这将阻止你的fork进程在获得SIGHUP时死亡。
或
b)复制appdata [i] .args并添加&#34; nohup&#34;在前面,并调用execvp。 nohup为你做了(a)。
第一个选项的最小示例:
void main(){
char * cmd[3] = {"sleep", "1337", 0};
int pid = fork();
if (pid < 0)
printf("Could not fork");
else if (pid == 0)
{
signal (SIGHUP, SIG_IGN);
execvp (cmd[0], cmd);
printf ("Could not run");
}
}
如果你运行上面的命令你会看到它立即死亡但是让睡眠成为孤儿(用top或ps找到它)
答案 1 :(得分:-2)
我的想法是获取您的程序PID(进程ID),找到它的父PID(终端shell)并使用shell命令&#34; kill -9&#34;将其终止,然后退出。