xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/open_lock.c (revision 41fbaed053f8fbfdf9d2a4ee0a7386a3c83f8505)
1 /*	$NetBSD: open_lock.c,v 1.1.1.1 2009/06/23 10:09:00 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	open_lock 3
6 /* SUMMARY
7 /*	open or create file and lock it for exclusive access
8 /* SYNOPSIS
9 /*	#include <open_lock.h>
10 /*
11 /*	VSTREAM	*open_lock(path, flags, mode, why)
12 /*	const char *path;
13 /*	int	flags;
14 /*	mode_t	mode;
15 /*	VSTRING *why;
16 /* DESCRIPTION
17 /*	This module opens or creates the named file and attempts to
18 /*	acquire an exclusive lock.  The lock is lost when the last
19 /*	process closes the file.
20 /*
21 /*	Arguments:
22 /* .IP "path, flags, mode"
23 /*	These are passed on to safe_open().
24 /* .IP why
25 /*	storage for diagnostics.
26 /* SEE ALSO
27 /*	safe_open(3) carefully open or create file
28 /*	myflock(3) get exclusive lock on file
29 /* DIAGNOSTICS
30 /*	In case of problems the result is a null pointer and a problem
31 /*	description is returned via the global \fIerrno\fR variable.
32 /* LICENSE
33 /* .ad
34 /* .fi
35 /*	The Secure Mailer license must be distributed with this software.
36 /* AUTHOR(S)
37 /*	Wietse Venema
38 /*	IBM T.J. Watson Research
39 /*	P.O. Box 704
40 /*	Yorktown Heights, NY 10598, USA
41 /*--*/
42 
43 /* System library. */
44 
45 #include <sys_defs.h>
46 #include <unistd.h>
47 #include <fcntl.h>
48 
49 /* Utility library. */
50 
51 #include <msg.h>
52 #include <vstream.h>
53 #include <vstring.h>
54 #include <safe_open.h>
55 #include <myflock.h>
56 #include <open_lock.h>
57 
58 /* open_lock - open file and lock it for exclusive access */
59 
open_lock(const char * path,int flags,mode_t mode,VSTRING * why)60 VSTREAM *open_lock(const char *path, int flags, mode_t mode, VSTRING *why)
61 {
62     VSTREAM *fp;
63 
64     /*
65      * Carefully create or open the file, and lock it down. Some systems
66      * don't have the O_LOCK open() flag, or the flag does not do what we
67      * want, so we roll our own lock.
68      */
69     if ((fp = safe_open(path, flags, mode, (struct stat *) 0, -1, -1, why)) == 0)
70 	return (0);
71     if (myflock(vstream_fileno(fp), INTERNAL_LOCK,
72 		MYFLOCK_OP_EXCLUSIVE | MYFLOCK_OP_NOWAIT) < 0) {
73 	vstring_sprintf(why, "unable to set exclusive lock: %m");
74 	vstream_fclose(fp);
75 	return (0);
76     }
77     return (fp);
78 }
79