xref: /netbsd-src/external/ibm-public/postfix/dist/src/global/deliver_flock.c (revision 41fbaed053f8fbfdf9d2a4ee0a7386a3c83f8505)
1 /*	$NetBSD: deliver_flock.c,v 1.1.1.1 2009/06/23 10:08:45 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	deliver_flock 3
6 /* SUMMARY
7 /*	lock open file for mail delivery
8 /* SYNOPSIS
9 /*	#include <deliver_flock.h>
10 /*
11 /*	int	deliver_flock(fd, lock_style, why)
12 /*	int	fd;
13 /*	int	lock_style;
14 /*	VSTRING	*why;
15 /* DESCRIPTION
16 /*	deliver_flock() sets one exclusive kernel lock on an open file,
17 /*	for example in order to deliver mail.
18 /*	It performs several non-blocking attempts to acquire an exclusive
19 /*	lock before giving up.
20 /*
21 /*	Arguments:
22 /* .IP fd
23 /*	A file descriptor that is associated with an open file.
24 /* .IP lock_style
25 /*	A locking style defined in myflock(3).
26 /* .IP why
27 /*	A null pointer, or storage for diagnostics.
28 /* DIAGNOSTICS
29 /*	deliver_flock() returns -1 in case of problems, 0 in case
30 /*	of success. The reason for failure is returned via the \fIwhy\fR
31 /*	parameter.
32 /* CONFIGURATION PARAMETERS
33 /*	deliver_lock_attempts, number of locking attempts
34 /*	deliver_lock_delay, time in seconds between attempts
35 /*	sun_mailtool_compatibility, disable kernel locking
36 /* LICENSE
37 /* .ad
38 /* .fi
39 /*	The Secure Mailer license must be distributed with this software.
40 /* AUTHOR(S)
41 /*	Wietse Venema
42 /*	IBM T.J. Watson Research
43 /*	P.O. Box 704
44 /*	Yorktown Heights, NY 10598, USA
45 /*--*/
46 
47 /* System library. */
48 
49 #include "sys_defs.h"
50 #include <unistd.h>
51 
52 /* Utility library. */
53 
54 #include <vstring.h>
55 #include <myflock.h>
56 #include <iostuff.h>
57 
58 /* Global library. */
59 
60 #include "mail_params.h"
61 #include "deliver_flock.h"
62 
63 /* Application-specific. */
64 
65 #define MILLION	1000000
66 
67 /* deliver_flock - lock open file for mail delivery */
68 
deliver_flock(int fd,int lock_style,VSTRING * why)69 int     deliver_flock(int fd, int lock_style, VSTRING *why)
70 {
71     int     i;
72 
73     for (i = 1; /* void */ ; i++) {
74 	if (myflock(fd, lock_style,
75 		    MYFLOCK_OP_EXCLUSIVE | MYFLOCK_OP_NOWAIT) == 0)
76 	    return (0);
77 	if (i >= var_flock_tries)
78 	    break;
79 	rand_sleep(var_flock_delay * MILLION, var_flock_delay * MILLION / 2);
80     }
81     if (why)
82 	vstring_sprintf(why, "unable to lock for exclusive access: %m");
83     return (-1);
84 }
85