Пытаюсь реализовать сигнализацию в моей программе оболочки. C Обработка сигналов

Я создаю свою собственную оболочку на C. Я хочу реализовать встроенную функцию с именем alarm, которая принимает целочисленный аргумент для количества секунд. Встроенная функция просто отправляет пользователю сообщение через i секунд (один раз), но функциональность оболочки тем временем должна продолжать работать.

Вот что у меня есть на данный момент:

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)
    }

Ясно, что это не работает. Я немного заблудился. Я пробовал это последние пару часов и не знаю, что делать.


person user7795564    schedule 31.03.2017    source источник
comment
не работает не является адекватным описанием проблемы. Пожалуйста, опишите проблемы, с которыми вы столкнулись, более конкретно.   -  person kaylum    schedule 31.03.2017
comment
Что ж, с приведенным выше кодом ничего не происходит. Поэтому, если я ввожу сигнал тревоги 4, это как если бы я только что ввел ввод, и оболочка распечатала приглашение   -  person user7795564    schedule 31.03.2017
comment
Почему вы устанавливаете будильник в обработчике будильника? Обработчик не вызывается, если еще не установлен сигнал тревоги.   -  person kaylum    schedule 31.03.2017


Ответы (1)


Возможно, вы неправильно понимаете, что делает signal ...

Системный вызов signal можно использовать для настройки обработка сигналов. Как правило, используйте системный вызов kill для отправка сигналов.

OTOH, возможно, это разница между семантикой обработки сигналов BSD и семантика обработки сигналов System V, вносящая путаницу. Семантика обработки сигналов System V может потребовать вызова signal (снова) в функции обработчика сигналов. Новые системы Linux по крайней мере придерживаются семантики обработки сигналов BSD, которая является надежной и не требует повторного вызова signal, если вы не хотите изменить вызываемый обработчик.

В качестве примечания: как только вы перестанете правильно использовать signal, я бы порекомендовал вместо этого использовать sigaction. Вы можете прочитать раздел «Переносимость» на signal странице руководства, на которую я указал, чтобы узнать больше о том, почему вам следует использовать sigaction вместо signal.

Но дальше ...

Есть и другие системные вызовы, которые можно использовать для отправки сигналов в дополнение к системному вызову kill. Как и в вашем случае, вы можете использовать alarm или _ 13_.

В качестве альтернативы, если вы хотите реализовать что-то вроде того, что делает alarm (без использования alarm или setitimer), вы можете использовать отдельный процесс (возможно, через вызов fork), который вызывает функцию сна с последующим вызовом kill следующим образом:

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

В этом примере pid будет идентификатором процесса, которому вы хотите отправить сигнал SIGALRM (который является сигналом, который отправляет alarm).

Надеюсь, это поможет ответить на ваш вопрос.

person Louis Langholtz    schedule 31.03.2017