Close all vdi's before exit, by Daniel.
[vdi_driver.git] / src / filelock.cpp
bloba9e9f208cba5c69d8adee12d2ec8831a9a0900e7
1 /* $Id: filelock-posix.cpp 23517 2007-08-07 17:07:59Z umoeller $ */
2 /** @file
3 * innotek Portable Runtime - File Locking, POSIX.
4 */
6 /*
7 * Copyright (C) 2006-2007 innotek GmbH
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
19 /*******************************************************************************
20 * Header Files *
21 *******************************************************************************/
22 #define LOG_GROUP RTLOGGROUP_FILE
24 #include <errno.h>
25 #include <sys/types.h>
26 #include <sys/ioctl.h>
27 #include <sys/fcntl.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <sys/time.h>
32 #include "file.h"
33 #include "func_defines.h"
34 #include "const_defines.h"
35 #include "fs.h"
36 #include "RTErrConvertFromErrno.h"
40 int RTFileLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock)
42 Assert(offLock >= 0);
44 /* Check arguments. */
45 if (fLock & ~RTFILE_LOCK_MASK)
47 AssertMsgFailed(("Invalid fLock=%08X\n", fLock));
48 return VERR_INVALID_PARAMETER;
52 * Validate offset.
54 if ( sizeof(off_t) < sizeof(cbLock)
55 && ( (offLock >> 32) != 0
56 || (cbLock >> 32) != 0
57 || ((offLock + cbLock) >> 32) != 0))
59 AssertMsgFailed(("64-bit file i/o not supported! offLock=%lld cbLock=%lld\n", offLock, cbLock));
60 return VERR_NOT_SUPPORTED;
63 /* Prepare flock structure. */
64 struct flock fl;
65 Assert(RTFILE_LOCK_WRITE);
66 fl.l_type = (fLock & RTFILE_LOCK_WRITE) ? F_WRLCK : F_RDLCK;
67 fl.l_whence = SEEK_SET;
68 fl.l_start = (off_t)offLock;
69 fl.l_len = (off_t)cbLock;
70 fl.l_pid = 0;
72 Assert(RTFILE_LOCK_WAIT);
73 if (fcntl(File, (fLock & RTFILE_LOCK_WAIT) ? F_SETLKW : F_SETLK, &fl) >= 0)
74 return VINF_SUCCESS;
76 int iErr = errno;
77 if ( iErr == EAGAIN
78 || iErr == EACCES)
79 return VERR_FILE_LOCK_VIOLATION;
81 return RTErrConvertFromErrno(iErr);
85 int RTFileChangeLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock)
87 /** @todo We never returns VERR_FILE_NOT_LOCKED for now. */
88 return RTFileLock(File, fLock, offLock, cbLock);
92 int RTFileUnlock(RTFILE File, int64_t offLock, uint64_t cbLock)
94 Assert(offLock >= 0);
97 * Validate offset.
99 if ( sizeof(off_t) < sizeof(cbLock)
100 && ( (offLock >> 32) != 0
101 || (cbLock >> 32) != 0
102 || ((offLock + cbLock) >> 32) != 0))
104 AssertMsgFailed(("64-bit file i/o not supported! offLock=%lld cbLock=%lld\n", offLock, cbLock));
105 return VERR_NOT_SUPPORTED;
108 /* Prepare flock structure. */
109 struct flock fl;
110 fl.l_type = F_UNLCK;
111 fl.l_whence = SEEK_SET;
112 fl.l_start = (off_t)offLock;
113 fl.l_len = (off_t)cbLock;
114 fl.l_pid = 0;
116 if (fcntl(File, F_SETLK, &fl) >= 0)
117 return VINF_SUCCESS;
119 /* @todo check error codes for non existing lock. */
120 int iErr = errno;
121 if ( iErr == EAGAIN
122 || iErr == EACCES)
123 return VERR_FILE_LOCK_VIOLATION;
125 return RTErrConvertFromErrno(iErr);