试图在我的shell程序中实现一个警报。 C信号处理

时间:2017-03-31 03:22:12

标签: c signals alarm

我在C中构建自己的shell。我想实现一个内置的名为alarm的内容,它接受一个整数参数的秒数。内置函数只是在i秒(一次)之后向用户发送消息,但shell功能应该在此期间继续工作。

到目前为止我所拥有的:

int seconds;

int main(int argc, char const *argv[], char* envp[]){
   ...
   signal(SIGALRM, alarmHandler);
   ...
}

void alarmHandler(int sig) {
    signal(sig, SIG_IGN);
    alarm(seconds);
    printf("%s\n", "message");
    signal(SIGALRM, alarmHandler);
}
void mainProgram(char* string, char* argument){
    ... //built ins that don't require forking
    pid_t processID = fork();

    if(processID==0){ //child
        if(strcmp(string, "alarm") == 0){
            seconds = atoi(argument);
            signal(SIGALRM, alarmHandler);
    }else{ // parent
        usleep(100000)
    }
显然,这不起作用。我有点迷路了。过去几个小时我一直在尝试这个,而且我不确定该怎么做。

1 个答案:

答案 0 :(得分:0)

也许你对signal做什么有错误的认识......

signal系统调用可用于设置信号的处理。一般来说,使用kill系统调用发送信号。

OTOH,也许正是BSD signal handling semanticsSystem V signal handling semantics之间的差异造成了混乱。系统V信号处理语义可能需要在信号处理函数内再次调用signal。较新的linux系统至少坚持BSD信号处理语义是可靠的,不需要再次调用signal,除非你想改变被调用的处理程序。

作为旁注,一旦您正确使用signal,我建议您改用sigaction。您可以阅读我关联的signal手册页的“可移植性”部分,详细了解您应该使用sigaction代替signal的原因。

但是后来......

除了kill系统调用之外,还有其他系统调用可用于发送信号。与您的情况类似,您可能希望使用alarmsetitimer

或者,如果您想要实现alarm所做的事情(不使用alarmsetitimer),您可以使用单独的流程(通过调用fork或许)调用一个sleep函数,然后像这样调用kill

usleep(100000);
kill(pid, SIGALRM);

在此示例中,pid将是您要将SIGALRM信号发送到的进程的进程ID(这是alarm发送的信号)。

希望这有助于回答您的问题。