Improve signal handling a bit

git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@569 db0b04b0-f4d1-0310-9a6d-de3e77497b0e
This commit is contained in:
Pasi Kallinen 2010-05-16 06:50:18 +00:00
parent bf9db511f5
commit 725b6cd1d2
2 changed files with 50 additions and 13 deletions

View File

@ -178,6 +178,36 @@ ttyrec_getpty ()
tcsetattr(slave, TCSANOW, &tt); tcsetattr(slave, TCSANOW, &tt);
} }
/* ************************************************************* */
static int dgl_signal_blocked = 0;
static sigset_t dgl_signal_blockmask;
static sigset_t dgl_signal_oldmask;
void
signals_block()
{
if (!dgl_signal_blocked) {
sigemptyset(&dgl_signal_blockmask);
sigaddset(&dgl_signal_blockmask, SIGHUP);
sigaddset(&dgl_signal_blockmask, SIGINT);
sigaddset(&dgl_signal_blockmask, SIGQUIT);
sigaddset(&dgl_signal_blockmask, SIGTERM);
sigprocmask(SIG_BLOCK, &dgl_signal_blockmask, &dgl_signal_oldmask);
dgl_signal_blocked = 1;
}
}
void
signals_release()
{
if (dgl_signal_blocked) {
sigprocmask(SIG_SETMASK, &dgl_signal_oldmask, NULL);
dgl_signal_blocked = 0;
}
}
/* ************************************************************* */ /* ************************************************************* */
char* char*
@ -253,6 +283,7 @@ catch_sighup (int signum)
sleep (5); sleep (5);
} }
#ifdef USE_SHMEM #ifdef USE_SHMEM
signals_block();
if (hup_shm_idx != -1) { if (hup_shm_idx != -1) {
struct dg_shm *shm_dg_data = NULL; struct dg_shm *shm_dg_data = NULL;
struct dg_shm_game *shm_dg_game = NULL; struct dg_shm_game *shm_dg_game = NULL;
@ -268,6 +299,7 @@ catch_sighup (int signum)
hup_shm_idx = -1; hup_shm_idx = -1;
free(hup_shm_ttyrec_fn); free(hup_shm_ttyrec_fn);
} }
signals_release();
#endif #endif
debug_write("catchup sighup"); debug_write("catchup sighup");
graceful_exit (2); graceful_exit (2);
@ -939,6 +971,7 @@ watchgame:
refresh (); refresh ();
endwin (); endwin ();
#ifdef USE_SHMEM #ifdef USE_SHMEM
signals_block();
if (games[idx]->is_in_shm) { if (games[idx]->is_in_shm) {
shm_idx = games[idx]->shm_idx; shm_idx = games[idx]->shm_idx;
shm_sem_wait(shm_dg_data); shm_sem_wait(shm_dg_data);
@ -951,6 +984,7 @@ watchgame:
hup_shm_ttyrec_fn = strdup(games[idx]->ttyrec_fn); hup_shm_ttyrec_fn = strdup(games[idx]->ttyrec_fn);
shm_sem_post(shm_dg_data); shm_sem_post(shm_dg_data);
} }
signals_release();
#endif #endif
resizey = games[idx]->ws_row; resizey = games[idx]->ws_row;
resizex = games[idx]->ws_col; resizex = games[idx]->ws_col;
@ -964,6 +998,7 @@ watchgame:
else else
setproctitle("<Anonymous>"); setproctitle("<Anonymous>");
#ifdef USE_SHMEM #ifdef USE_SHMEM
signals_block();
if (games[idx]->is_in_shm) { if (games[idx]->is_in_shm) {
hup_shm_idx = -1; hup_shm_idx = -1;
free(hup_shm_ttyrec_fn); free(hup_shm_ttyrec_fn);
@ -976,6 +1011,7 @@ watchgame:
} }
shm_sem_post(shm_dg_data); shm_sem_post(shm_dg_data);
} }
signals_release();
#endif #endif
initcurses (); initcurses ();
} }
@ -1969,30 +2005,24 @@ writefile (int requirenew)
int i = 0; int i = 0;
int my_done = 0; int my_done = 0;
struct flock fl = { 0 }; struct flock fl = { 0 };
sigset_t oldmask, toblock;
fl.l_type = F_WRLCK; fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET; fl.l_whence = SEEK_SET;
fl.l_start = 0; fl.l_start = 0;
fl.l_len = 0; fl.l_len = 0;
sigemptyset(&toblock); signals_block();
sigaddset(&toblock, SIGHUP);
sigaddset(&toblock, SIGINT);
sigaddset(&toblock, SIGQUIT);
sigaddset(&toblock, SIGTERM);
sigprocmask(SIG_BLOCK, &toblock, &oldmask);
fpl = fopen (globalconfig.lockfile, "r+"); fpl = fopen (globalconfig.lockfile, "r+");
if (!fpl) if (!fpl)
{ {
sigprocmask(SIG_SETMASK, &oldmask, NULL); signals_release();
debug_write("writefile locking failed"); debug_write("writefile locking failed");
graceful_exit (115); graceful_exit (115);
} }
if (fcntl (fileno (fpl), F_SETLK, &fl)) if (fcntl (fileno (fpl), F_SETLK, &fl))
{ {
sigprocmask(SIG_SETMASK, &oldmask, NULL); signals_release();
debug_write("writefile fcntl failed"); debug_write("writefile fcntl failed");
graceful_exit (107); graceful_exit (107);
} }
@ -2005,7 +2035,7 @@ writefile (int requirenew)
fp = fopen (globalconfig.passwd, "w"); fp = fopen (globalconfig.passwd, "w");
if (!fp) if (!fp)
{ {
sigprocmask(SIG_SETMASK, &oldmask, NULL); signals_release();
debug_write("passwd file fopen failed"); debug_write("passwd file fopen failed");
graceful_exit (104); graceful_exit (104);
} }
@ -2020,7 +2050,7 @@ writefile (int requirenew)
* as someone else. just die. */ * as someone else. just die. */
fclose(fp); fclose(fp);
fclose(fpl); fclose(fpl);
sigprocmask(SIG_SETMASK, &oldmask, NULL); signals_release();
debug_write("two users registering at the same time"); debug_write("two users registering at the same time");
graceful_exit (111); graceful_exit (111);
} }
@ -2043,7 +2073,7 @@ writefile (int requirenew)
{ {
fclose(fp); fclose(fp);
fclose(fpl); fclose(fpl);
sigprocmask(SIG_SETMASK, &oldmask, NULL); signals_release();
debug_write("too many users in passwd db already"); debug_write("too many users in passwd db already");
graceful_exit (116); graceful_exit (116);
} }
@ -2052,7 +2082,7 @@ writefile (int requirenew)
fclose (fp); fclose (fp);
fclose (fpl); fclose (fpl);
sigprocmask(SIG_SETMASK, &oldmask, NULL); signals_release();
} }
#else #else
void void
@ -2391,6 +2421,10 @@ main (int argc, char** argv)
/* signal handlers */ /* signal handlers */
signal (SIGHUP, catch_sighup); signal (SIGHUP, catch_sighup);
signal (SIGINT, catch_sighup);
signal (SIGQUIT, catch_sighup);
signal (SIGTERM, catch_sighup);
signal(SIGWINCH, sigwinch_func); signal(SIGWINCH, sigwinch_func);
(void) tcgetattr (0, &tt); (void) tcgetattr (0, &tt);

View File

@ -260,6 +260,9 @@ extern struct dg_game **sort_games(struct dg_game **games, int len, dg_sortmode
int runmenuloop(struct dg_menu *menu); int runmenuloop(struct dg_menu *menu);
extern void signals_block(void);
extern void signals_release(void);
extern void shm_sem_wait(struct dg_shm *shm_dg_data); extern void shm_sem_wait(struct dg_shm *shm_dg_data);
extern void shm_sem_post(struct dg_shm *shm_dg_data); extern void shm_sem_post(struct dg_shm *shm_dg_data);
extern void shm_update(struct dg_shm *shm_dg_data, struct dg_game **games, int len); extern void shm_update(struct dg_shm *shm_dg_data, struct dg_game **games, int len);