--- imap-2001a/src/osdep/unix/os_lnx.h.flock 2002-10-17 13:59:58 +0400 +++ imap-2001a/src/osdep/unix/os_lnx.h 2002-10-17 13:59:58 +0400 @@ -47,3 +47,4 @@ #define utime portable_utime int portable_utime (char *file,time_t timep[2]); +#include "flocksim.h" --- imap-2001a/src/osdep/unix/nfstold.c.flock 2001-04-11 01:20:31 +0400 +++ imap-2001a/src/osdep/unix/nfstold.c 2002-10-17 13:59:58 +0400 @@ -18,6 +18,10 @@ * CPYRIGHT, included with this Distribution. */ +#include +#include +#include + /* Test for NFS * Accepts: file descriptor * Returns: T if NFS file, NIL otherwise --- imap-2001a/src/osdep/unix/os_lnx.c.flock 2002-10-17 13:59:58 +0400 +++ imap-2001a/src/osdep/unix/os_lnx.c 2002-10-17 13:59:58 +0400 @@ -41,5 +41,7 @@ #define fork vfork #include "tcp_unix.c" #include "gr_waitp.c" +#include +#include "flocksim.c" #include "tz_sv4.c" #include "utime.c" --- imap-2001a/src/osdep/unix/flocksim.c.flock 2001-11-06 19:49:29 +0300 +++ imap-2001a/src/osdep/unix/flocksim.c 2002-10-17 14:23:23 +0400 @@ -20,7 +20,7 @@ #undef flock /* name is used as a struct for fcntl */ #undef fork /* make damn sure that we don't use vfork!! */ -#include "nfstest.c" /* get NFS tester */ +/* Do not care about NFS: treat it just as any other FS */ #ifndef NSIG /* don't know if this can happen */ #define NSIG 32 /* a common maximum */ @@ -55,36 +55,56 @@ return -1; } - /* Make fcntl() locking of NFS files be a no-op the way it is with flock() - * on BSD. This is because the rpc.statd/rpc.lockd daemons don't work very + /* DO NOT make fcntl() locking of NFS files be a no-op the way it is with flock() + * on BSD. We do not care if the rpc.statd/rpc.lockd daemons don't work very * well and cause cluster-wide hangs if you exercise them at all. The - * result of this is that you lose the ability to detect shared mail_open() - * on NFS-mounted files. If you are wise, you'll use IMAP instead of NFS + * result of this would be that you lose the ability to detect shared mail_open() + * on NFS-mounted files and on some other innocent files (e.g on reiserfs). + * If you are wise, you'll use IMAP instead of NFS * for mail files. * + * I suggest you to check this yourself if it applies to you: * Sun alleges that it doesn't matter, because they say they have fixed all * the rpc.statd/rpc.lockd bugs. This is absolutely not true; huge amounts * of user and support time have been wasted in cluster-wide hangs. */ - if (test_nfs (fd) || mail_parameters (NIL,GET_DISABLEFCNTLLOCK,NIL)) + if (mail_parameters (NIL,GET_DISABLEFCNTLLOCK,NIL)) { + /* give user a warning: it is not good in any case to have no locks */ + sprintf (tmp,"Mailbox vulnerable - you disabled fcntl(2)-locking"); + MM_LOG (tmp,WARN); return 0; /* fcntl() locking disabled, return success */ + } /* do the lock */ - while (fcntl (fd,(op & LOCK_NB) ? F_SETLK : F_SETLKW,&fl)) - if (errno != EINTR) { - /* Can't use switch here because these error codes may resolve to the - * same value on some systems. - */ - if ((errno != EWOULDBLOCK) && (errno != EAGAIN) && (errno != EACCES)) { - sprintf (tmp,"Unexpected file locking failure: %s",strerror (errno)); - /* give the user a warning of what happened */ + while (fcntl (fd,(op & LOCK_NB) ? F_SETLK : F_SETLKW,&fl)) { + /* Can't use switch here because some error codes may resolve to the + * same value on some systems. + */ + if (errno == EINTR) /* interrupt */ + continue; + if ( (errno == ENOLCK) /* lock table is full */ + || (errno == EDEADLK) ) /* system thinks it would cause a deadlock */ + { + sprintf (tmp,"File locking failure: %s",strerror (errno)); + /* give the user a warning of what happened */ MM_NOTIFY (NIL,tmp,WARN); if (!logged++) syslog (LOG_ERR,"%s",tmp); - if (op & LOCK_NB) return -1; - sleep (5); /* slow things down for loops */ + if (op & LOCK_NB) return -1;/* return failure if non-blocking lock */ + sleep (5); /* slow down in case it loops */ + continue; } - /* return failure for non-blocking lock */ - else if (op & LOCK_NB) return -1; - } + if ( (errno == EACCES) /* lock held by another process? */ + || (errno == EWOULDBLOCK) /* file is locked */ + || (errno == EAGAIN) ) + { + if (op & LOCK_NB) return -1;/* return failure if non-blocking lock */ + continue; + } + /* case EBADF: not valid open file descriptor */ + /* case EINVAL: invalid operator */ + /* other error code? */ + sprintf (tmp,"Unexpected file locking failure: %s",strerror (errno)); + fatal (tmp); + } return 0; /* success */ } --- imap-2001a/src/osdep/unix/nfstnew.c.flock 2001-04-13 00:37:59 +0400 +++ imap-2001a/src/osdep/unix/nfstnew.c 2002-10-17 13:59:58 +0400 @@ -19,6 +19,8 @@ */ #include +#include +#include /* Test for NFS * Accepts: file descriptor