Эмуляция execvp - есть ли лучший способ сделать это? - PullRequest
0 голосов
/ 04 июля 2011

Сейчас я обертываю инструмент командной строки (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?

1 Ответ

2 голосов
/ 04 июля 2011

Tcl использует execvp внутренне (на самом деле; я только что проверил источник), поэтому разница лежит в другом месте.Это в другом месте будет в сигналах;подпроцесс, созданный командой exec (и другими вещами, использующими тот же базовый механизм), будет иметь большинство сигналов, вынужденных использовать обработчики сигналов по умолчанию, но поскольку единственный сигнал, который он устанавливает в значение по умолчанию, это SIGPIPE, мне интересночто еще происходит.

Тем не менее, окончательное расширение для работы с такого рода вещами - TclX .Это дает вам доступ ко всем низкоуровневым функциям POSIX, которые вы использовали частично.(Ожидайте также, что сможете это сделать.)

...