📄 sig.cpp
字号:
// socket++ library. sig.C // Copyright (C) 1992-1996 Gnanasekaran Swaminathan <gs4t@virginia.edu>//// Permission is granted to use at your own risk and distribute this software// in source and binary forms provided the above copyright notice and this// paragraph are preserved on all copies. This software is provided "as is"// with no express or implied warranty.#include <signal.h>#include <sig.h>//explicit template instantiation.typedef sig::phnd phnd;typedef sig::phndlist phndlist;//template class list<phnd>;//template class map<int, phndlist, less<int> >;//static sigerr se; //commended out by Herbert Straub// Change all se to sigerrsiginit siginit::init;sig& sig::nal = *siginit::init.s;typedef void (*sighnd_type) (int);extern "C" { static void sighandler (int signo) { sig::nal.kill (signo); }}sig::hnd::hnd (int s) : signo (s){ sig::nal.set (signo, this);}sig::hnd::~hnd (){ sig::nal.unset (signo, this);}bool sig::set (int signo, sig::hnd* hnd){ if (hnd == 0) return false; phndlist& v = smap [signo]; if (v.empty ()) { struct sigaction sa; if (sigaction (signo, 0, &sa) == -1) throw sigerr(); if (sa.sa_handler != sighnd_type (&sighandler)) { // setting for the first time sa.sa_handler = (void(*)(int)) sighnd_type (&sighandler); if (sigemptyset (&sa.sa_mask) == -1) throw sigerr(); sa.sa_flags = 0; if (sigaction (signo, &sa, 0) == -1) throw sigerr(); } v.push_back (hnd); return true; } phndlist::iterator j = find (v.begin(), v.end (), hnd); if (j == v.end ()) { v.push_back (hnd); return true; } return false;}bool sig::unset (int signo, sig::hnd* hnd){ if (hnd == 0) return false; phndlist& v = smap [signo]; phndlist::iterator j = find (v.begin(), v.end (), hnd); if (j != v.end ()) { v.erase (j); return true; } return false;}void sig::unset (int signo){ phndlist& v = smap [signo]; v.erase (v.begin (), v.end ()); struct sigaction sa; if (sigaction (signo, 0, &sa) == -1) throw sigerr(); if (sa.sa_handler == sighnd_type (&sighandler)) { sa.sa_handler = (void(*)(int)) sighnd_type (SIG_DFL); if (sigemptyset (&sa.sa_mask) == -1) throw sigerr(); sa.sa_flags = 0; if (sigaction (signo, &sa, 0) == -1) throw sigerr(); }}void sig::mask (int signo) const{ sigset_t s; if (sigemptyset (&s) == -1) throw sigerr(); if (sigaddset (&s, signo) == -1) throw sigerr(); if (sigprocmask (SIG_BLOCK, &s, 0) == -1) throw sigerr();}void sig::unmask (int signo) const{ sigset_t s; if (sigemptyset (&s) == -1) throw sigerr(); if (sigaddset (&s, signo) == -1) throw sigerr(); if (sigprocmask (SIG_UNBLOCK, &s, 0) == -1) throw sigerr();}void sig::mask (int siga, int sigb) const{ struct sigaction sa; if (sigaction (siga, 0, &sa) == -1) throw sigerr(); if (sa.sa_handler != sighnd_type (&sighandler)) { sa.sa_handler = (void(*)(int)) sighnd_type (&sighandler); if (sigemptyset (&sa.sa_mask) == -1) throw sigerr(); sa.sa_flags = 0; } if (sigaddset (&sa.sa_mask, sigb) == -1) throw sigerr(); if (sigaction (siga, &sa, 0) == -1) throw sigerr();}void sig::unmask (int siga, int sigb) const{ struct sigaction sa; if (sigaction (siga, 0, &sa) == -1) throw sigerr(); if (sa.sa_handler != sighnd_type (&sighandler)) { sa.sa_handler = (void(*)(int)) sighnd_type (&sighandler); if (sigemptyset (&sa.sa_mask) == -1) throw sigerr(); sa.sa_flags = 0; } else { if (sigdelset (&sa.sa_mask, sigb) == -1) throw sigerr(); } if (sigaction (siga, &sa, 0) == -1) throw sigerr();}void sig::sysresume (int signo, bool set) const{ struct sigaction sa; if (sigaction (signo, 0, &sa) == -1) throw sigerr(); if (sa.sa_handler != sighnd_type (&sighandler)) { sa.sa_handler = (void(*)(int)) sighnd_type (&sighandler); if (sigemptyset (&sa.sa_mask) == -1) throw sigerr(); sa.sa_flags = 0; }#if !(defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__sun__) || defined(__linux__) || defined(__APPLE))// Early SunOS versions may have SA_INTERRUPT. I can't confirm. if (set == false) sa.sa_flags |= SA_INTERRUPT; else sa.sa_flags &= ~SA_INTERRUPT; if (sigaction (signo, &sa, 0) == -1) throw sigerr();#endif}struct procsig { int signo; procsig (int s): signo (s) {} void operator () (phnd& ph) { (*ph) (signo); }};void sig::kill (int signo){ phndlist& v = smap [signo]; // struct procsig used to be here // LN for_each (v.begin (), v.end (), procsig (signo));}sigset_t sig::pending () const{ sigset_t s; if (sigemptyset (&s) == -1) throw sigerr(); if (sigpending (&s) == -1) throw sigerr(); return s;}bool sig::ispending (int signo) const{ sigset_t s = pending (); switch (sigismember (&s, signo)) { case 0: return false; case 1: return true; } throw sigerr();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -