From a823d5b4a231f42a598ac3624f9271a2a3b29a50 Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Sat, 18 Jun 2011 15:10:41 +0200 Subject: [PATCH] Ensure libdb handles are properly closed when terminating. --- dbsrc.c | 28 +++++++++++++++++++++++----- statserve.c | 25 ++++++++++++++++++++++++- statserve.h | 1 + 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/dbsrc.c b/dbsrc.c index bb239ae..80a2202 100644 --- a/dbsrc.c +++ b/dbsrc.c @@ -103,6 +103,14 @@ static void dbidle(struct source *src) } } +static void dbclose(struct source *src) +{ + struct dbsrc *d = src->pdata; + + d->db->close(d->db, 0); + d->env->close(d->env, 0); +} + static void enverror(const DB_ENV *env, const char *prefix, const char *msg) { flog(LOG_ERR, "dbsource: environment error: %s", msg); @@ -118,10 +126,11 @@ struct source *mkdbsrc(char *path, char *envpath) omalloc(src); src->serve = dbserve; src->idle = dbidle; + src->close = dbclose; src->pdata = omalloc(d); if((ret = db_env_create(&d->env, 0)) != 0) { flog(LOG_ERR, "could not create bdb environment: %s", db_strerror(ret)); - exit(1); + goto fail; } if(envpath) { d->envnm = sstrdup(envpath); @@ -136,23 +145,32 @@ struct source *mkdbsrc(char *path, char *envpath) } if((ret = d->env->open(d->env, d->envnm, DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN, 0666)) != 0) { flog(LOG_ERR, "could not open bdb environment: %s", db_strerror(ret)); - exit(1); + goto fail; } d->env->set_lk_detect(d->env, DB_LOCK_RANDOM); d->env->set_errcall(d->env, enverror); if((ret = db_create(&d->db, d->env, 0)) != 0) { flog(LOG_ERR, "could not create bdb database: %s", db_strerror(ret)); - exit(1); + goto fail; } if(dbpagesize) { if((ret = d->db->set_pagesize(d->db, dbpagesize)) != 0) { flog(LOG_ERR, "could not set bdb page size (to %i): %s", dbpagesize, db_strerror(ret)); - exit(1); + goto fail; } } if((ret = d->db->open(d->db, NULL, path, NULL, DB_HASH, DB_AUTO_COMMIT | DB_CREATE, 0666)) != 0) { flog(LOG_ERR, "could not open bdb database: %s", db_strerror(ret)); - exit(1); + goto fail; } return(src); + +fail: + if(d->db) + d->db->close(d->db, 0); + if(d->env) + d->env->close(d->env, 0); + free(d); + free(src); + return(NULL); } diff --git a/statserve.c b/statserve.c index ab3b346..9bee73b 100644 --- a/statserve.c +++ b/statserve.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,21 @@ static void listenloop(struct muth *muth, va_list args) } } +static void sigterm(int sig) +{ + shutdown(0, SHUT_RDWR); +} + +static void closeall(void) +{ + struct source *src; + + for(src = sources; src != NULL; src = src->next) { + if(src->close) + src->close(src); + } +} + int main(int argc, char **argv) { int c; @@ -104,7 +120,10 @@ int main(int argc, char **argv) } last = NULL; while(optind < argc) { - src = parsesource(argv[optind++]); + if((src = parsesource(argv[optind++])) == NULL) { + closeall(); + return(1); + } if(!sources) sources = src; if(last) @@ -113,9 +132,13 @@ int main(int argc, char **argv) } if(!sources) { usage(stderr); + closeall(); return(1); } mustart(listenloop, 0); + signal(SIGINT, sigterm); + signal(SIGTERM, sigterm); ioloop(); + closeall(); return(0); } diff --git a/statserve.h b/statserve.h index b276bc0..507a8da 100644 --- a/statserve.h +++ b/statserve.h @@ -15,6 +15,7 @@ struct source { struct source *next; struct fileinfo (*serve)(struct source *src, char *nm); void (*idle)(struct source *src); + void (*close)(struct source *src); void *pdata; }; -- 2.11.0