From d31c83bf33094b8dc6574f2e417dc238893b2179 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 29 Dec 2009 17:15:14 +0100 Subject: [PATCH] add an abstraction layer separating out db-4 specific code The extra abstraction layer is needed to more easily add a db-1 implementation later. --- common/db.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/db.h | 7 +++ common/exf.c | 128 +++-------------------------------------------------- common/msg.c | 14 +++--- 4 files changed, 160 insertions(+), 130 deletions(-) diff --git a/common/db.c b/common/db.c index 83f8578b..9e375a20 100644 --- a/common/db.c +++ b/common/db.c @@ -16,6 +16,7 @@ static const char sccsid[] = "$Id: db.c,v 10.48 2002/06/08 19:32:52 skimo Exp $ #include #include #include +#include #include #include @@ -680,3 +681,143 @@ line_insdel(SCR *sp, lnop_t op, db_recno_t lno) return rval; } + +#ifdef USE_DB4_LOGGING +#define VI_DB_INIT_LOG DB_INIT_LOG +#else +#define VI_DB_INIT_LOG 0 +#endif + +/* + * PUBLIC: int db_setup __P((SCR *, EXF *)); + */ +int +db_setup(SCR *sp, EXF *ep) +{ + char path[MAXPATHLEN]; + int fd; + DB_ENV *env; + + (void)snprintf(path, sizeof(path), "%s/vi.XXXXXX", O_STR(sp, O_RECDIR)); + if ((fd = mkstemp(path)) == -1) { + msgq(sp, M_SYSERR, "%s", path); + goto err; + } + (void)close(fd); + (void)unlink(path); + if (mkdir(path, S_IRWXU)) { + msgq(sp, M_SYSERR, "%s", path); + goto err; + } + if (db_env_create(&env, 0)) { + msgq(sp, M_ERR, "env_create"); + goto err; + } +#ifdef USE_DB4_LOGGING + if ((sp->db_error = vi_db_init_recover(env))) { + msgq(sp, M_DBERR, "init_recover"); + goto err; + } + if ((sp->db_error = __vi_init_recover(env))) { + msgq(sp, M_DBERR, "init_recover"); + goto err; + } +#endif + if ((sp->db_error = db_env_open(env, path, + DB_PRIVATE | DB_CREATE | DB_INIT_MPOOL | VI_DB_THREAD + | VI_DB_INIT_LOG, 0)) != 0) { + msgq(sp, M_DBERR, "env->open"); + goto err; + } + + if ((ep->env_path = strdup(path)) == NULL) { + msgq(sp, M_SYSERR, NULL); + (void)rmdir(path); + goto err; + } + ep->env = env; + return 0; +err: + return 1; +} + +/* + * PUBLIC: int db_msg_open __P((SCR *, char *, DB **)); + */ +int db_msg_open(SCR *sp, char *file, DB **dbp) +{ + return (sp->db_error = db_create(dbp, 0, 0)) != 0 || + (sp->db_error = (*dbp)->set_re_source(*dbp, file)) != 0 || + (sp->db_error = db_open(*dbp, NULL, DB_RECNO, 0, 0)) != 0; +} + +/* + * PUBLIC: int db_init __P((SCR *, EXF *, char *, char *, size_t, int *)); + */ +int +db_init(SCR *sp, EXF *ep, char *rcv_name, char *oname, size_t psize, int *open_err) +{ + if (db_setup(sp, ep)) + return 1; + + /* Open a db structure. */ + if ((sp->db_error = db_create(&ep->db, 0, 0)) != 0) { + msgq(sp, M_DBERR, "db_create"); + return 1; + } + + ep->db->set_re_delim(ep->db, '\n'); /* Always set. */ + ep->db->set_pagesize(ep->db, psize); + ep->db->set_flags(ep->db, DB_RENUMBER | DB_SNAPSHOT); + if (rcv_name == NULL) + ep->db->set_re_source(ep->db, oname); + +/* + * Don't let db use mmap when using fcntl for locking + */ +#ifdef HAVE_LOCK_FCNTL +#define NOMMAPIFFCNTL DB_NOMMAP +#else +#define NOMMAPIFFCNTL 0 +#endif + +#define _DB_OPEN_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH + + if ((sp->db_error = db_open(ep->db, ep->rcv_path, DB_RECNO, + ((rcv_name == 0) ? DB_TRUNCATE : 0) | VI_DB_THREAD | NOMMAPIFFCNTL, + _DB_OPEN_MODE)) != 0) { + msgq_str(sp, + M_DBERR, rcv_name == NULL ? oname : rcv_name, "%s"); + /* + * !!! + * Historically, vi permitted users to edit files that couldn't + * be read. This isn't useful for single files from a command + * line, but it's quite useful for "vi *.c", since you can skip + * past files that you can't read. + */ + ep->db = NULL; /* Don't close it; it wasn't opened */ + + *open_err = 1; + return 1; + } + + /* re_source is loaded into the database. + * Close it and reopen it in the environment. + */ + if ((sp->db_error = ep->db->close(ep->db, 0))) { + msgq(sp, M_DBERR, "close"); + return 1; + } + if ((sp->db_error = db_create(&ep->db, ep->env, 0)) != 0) { + msgq(sp, M_DBERR, "db_create 2"); + return 1; + } + if ((sp->db_error = db_open(ep->db, ep->rcv_path, DB_RECNO, + VI_DB_THREAD | NOMMAPIFFCNTL, _DB_OPEN_MODE)) != 0) { + msgq_str(sp, + M_DBERR, ep->rcv_path, "%s"); + return 1; + } + + return 0; +} diff --git a/common/db.h b/common/db.h index fd1dc646..87dcf2d1 100644 --- a/common/db.h +++ b/common/db.h @@ -16,6 +16,9 @@ (env)->remove(env, path, NULL, flags) #endif +#define db_env_close(env,flags) \ + (env)->close(env, flags) + #if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 #define db_open(db,file,type,flags,mode) \ (db)->open(db, NULL, file, NULL, type, flags, mode) @@ -23,6 +26,10 @@ #define db_open(db,file,type,flags,mode) \ (db)->open(db, file, NULL, type, flags, mode) #endif +#define db_get_low(db,key,data,flags) \ + (db)->get(db, NULL, key, data, flags) +#define db_close(db) \ + (db)->close(db, DB_NOSYNC) #ifdef USE_DYNAMIC_LOADING #define db_create nvi_db_create diff --git a/common/exf.c b/common/exf.c index 75c3d9fa..d24db997 100644 --- a/common/exf.c +++ b/common/exf.c @@ -42,7 +42,6 @@ static int file_backup __P((SCR *, char *, char *)); static void file_cinit __P((SCR *)); static void file_comment __P((SCR *)); static int file_spath __P((SCR *, FREF *, struct stat *, int *)); -static int db_setup __P((SCR *sp, EXF *ep)); /* * file_add -- @@ -261,68 +260,9 @@ file_init(SCR *sp, FREF *frp, char *rcv_name, int flags) F_SET(ep, F_MODIFIED); } - if (db_setup(sp, ep)) - goto err; - - /* Open a db structure. */ - if ((sp->db_error = db_create(&ep->db, 0, 0)) != 0) { - msgq(sp, M_DBERR, "db_create"); - goto err; - } - - ep->db->set_re_delim(ep->db, '\n'); /* Always set. */ - ep->db->set_pagesize(ep->db, psize); - ep->db->set_flags(ep->db, DB_RENUMBER | DB_SNAPSHOT); - if (rcv_name == NULL) - ep->db->set_re_source(ep->db, oname); - -/* - * Don't let db use mmap when using fcntl for locking - */ -#ifdef HAVE_LOCK_FCNTL -#define NOMMAPIFFCNTL DB_NOMMAP -#else -#define NOMMAPIFFCNTL 0 -#endif - -#define _DB_OPEN_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH - - if ((sp->db_error = db_open(ep->db, ep->rcv_path, DB_RECNO, - ((rcv_name == 0) ? DB_TRUNCATE : 0) | VI_DB_THREAD | NOMMAPIFFCNTL, - _DB_OPEN_MODE)) != 0) { - msgq_str(sp, - M_DBERR, rcv_name == NULL ? oname : rcv_name, "%s"); - /* - * !!! - * Historically, vi permitted users to edit files that couldn't - * be read. This isn't useful for single files from a command - * line, but it's quite useful for "vi *.c", since you can skip - * past files that you can't read. - */ - ep->db = NULL; /* Don't close it; it wasn't opened */ - - if (LF_ISSET(FS_OPENERR)) - goto err; - - open_err = 1; - goto oerr; - } - - /* re_source is loaded into the database. - * Close it and reopen it in the environment. - */ - if ((sp->db_error = ep->db->close(ep->db, 0))) { - msgq(sp, M_DBERR, "close"); - goto err; - } - if ((sp->db_error = db_create(&ep->db, ep->env, 0)) != 0) { - msgq(sp, M_DBERR, "db_create 2"); - goto err; - } - if ((sp->db_error = db_open(ep->db, ep->rcv_path, DB_RECNO, - VI_DB_THREAD | NOMMAPIFFCNTL, _DB_OPEN_MODE)) != 0) { - msgq_str(sp, - M_DBERR, ep->rcv_path, "%s"); + if (db_init(sp, ep, rcv_name, oname, psize, &open_err)) { + if (open_err && !LF_ISSET(FS_OPENERR)) + goto oerr; goto err; } @@ -502,7 +442,7 @@ oerr: if (F_ISSET(ep, F_RCV_ON)) ep->rcv_path = NULL; } if (ep->db != NULL) { - (void)ep->db->close(ep->db, DB_NOSYNC); + (void)db_close(ep->db); ep->db = NULL; } free(ep); @@ -751,7 +691,7 @@ file_end(SCR *sp, EXF *ep, int force) * Close the db structure. */ if (ep->db->close != NULL) { - if ((sp->db_error = ep->db->close(ep->db, DB_NOSYNC)) != 0 && + if ((sp->db_error = db_close(ep->db)) != 0 && !force) { msgq_str(sp, M_DBERR, frp->name, "241|%s: close"); CIRCLEQ_INSERT_HEAD(&ep->scrq, sp, eq); @@ -772,7 +712,7 @@ file_end(SCR *sp, EXF *ep, int force) if (ep->env) { DB_ENV *env; - ep->env->close(ep->env, 0); + db_env_close(ep->env, 0); ep->env = 0; if ((sp->db_error = db_env_create(&env, 0))) msgq(sp, M_DBERR, "env_create"); @@ -1584,59 +1524,3 @@ file_lock(SCR *sp, char *name, int *fdp, int fd, int iswrite) return (LOCK_SUCCESS); #endif } - -#ifdef USE_DB4_LOGGING -#define VI_DB_INIT_LOG DB_INIT_LOG -#else -#define VI_DB_INIT_LOG 0 -#endif - -static int -db_setup(SCR *sp, EXF *ep) -{ - char path[MAXPATHLEN]; - int fd; - DB_ENV *env; - - (void)snprintf(path, sizeof(path), "%s/vi.XXXXXX", O_STR(sp, O_RECDIR)); - if ((fd = mkstemp(path)) == -1) { - msgq(sp, M_SYSERR, "%s", path); - goto err; - } - (void)close(fd); - (void)unlink(path); - if (mkdir(path, S_IRWXU)) { - msgq(sp, M_SYSERR, "%s", path); - goto err; - } - if (db_env_create(&env, 0)) { - msgq(sp, M_ERR, "env_create"); - goto err; - } -#ifdef USE_DB4_LOGGING - if ((sp->db_error = vi_db_init_recover(env))) { - msgq(sp, M_DBERR, "init_recover"); - goto err; - } - if ((sp->db_error = __vi_init_recover(env))) { - msgq(sp, M_DBERR, "init_recover"); - goto err; - } -#endif - if ((sp->db_error = db_env_open(env, path, - DB_PRIVATE | DB_CREATE | DB_INIT_MPOOL | VI_DB_THREAD - | VI_DB_INIT_LOG, 0)) != 0) { - msgq(sp, M_DBERR, "env->open"); - goto err; - } - - if ((ep->env_path = strdup(path)) == NULL) { - msgq(sp, M_SYSERR, NULL); - (void)rmdir(path); - goto err; - } - ep->env = env; - return 0; -err: - return 1; -} diff --git a/common/msg.c b/common/msg.c index a47d986c..6bcd3161 100644 --- a/common/msg.c +++ b/common/msg.c @@ -724,9 +724,7 @@ msg_open(SCR *sp, char *file) p = buf; } else p = file; - if ((sp->db_error = db_create(&db, 0, 0)) != 0 || - (sp->db_error = db->set_re_source(db, p)) != 0 || - (sp->db_error = db_open(db, NULL, DB_RECNO, 0, 0)) != 0) { + if (db_msg_open(sp, p, &db)) { if (first) { first = 0; return (1); @@ -745,10 +743,10 @@ msg_open(SCR *sp, char *file) key.size = sizeof(db_recno_t); memset(&data, 0, sizeof(data)); msgno = 1; - if ((sp->db_error = db->get(db, NULL, &key, &data, 0)) != 0 || + if ((sp->db_error = db_get_low(db, &key, &data, 0)) != 0 || data.size != sizeof(VMC) - 1 || memcmp(data.data, VMC, sizeof(VMC) - 1)) { - (void)db->close(db, DB_NOSYNC); + (void)db_close(db); if (first) { first = 0; return (1); @@ -760,7 +758,7 @@ msg_open(SCR *sp, char *file) first = 0; if (sp->gp->msg != NULL) - (void)sp->gp->msg->close(sp->gp->msg, DB_NOSYNC); + (void)db_close(sp->gp->msg); sp->gp->msg = db; return (0); } @@ -775,7 +773,7 @@ void msg_close(GS *gp) { if (gp->msg != NULL) { - (void)gp->msg->close(gp->msg, 0); + (void)db_close(gp->msg); gp->msg = NULL; } } @@ -850,7 +848,7 @@ msg_cat(SCR *sp, const char *str, size_t *lenp) */ gp = sp == NULL ? NULL : sp->gp; if (gp != NULL && gp->msg != NULL && - gp->msg->get(gp->msg, NULL, &key, &data, 0) == 0 && + db_get_low(gp->msg, &key, &data, 0) == 0 && data.size != 0) { if (lenp != NULL) *lenp = data.size - 1; -- 2.11.4.GIT