LINUX.ORG.RU

Когда сигнал может прервать выполнение программы


0

0

Привет!

Рассмотрим ситуацию:
1) Выполняется printf("Hello world\n");
2) Приходит сигнал HUP, который прерывает printf "где-то в середине".
3) В обработчике сигнала я выполняю printf("Fuck world\n");
4) Происходит возврат.

Что будет (точнее может быть) выведено на stdout?

Главный вопрос - в каких местах система может прерывать выполнение
программы?
В любом (где сигнал не блокирован) или есть участки кода, которые
прерваны быть не могут и сингал приходит только после выхода из
этого участка?
Ответ на: комментарий от anonymous

Теоретик, млин.

==={{{
$ сat 1.c
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>

static const char *s = "Hello, world";

static void on_sighup()
{
        printf("Fuck world\n");
}

int
main()
{
        struct sigaction act;
        pid_t pid;
        act.sa_handler = on_sighup;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
        sigaction(SIGHUP, &act, NULL);
        pid = fork();
        if ( ! pid ) {
                while(1) {
                        printf("%s%s%s\n", s, s, s);
                }
        } else {
                while (1) {
                        kill(pid, SIGHUP);
                }
        }
        return 0;
}

$ cc -W -Wall -pedantic -std=c99 1.c -o 1

$ ./1 >|logg

Ctrl-C
$ more logg
...
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
Hello, worldHello, worldFuck worldld
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
Fuck world
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
Hello, worldFuck world
Hello, worldHello, world
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
Fuck world
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
Fuck world
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
...
===}}}

Мало того, на солярке:

==={{{
$ more logg
...
Hello, worldHello, worldHello, woFuck world
rld
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
...
Hello, worldHello, worldHello, world
Hello, wFuck world
orldHello, worldHello, world
Hello, worldHello, worldHello, world
Hello, worldHello, worldHello, world
...
===}}}

Вообще этот спор о сортах говна поднадоел.
printf из обработчика сигнала делать нельзя. Period.
И вменяемые разработчики этому правилу следуют.

А что там в случае использования напечатается никому вобщем-то не интересно.

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

> Вообще этот спор о сортах говна поднадоел.

А мне забавно пообсуждать никому не нужные вещи ;) Яж anonymous! :)

anonymous
()
Ответ на: комментарий от execve

> printf из обработчика сигнала делать нельзя. Period.

Это неправда. async-signal-unsafe функции можно вызывать из обработчика сигнала. Просто в этом случае их нельзя вызывать в основном теле программы.

Но зачем такое может понадобиться - ума не приложу ;)

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

> Это неправда. async-signal-unsafe функции можно вызывать из обработчика сигнала. Просто в этом случае их нельзя вызывать в основном теле программы.

...а так же нельзя вызывать в основном теле программы все функции, которые в свою очередь вызываются небезопасным вызовом. у вас есть уверенность, что printf() ни при каких условиях не вызывает, скажем, malloc()? независимо от платформы? у меня вот нет такой уверенности бо быть её не может. нет, ну конечно, если вы не вызываете malloc() то без проблем :)

// wbr

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


ps: это я к тому, что утверждение "в обработчика сигнала *нельзя* вызывать printf()" верно без всяких "если". просто нельзя. c'est la vie.

// wbr

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