filelock-darwin.cpp revision c7945191b700920f0ab9b951ce92cc69cb48ffb4
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync/* $Id$ */
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync/** @file
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * InnoTek Portable Runtime - File Locking, POSIX.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync */
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync/*
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * Copyright (C) 2006 InnoTek Systemberatung GmbH
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync *
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * available from http://www.virtualbox.org. This file is free software;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * you can redistribute it and/or modify it under the terms of the GNU
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * General Public License as published by the Free Software Foundation,
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync *
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * If you received this file as part of a commercial VirtualBox
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * distribution, then only the terms of your commercial VirtualBox
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * license agreement apply instead of the previous paragraph.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync */
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync/*******************************************************************************
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync* Header Files *
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync*******************************************************************************/
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#define LOG_GROUP RTLOGGROUP_FILE
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include <errno.h>
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include <sys/types.h>
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include <sys/ioctl.h>
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include <sys/fcntl.hs>
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include <fcntl.h>
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include <unistd.h>
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include <sys/time.h>
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include <iprt/file.h>
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include <iprt/assert.h>
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include <iprt/string.h>
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include <iprt/err.h>
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include <iprt/log.h>
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include "internal/file.h"
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync#include "internal/fs.h"
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncRTR3DECL(int) RTFileLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock)
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync{
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync Assert(offLock >= 0);
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync /* Check arguments. */
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync if (fLock & ~RTFILE_LOCK_MASK)
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync {
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync AssertMsgFailed(("Invalid fLock=%08X\n", fLock));
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync return VERR_INVALID_PARAMETER;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync }
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync /*
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * Validate offset.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync */
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync if ( sizeof(off_t) < sizeof(cbLock)
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync && ( (offLock >> 32) != 0
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync || (cbLock >> 32) != 0
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync || ((offLock + cbLock) >> 32) != 0))
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync {
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync AssertMsgFailed(("64-bit file i/o not supported! offLock=%lld cbLock=%lld\n", offLock, cbLock));
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync return VERR_NOT_SUPPORTED;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync }
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync /* Prepare flock structure. */
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync struct flock fl;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync Assert(RTFILE_LOCK_WRITE);
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync fl.l_type = (fLock & RTFILE_LOCK_WRITE) ? F_WRLCK : F_RDLCK;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync fl.l_whence = SEEK_SET;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync fl.l_start = (off_t)offLock;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync fl.l_len = (off_t)cbLock;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync fl.l_pid = 0;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync Assert(RTFILE_LOCK_WAIT);
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync if (fcntl(File, (fLock & RTFILE_LOCK_WAIT) ? F_SETLKW : F_SETLK, &fl) >= 0)
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync return VINF_SUCCESS;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync int iErr = errno;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync if ( iErr == EAGAIN
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync || iErr == EACCES)
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync return VERR_FILE_LOCK_VIOLATION;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync return RTErrConvertFromErrno(iErr);
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync}
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncRTR3DECL(int) RTFileChangeLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock)
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync{
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync /** @todo We never returns VERR_FILE_NOT_LOCKED for now. */
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync return RTFileLock(File, fLock, offLock, cbLock);
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync}
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncRTR3DECL(int) RTFileUnlock(RTFILE File, int64_t offLock, uint64_t cbLock)
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync{
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync Assert(offLock >= 0);
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync /*
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync * Validate offset.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync */
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync if ( sizeof(off_t) < sizeof(cbLock)
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync && ( (offLock >> 32) != 0
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync || (cbLock >> 32) != 0
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync || ((offLock + cbLock) >> 32) != 0))
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync {
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync AssertMsgFailed(("64-bit file i/o not supported! offLock=%lld cbLock=%lld\n", offLock, cbLock));
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync return VERR_NOT_SUPPORTED;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync }
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync /* Prepare flock structure. */
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync struct flock fl;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync fl.l_type = F_UNLCK;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync fl.l_whence = SEEK_SET;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync fl.l_start = (off_t)offLock;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync fl.l_len = (off_t)cbLock;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync fl.l_pid = 0;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync if (fcntl(File, F_SETLK, &fl) >= 0)
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync return VINF_SUCCESS;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync /* @todo check error codes for non existing lock. */
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync int iErr = errno;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync if ( iErr == EAGAIN
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync || iErr == EACCES)
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync return VERR_FILE_LOCK_VIOLATION;
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync return RTErrConvertFromErrno(iErr);
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync}
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync