From: Ken Hornstein Date: Thu, 14 Mar 2013 01:02:48 +0000 (-0400) Subject: Start of the changes for the new lock code. Does not compile yet. X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/4823929d7c53e0cb167884ef35c34db34fef2729?ds=inline;hp=--cc Start of the changes for the new lock code. Does not compile yet. --- 4823929d7c53e0cb167884ef35c34db34fef2729 diff --git a/configure.ac b/configure.ac index 238e17a4..96a99022 100644 --- a/configure.ac +++ b/configure.ac @@ -62,43 +62,6 @@ AS_IF([test x"$with_hash_backup" != x -a x"$with_hash_backup" != x"no"], AC_DEFINE_UNQUOTED([BACKUP_PREFIX], "$backup_prefix", [The prefix that is prepended to the name of message files when they are "removed" by rmm. This should typically be `,' or `#'.])dnl -dnl What method of locking to use? -AS_CASE(["$host_os"], - [aix*|cygwin*|linux*], - [default_locktype="fcntl"; default_locking=FCNTL_LOCKING], - [freebsd*|openbsd*|darwin*], [default_locktype="flock"; default_locking=FLOCK_LOCKING], - [default_locktype="dot"; default_locking=DOT_LOCKING]) - -AC_ARG_WITH([locking], - AS_HELP_STRING([--with-locking=@<:@dot|fcntl|flock|lockf@:>@], - [specify the file locking method])) - -AS_IF([test x"$with_locking" = x"dot"], - [LOCKTYPE="dot" - AC_DEFINE([DOT_LOCKING], [1], [Define to use dot based file locking.])], - [test x"$with_locking" = x"flock"], - [LOCKTYPE="flock" - AC_DEFINE([FLOCK_LOCKING], [1], [Define to use flock() based locking.])], - [test x"$with_locking" = x"lockf"], - [LOCKTYPE="lockf" - AC_DEFINE([LOCKF_LOCKING], [1], [Define to use lockf() based locking.])], - [test x"$with_locking" = x"fcntl"], - [LOCKTYPE="fcntl" - AC_DEFINE([FCNTL_LOCKING], [1], [Define to use fnctl() based locking.])], - [LOCKTYPE="$default_locktype" - AC_DEFINE_UNQUOTED([$default_locking], [1])]) - -dnl Should we use a locking directory? -AC_ARG_ENABLE([lockdir], - [AS_HELP_STRING([--enable-lockdir=dir], [Store dot-lock files in "dir"])], [ - AS_IF([test "x$enableval" = xyes],[ - AC_MSG_ERROR([--enable-lockdir requires an argument])]) - AS_IF([test "x$LOCKTYPE" != xdot],[ - AC_MSG_ERROR([Can only use --enable-lockdir with dot locking])]) - AC_DEFINE_UNQUOTED([LOCKDIR], ["$enableval"], - [Directory to store dot-locking lock files]) -]) - dnl What method of posting should post use? AC_ARG_WITH([mts], AS_HELP_STRING([--with-mts=@<:@smtp|sendmail/smtp|sendmail/pipe@:>@], @@ -409,6 +372,9 @@ NMH_CHECK_NETLIBS dnl Check for readline support NMH_READLINE +dnl Check the locking functions supported and what we should use by default +NMH_LOCKING + dnl Check for iconv NMH_CHECK_ICONV diff --git a/h/mh.h b/h/mh.h index daf47c02..2d977446 100644 --- a/h/mh.h +++ b/h/mh.h @@ -316,6 +316,12 @@ typedef struct m_getfld_state *m_getfld_state_t; #define NMH_ATTACH_HEADER "Nmh-Attachment" /* Default header for -attach */ +/* + * The type of locking we support + */ + +enum locktype { FCNTL_LOCKING, FLOCK_LOCKING, LOCKF_LOCKING, DOT_LOCKING }; + /* * miscellaneous macros */ diff --git a/h/prototypes.h b/h/prototypes.h index ae6a115e..fff761d4 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -1,6 +1,9 @@ /* * prototypes.h -- various prototypes + * + * If you modify functions here, please document their current behavior + * as much as practical. */ /* @@ -76,10 +79,19 @@ char *get_charset(void); char *getcpy (char *); char *get_default_editor(void); char *getfolder(int); +/* + * Parse a lock type and return the type of lock it is + */ +enum locktype init_locktype(const char *); +/* + * Lock open/close routines. The 3rd argument to lkopen/lfkopen is an + * integer which indicates the type of lock. A "0" means a shared (read) + * lock, and a "1" indicates an exclusive (write) lock. + */ int lkclose(int, char*); int lkfclose(FILE *, char *); -FILE *lkfopen(char *, char *); -int lkopen(char *, int, mode_t); +FILE *lkfopen(char *, char *, int); +int lkopen(char *, int, mode_t, int); int m_atoi (char *); char *m_backup (char *); int m_convert (struct msgs *, char *); diff --git a/m4/locking.m4 b/m4/locking.m4 new file mode 100644 index 00000000..e013790a --- /dev/null +++ b/m4/locking.m4 @@ -0,0 +1,48 @@ +dnl +dnl Our functions to check the locking functions available and select a +dnl default locking function for the spool file +dnl +dnl Since we're assuming POSIX as a minimum, we always assume we have fcntl +dnl locking available. +dnl + +AC_DEFUN([NMH_LOCKING], +[AC_CHECK_FUNCS([flock lockf]) +AS_CASE(["$host_os"], + [aix*|cygwin*|linux*], + [default_locktype="fcntl"], + [freebsd*|openbsd*|darwin*], [default_locktype="flock"], + [default_locktype="dot"]) + +AC_MSG_CHECKING([default locking method for the mail spool]) + +AC_ARG_WITH([locking], + AS_HELP_STRING([--with-locking=@<:@dot|fcntl|flock|lockf@:>@], + [The default locking method for the mail spool file]), , + [with_locking="$default_locktype"]) + +AS_CASE([$with_locking], + [fcntl|dot], , + [flock], + [AS_IF([test x"$ac_cv_func_flock" != x"yes"], + [AC_MSG_ERROR([flock locks not supported on this system])])], + [lockf], + [AS_IF([test x"$ac_cv_func_lockf" != x"yes"], + [AC_MSG_ERROR([lockf locks not supported on this system])])], + [no], + [AC_MSG_ERROR([--without-locking not supported])], + [AC_MSG_ERROR([Unknown locking type $with_locking])]) + +AC_DEFINE_UNQUOTED([DEFAULT_LOCKING], [$with_locking], + [The default lock type for the mail spool file]) + +AC_MSG_RESULT([$with_locking]) + +dnl Should we use a locking directory? +AC_ARG_ENABLE([lockdir], + [AS_HELP_STRING([--enable-lockdir=dir], [Store dot-lock files in "dir"])], [ + AS_IF([test "x$enableval" = xyes],[ + AC_MSG_ERROR([--enable-lockdir requires an argument])]) + AC_DEFINE_UNQUOTED([LOCKDIR], ["$enableval"], + [Directory to store dot-locking lock files]) +])]) diff --git a/sbr/lock_file.c b/sbr/lock_file.c index bbfc8fc7..6653a28b 100644 --- a/sbr/lock_file.c +++ b/sbr/lock_file.c @@ -24,15 +24,12 @@ #endif #include #include - -#ifdef HAVE_FCNTL_H -# include -#else +#include +#ifdef HAVE_FLOCK # include #endif - -#if defined(LOCKF_LOCKING) || defined(FLOCK_LOCKING) -# include +#ifdef HAVE_LOCKF +# include #endif #include @@ -45,13 +42,6 @@ char *lockdir = LOCKDIR; #endif -/* Are we using any kernel locking? */ -#if defined (FLOCK_LOCKING) || defined(LOCKF_LOCKING) || defined(FCNTL_LOCKING) -# define KERNEL_LOCKING -#endif - -#ifdef DOT_LOCKING - /* struct for getting name of lock file to create */ struct lockinfo { char curlock[BUFSIZ]; @@ -83,14 +73,11 @@ struct lock { /* top of list containing all open locks */ static struct lock *l_top = NULL; -#endif /* DOT_LOCKING */ -/* - * static prototypes - */ -#ifdef KERNEL_LOCKING -static int lkopen_kernel (char *, int, mode_t); -#endif +static int lkopen_fcntl (char *, int, mode_t, int); +#ifdef HAVE_LOCKF +static int lkopen_lockf (char *, int, mode_t, int); +#endif /* HAVE_LOCKF */ #ifdef DOT_LOCKING static int lkopen_dot (char *, int, mode_t); @@ -609,3 +596,33 @@ alrmser (int sig) } #endif /* DOT_LOCKING */ + +/* + * Return a locking algorithm based on the string name + */ + +enum locktype +init_locktype(const char *lockname) +{ + if (mh_strcasecmp(lockname, "fcntl") == 0) { + return FCNTL_LOCKING; + } else if (mh_strcasecmp(lockname, "lockf") == 0) { +#ifdef HAVE_LOCKF + return LOCKF_LOCKING; +#else /* ! HAVE_LOCKF */ + adios(NULL, "lockf not supported on this system"); +#endif /* HAVE_LOCKF */ + } else if (mh_strcasecmp(lockname, "flock") == 0) { +#ifdef HAVE_FLOCK + return FLOCK_LOCKING; +#else /* ! HAVE_FLOCK */ + adios(NULL, "flock not supported on this system"); +#endif /* HAVE_FLOCK */ + } else if (mh_strcasecmp(lockname, "dot") == 0) { + return DOT_LOCKING; + } else { + adios(NULL, "Unknown lock type: \"%s\"", lockname) + /* NOTREACHED */ + return 0; + } +}