来自终端应用程序的exec杀死终端

时间:2017-07-18 23:21:20

标签: c linux process fork exec

我编写了一个小的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;
    }
}

2 个答案:

答案 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;将其终止,然后退出。

相关问题