-1

我目前正在espeak用 Tcl/Tk 包装一个命令行工具 ( ),到目前为止我已经弄清楚了:

load ./extensions/system.so
package require Tk
package require Tclx

set chid 0

proc kill {id} {
    exec kill -9 $id
}

proc speak {} {
    global chid
    set chid [fork]
    if {$chid == 0} {
        execvp espeak [.text get 1.0 end]
    }
}

proc silent {} {
    global chid
    kill $chid
}

system.so 是我一起破解以便能够使用的扩展execvp

#include <tcl.h>
#include <tclExtend.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

static int 
execvp_command(ClientData cdata, Tcl_Interp *interp, int argc, const char* argv[])
{   
    if (argc == 1)
    {
        interp->result = "execvp command ?args ...?";
        return TCL_ERROR;
    }

    execvp(argv[1], argv + 1);

    return TCL_OK;
}

int System_Init(Tcl_Interp* interp)
{
    if (Tcl_InitStubs(interp, "8.1", 0) == NULL)
        return TCL_ERROR;

    Tcl_CreateCommand(interp, "execvp", execvp_command, NULL, NULL);

    Tcl_PkgProvide(interp, "system", "1.0");

    return TCL_OK;
}

我需要的原因execvp是,由exec(Tcl) 创建的子进程似乎在进程终止时继续运行(我可以^C通过退出 GUI 来确认这一点),而如果我使用execvp,则espeak正常终止。

因此,我真正需要的只是能够启动一个子进程并按需终止它。

是否有另一个库可以正确执行此操作,例如 Expect?

4

1 回答 1

2

Tclexecvp在内部使用(真的;我刚刚检查了源代码),所以区别在于其他地方。其他地方将在信号中;命令创建的子进程exec(以及使用相同底层引擎的其他东西)将强制使用默认信号处理程序的大多数信号,但由于它设置为非默认的唯一信号是 SIGPIPE,我想知道还有什么继续。

也就是说,使用这种东西的最终扩展是TclX。这使您可以访问您部分使用的所有低级 POSIX 功能。(期望也能做到。)

于 2011-07-04T17:24:25.267 回答