lockfix.h
上传用户:ycwykj01
上传日期:2007-01-04
资源大小:1819k
文件大小:3k
源码类别:

网络编程

开发平台:

Unix_Linux

  1. /*
  2.  * Program: Safe function call for fcntl() locking
  3.  *
  4.  * Author: Mark Crispin
  5.  * Networks and Distributed Computing
  6.  * Computing & Communications
  7.  * University of Washington
  8.  * Administration Building, AG-44
  9.  * Seattle, WA  98195
  10.  * Internet: MRC@CAC.Washington.EDU
  11.  *
  12.  * Date: 22 May 1997
  13.  * Last Edited: 5 June 1997
  14.  *
  15.  * Copyright 1997 by the University of Washington
  16.  *
  17.  *  Permission to use, copy, modify, and distribute this software and its
  18.  * documentation for any purpose and without fee is hereby granted, provided
  19.  * that the above copyright notice appears in all copies and that both the
  20.  * above copyright notice and this permission notice appear in supporting
  21.  * documentation, and that the name of the University of Washington not be
  22.  * used in advertising or publicity pertaining to distribution of the software
  23.  * without specific, written prior permission.  This software is made available
  24.  * "as is", and
  25.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  26.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  27.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  28.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  29.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  30.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  31.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  32.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  33.  *
  34.  */
  35. /*  The purpose of this nonsense is to work around a bad bug in fcntl()
  36.  * locking.  The cretins who designed it decided that a close() should
  37.  * release any locks made by that process on the file opened on that
  38.  * file descriptor.  Never mind that the lock wasn't made on that file
  39.  * descriptor, but rather on some other file descriptor.
  40.  *
  41.  *  This bug is on every implementation of fcntl() locking that I have
  42.  * tested.  Fortunately, on BSD systems and OSF/1, we can use the flock()
  43.  * system call which doesn't have this bug.
  44.  *
  45.  *  On broken systems, we invoke an inferior fork to execute any driver
  46.  * dispatches which are likely to tickle this bug; specifically, any
  47.  * dispatch which may fiddle with a mailbox that is already selected.  As
  48.  * of this writing, these are: delete, rename, status, copy, and append.
  49.  *
  50.  *  Delete and rename are pretty marginal (does anyone really want to
  51.  * deleted or rename the selected mailbox?).  The same is true of status,
  52.  * but there are people who don't understand why status of the selected
  53.  * mailbox is bad news.
  54.  *
  55.  *  However, in copy and append it is reasonable to do this to a selected
  56.  * mailbox.
  57.  *
  58.  *  It is still possible for an application to trigger this bug by doing
  59.  * mail_open() on the same mailbox twice.  Don't do it.
  60.  */
  61. /* Safe call to function
  62.  * Accepts: driver dispatch table
  63.  *     return value
  64.  *     function to call
  65.  *     function arguments
  66.  */
  67. #undef SAFE_FUNCTION
  68. #define SAFE_FUNCTION(dtb,ret,func,args) {
  69.   if (dtb->flags & DR_LOCKING) {
  70.     int pid = fork ();
  71.     if (pid < 0) mm_log ("Can't create execution fork",ERROR);
  72.     else if (pid) {
  73.       grim_pid_reap_status (pid,NIL,&ret);
  74.       ret = ((ret & 0177) == 0177) ? (ret >> 8) : 0;
  75.     }
  76.     else exit (func args);
  77.   }
  78.   else ret = func args;
  79. }