为什么我的流程不与tty脱离关系?

时间:2015-01-15 13:38:29

标签: posix

我编写了一个工具,用于在Linux用户ID之间共享tmux会话,以便主用户领导会话,观察者具有对会话的只读访问权限。分为两部分:

  • 启动命名会话的脚本
  • 由观察者uid运行带有uid的setuid的C程序

问题是如果启动观察者进程的交互式shell退出,则会终止观察者。我试图通过正确守护子进程来避免这种情况,但它不起作用(参见代码)。我还尝试了SIG_IGN,然后删除了该代码。

以下是代码:

第1部分,启动主会话的脚本:

#!/usr/bin/env bash                                                             

sessionName=${1:-shared}                                                        
me=`id -ru`                                                                     
socket=/tmp/tms-$me-shared                                                      

tmux -S $socket new-session -s $sessionName                                     
# Use companion setuid pgm to start slaves...                                   
# tmux-slave [sessionName]                                                      

第2部分是运行setuid作为主服务器的观察者的C代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>

int main (int argc, char *argv[]) {
    char *alist[] = { "xterm","-e","/usr/bin/tmux", 0 };
    int me = geteuid();
    char tmuxCmd[200];
    char sessionName[10] = "shared";
    if (argc > 1) {
            strncpy(sessionName,argv[1],9);
            sessionName[10] = '\0';
    }
    sprintf(tmuxCmd,"/usr/bin/tmux -S /tmp/tms-%d-shared att -t %s -r",me,sessionName);
    alist[2] = tmuxCmd;

    printf("\nppid/pid/sid/pgid: %d/%d/%d/%d\n",getppid(),getpid(),getsid(0),getpgrp());
    int fc;
    if (!(fc = fork())) { // child
        int sid = setsid(); // put child in independent session
        setpgrp();
        printf("New ppid/pid/session/pgrp is %d/%d/%d/%d\n",getppid(),getpid(),sid,getpgrp());
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
        if (fork() > 0) exit(0); // spawn child in new session
        execv("/usr/bin/xterm",alist);
        printf("Failed to invoke tmux in xterm\n");
        exit(-1);
    }
    // parent
    printf("Child PID from first fork(): %d\n",fc);
    if (fc == -1) {
        printf("fork() failed for slave\n");
        exit(-2);
    }
    printf("Slave spawned from %d\n",getpid());
    exit(0);
}

编译:

bill@port:~/Desktop/u/src$ cc -o tmux-slave tmux-slave.c; chmod u+s tmux-slave

所以要运行这个:

bill@port:~/Desktop$ tmux-share cherry # master session

cindy@port:~$ /home/bill/Desktop/u/src/tmux-slave cherry

然后,一切都很好,直到cindy退出shell。它挂了。 Ctl-C导致退出,但然后child(观察者xterm / tmux)死亡。就像一个没有使用nohup的过程一样。我以为setsid()会照顾这个。显然不是。

嗯?

1 个答案:

答案 0 :(得分:0)

回答我自己的问题 - 试图将此标记为已关闭。

代码中没有问题。问题出在环境中。我依赖的是一个ssh隧道,它在调用shell关闭时被破坏了。傻我。

那我该如何标记这封闭?