2014-02-18 32 views
0

如何从XWindow程序执行xterm,将其插入到我的窗口中,但在xterm处于活动状态并关闭后两者都继续执行?XWindow应用程序中的fork()/ exec()

在我的XWindows(XLib over XCB)应用程序中,我想执行xterm -Into <handle>。这样我的窗口就包含了xterm窗口。不幸的是发生了一些错误。

伪代码:

if (fork() == 0) { 
    pipe = popen('xterm -Into ' + handle); 
    while (feof(pipe)) gets(pipe); 
    exit(0); 
} 

我累system()execvp()为好。在我退出运行的xterm之前,每件事情都可以,然后我的程序退出。我猜想与X服务器的连接会丢失,因为它是在父和子之间共享的。

更新:这里是程序退出后(或者说崩溃)在终端上显示的内容。

XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0.0" 
    after 59 requests (59 known processed) with 1 events remaining. 
[xcb] Unknown sequence number while processing queue 
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called 
[xcb] Aborting, sorry about that. 
y: ../../src/xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed. 
Aborted 

回答

2

一种可能性是,你是由于SIGCHLD信号不 终止被忽略并导致程序中止。

signal(SIGCHLD, SIG_IGN); 

另一个问题是,因为您怀疑某个活动正在关闭X会话。只需 关闭套接字本身应该没有关系,但您是否使用一个库, 注册一个atexit调用它可能会导致问题。

因为从你的代码片段 看起来你实际上并不关心xterm的标准输出,更好的方法是执行关闭fd的0,1,2。另外,因为它看起来像你不需要在xterm 终止之后在子进程中执行任何操作,所以你可以使用'exec'而不是'popen'来完全替换子进程 和包含任何清理处理程序的子进程留下了 。虽然,我不知道你的片段是如何修剪你想要做的,因为很明显,“获取”的呼吁不是你想要的。

为确保X连接已关闭,您可以使用以下命令将其关闭设置为可执行标志 。 (这将在POSIX系统上运行,其中x连接 号码是服务器套接字的FD)

fcntl(XConnectionNumber(display), F_SETFD, fcntl(XConnectionNumber(display), F_GETFD) | FD_CLOEXEC); 

另外,请注意,除了你的叉子的背景下,“popen方法”本身叉,我想你可能想在那里做一个execvp然后使用waitpid(...,WNOHANG)来检查你的主X11循环中的孩子终止情况,如果你想知道它何时退出。