Есть ли способ запретить пользователю регистрироваться / использовать свой собственный обработчик сигналов и всегда использовать конкретный обработчик? - PullRequest
1 голос
/ 27 апреля 2011

Мое требование: У меня есть обработчик сигнала в моем инструменте, который зарегистрирован и используется между определенным интервалом (я использую таймер).

Теперь этот обработчик сигнала НЕ должен позволять регистрировать любой другой обработчик после того, как этот обработчик будет зарегистрирован. (Но это ограничение действует только на короткий промежуток времени, значит, по истечении этого срока пользователь может свободно вызывать свой собственный обработчик)

Есть ли способ сделать это?

 sigset_t mask;
 struct sigaction sa;
 printf("Establishing handler for signal %d\n", SIG);
 sa.sa_flags = SA_SIGINFO;
 sa.sa_sigaction = handler; // This handler should override all handlers
 sigaction(SIG, &sa, NULL);
 sev.sigev_notify = SIGEV_SIGNAL;
 sev.sigev_signo = SIGUSR1;

Примечание: мой инструмент на самом деле написан на C ++, но концепции настолько близки, и, поскольку больше людей знакомы с ним, я также добавляю тег C, с C ++ Пожалуйста, не стесняйтесь просить больше разъяснений (если вам нужно)

Ответы [ 4 ]

8 голосов
/ 27 апреля 2011

Полагаю, вы пишете библиотеку. Ответ - нет, нет, нет, NO ! Просто напишите в документации, что клиентский код не должен регистрировать обработчик для этого сигнала. Если вы не можете доверять пользователям вашей библиотеки, чтобы они не ломали вещи, тогда вы должны писать приложения, а не библиотеки.

Независимо от того, что вы делаете, чтобы ваш обработчик был приоритетным по отношению к другим, он не будет работать, если другой код делает то же самое. Вот очень важный пост в блоге о разработчиках Windows, которые хотят создать «самое верхнее окно» (вроде как обработчик сигналов «самого высокого приоритета»).

http://blogs.msdn.com/b/oldnewthing/archive/2011/03/10/10138969.aspx

P.S. В Linux не существует хорошего способа предоставить разные уровни полномочий на более тонком уровне, чем уровень процесса.

P.P.S. Чтобы уточнить, работает ли мой код в вашем процессе, вы ничего не можете сделать. Вы уже потеряли. Мой код может получить доступ к вашим личным переменным-членам, освободить вашу память, закрыть ваши файлы и выгрузить ваши библиотеки. (Вы можете написать код ядра или запустить все в виртуализации, но это было бы ужасно.)

1 голос
/ 27 апреля 2011

Если обработка сигнала является проблемой, то избавьтесь от сигнала! Вы можете использовать select как способ спать с той точностью, которую позволяет ваша гранулярность. Вызов select выбирается с нулевыми номерами (дескриптор отсутствует в любых наборах), и допустимое время ожидания - это, по сути, блокирующий системный вызов с временной нижней границей.

Если вы не хотите блокировать, вы можете поместить таймер в его собственный поток и использовать семафор или мьютекс или что-то еще для синхронизации.

0 голосов
/ 05 августа 2011

Самый простой ответ - не использовать сигналы для таймеров. Вместо этого вы могли бы просто создать POSIX-таймер с доставкой SIGEV_THREAD (обработчик запускается в новом потоке, а не обработчиком сигнала) или создать свой собственный поток и nanosleep в нем для желаемого интервала. Преимущество этого заключается в том, что обработчик истечения таймера не ограничивается только функциями, защищающими асинхронный сигнал, и вам не нужно беспокоиться об установке конфликтующих обработчиков сигналов.

0 голосов
/ 05 мая 2011

Этого можно достичь, и на самом деле я сделал это, написав обертку sigaction вокруг фактической и используя методику dlsym и RTLD_NEXT.

Вот фрагмент кода моей оболочки:

enter code here
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{

 struct sigaction sa;
 printf("My sigaction called\n");

 if((Timerflag==1)&&(sig==SIGUSR1))
 {
   sa.sa_sigaction=my_handler;
   sa.sa_flags=0;

   return LT_SIGACTION(sig,&sa,NULL);
  }
  else if(Timerflag==0)
    return LT_SIGACTION(sig, act, oact);  
}

Наконец, я думаю, что все знают, как получить дескриптор libc, используя dlsym :-) К сожалению, никто не мог дать мне эту идею в "stackoverflow".

...