1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1997,2008 Oracle.  All rights reserved.
5 *
6 * $Id: os_flock.c,v 12.16 2008/01/08 20:58:43 bostic Exp $
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12
13/*
14 * __os_fdlock --
15 *	Acquire/release a lock on a byte in a file.
16 *
17 * PUBLIC: int __os_fdlock __P((ENV *, DB_FH *, off_t, int, int));
18 */
19int
20__os_fdlock(env, fhp, offset, acquire, nowait)
21	ENV *env;
22	DB_FH *fhp;
23	int acquire, nowait;
24	off_t offset;
25{
26#ifdef HAVE_FCNTL
27	DB_ENV *dbenv;
28	struct flock fl;
29	int ret, t_ret;
30
31	dbenv = env == NULL ? NULL : env->dbenv;
32
33	DB_ASSERT(env, F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
34
35	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
36		__db_msg(env,
37		    "fileops: flock %s %s offset %lu",
38		    fhp->name, acquire ? "acquire": "release", (u_long)offset);
39
40	fl.l_start = offset;
41	fl.l_len = 1;
42	fl.l_type = acquire ? F_WRLCK : F_UNLCK;
43	fl.l_whence = SEEK_SET;
44
45	RETRY_CHK_EINTR_ONLY(
46	    (fcntl(fhp->fd, nowait ? F_SETLK : F_SETLKW, &fl)), ret);
47
48	if (ret == 0)
49		return (0);
50
51	if ((t_ret = __os_posix_err(ret)) != EACCES && t_ret != EAGAIN)
52		__db_syserr(env, ret, "fcntl");
53	return (t_ret);
54#else
55	COMPQUIET(fhp, NULL);
56	COMPQUIET(acquire, 0);
57	COMPQUIET(nowait, 0);
58	COMPQUIET(offset, 0);
59	__db_syserr(env, DB_OPNOTSUP, "advisory file locking unavailable");
60	return (DB_OPNOTSUP);
61#endif
62}
63