我编写了一个工具,用于在Linux用户ID之间共享tmux会话,以便主用户领导会话,观察者具有对会话的只读访问权限。分为两部分:
问题是如果启动观察者进程的交互式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()会照顾这个。显然不是。
嗯?
答案 0 :(得分:0)
回答我自己的问题 - 试图将此标记为已关闭。
代码中没有问题。问题出在环境中。我依赖的是一个ssh隧道,它在调用shell关闭时被破坏了。傻我。
那我该如何标记这封闭?