1/*	$NetBSD$	*/
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
60VSTREAM *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