LINUX.ORG.RU

c signal handling and setjmp/longjmp


0

0

Пример отсюда:

http://www.csl.mtu.edu/cs4411/www/NOTES/non-local-goto/sig-1.html

у меня работает косяково. На ctl-c реагирует только один раз. Если ответить n, на последующие нажатия ctl-c не реагирует. Это с примером чё-то не так или дело в чём-то другом? Подобные же примеры, имеющие отношение с кабжу, работают также. Помогите разобраться плз!

★★★★☆

Как-то ещё можно перехватить отработку SIGINT, если прога основное время проводит в getchar() ?

bugmaker ★★★★☆
() автор топика

> На ctl-c реагирует только один раз.

потому что после longjmp() SIGINT остается blocked.

sigsetjmp/siglongjmp

idle ★★★★★
()
Ответ на: комментарий от idle

Пробовал тоже. Результат одинаковый.

bugmaker ★★★★☆
() автор топика
Ответ на: комментарий от bugmaker

Какое ядро? Утверждается, что в 2.6 нельзя использовать longjmp в обработчике сигналов. http://www.ussg.iu.edu/hypermail/linux/kernel/0405.2/0525.html

>Как-то ещё можно перехватить отработку SIGINT, если прога основное время проводит в getchar() ?

Опиши проблему подробнее...

P.S. Почему signal(), а не sigaction()?

mky ★★★★★
()
Ответ на: комментарий от mky

Ядро как раз 2.6. 
В общем, проблема такова: делаю оболочку, типо bash например. 
Нужно обработать ctrl-c. С сигналами раньше практически не работал. 
Нашёл пример, как это сделать. Ссылка в первом посте. Не работает.
Также, обнаружил что нужно юзать sigsetjmp/siglognjmp. Не работает.

Вот тестовая прога, что я сделал:

#include <stdio.h>
#include <signal.h>
#include <setjmp.h>

sigjmp_buf ici;

void handler (int n) {
    printf ("interrupt\n");
    siglongjmp(ici, 123456);
}

int main (int argc, char * argv []) {
    char c;
    int x;
    signal(SIGINT, handler);
    for (; ((char) x) != 'q';) {
        switch (x = sigsetjmp(ici, 0)) {
            case 0:
                x = getchar ();
            break;
            case 123456:
                printf ("from signal\n");
            break;
            default:
                printf ("unknown value: %i\n", x);
        }
    }
    return 0;
}

срабатывает как нужно, но только один раз. 
На следующие нажатия ctrl-c не реагирует. 
Прога не сегфолтится, продолжает работать.
Буду ковырять исходники какого-нибудь шелла, 
там ведь нормально всё и на всех ядрах...

bugmaker ★★★★☆
() автор топика
Ответ на: комментарий от bugmaker

Допустим вот так...
Или надо, чтобы getchar() считывал строку, введенную до нажатия Ctrl-C?
> делаю оболочку, типо bash например.
Есть такая штука --- readline().

volatile int flag;                                                              
                                                                                
void sig_INT(int signal)                                                        
{                                                                               
    flag=1;  return;                                                            
}                                                                               
                                                                                
int main()                                                                      
{                                                                               
    struct sigaction sa;                                                        
    int x;                                                                      
                                                                                
    sa.sa_handler = sig_INT;                                                    
    sa.sa_flags = 0;                                                            
    sigfillset(&sa.sa_mask);
    if ( sigaction(SIGINT, &sa, NULL) == -1 ) {                                 
        fprintf(stderr, "Error in sigaction: %s\n", strerror(errno));           
        exit(1);                                                                
    }                                                                           
    while (1) {                                                                 
        while( (x=getchar()) != EOF )                                           
            printf("Read char 0x%02X\n", x);                                    
        if (flag) {                                                             
            printf("\nGet SIGINT\n");   flag=0;                                 
        }                                                                       
    }                                                                           
    return 0;                                                                   
}             

mky ★★★★★
()
Ответ на: комментарий от mky

Спасибо огромное, это как раз то, что нужно! Про readline я знаю, но использовать сторонние библиотеки возможности нету...

bugmaker ★★★★☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.