/* BeLock.h - interface to Fido-style message bases lock library. Copyright 2001-2003 Siarzhuk Zharski, imker@gmx.li All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: 4. Neither the names of the authors nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* COMMENT: Many of Fidonet message bases uses file locks for theirs work in concurrent environment. The Be Operating System has not such possibility. Existing BeOS inplementations of locking allows to block only "nodes" from any access. This blocking cannot prevent from some "entry" modification attempts - for example, you can delete such file without problems or move it to somewhere. The node is still locked but it is not that we wait for. After long discussion on beos developer mail-lists I have not found usable solution for this problem. That's why I decide to implement some alternative locking technology. The key idea of my locking is using some BeOS-specific kernel objects. At this time I found only single one to be accessible from many processes - the BeOS kernel ports. See BeBook->Kernel Kit->Ports for details. We can create port with some name and we can look for port with such name in the system. Than, the locking algorithm is below: 1) Get the device and node IDs for file handle we going to lock: fstat(file_handle, &stat_info); 2) Create the name for the port to be used as locking object: sprintf(name, "FidoLock:%08X:%08X", stat_info.st_dev, stat_info.st_ino); 3) Look for existing port with this name: pid = find_port(name); if(pid == B_NAME_NOT_FOUND) { 4) Create such port. pid = create_port(1, name); } else { 5) If such port exists - the file is locked - we must not touch it now - say calling program about failed lock. } To unlock locked file - just delete the port delete_port(pid); This technique is also not perfect, but, in my opinion it is more safe than node locking and more safe that work without any locking at al. */ #ifndef __BeLock_H_ #define __BeLock_H_ #include #ifdef __cplusplus extern "C" { #endif //__cplusplus /* be[os]_[f][un]lock() - acquires/releases file lock for file handle or stream parameters: file_handle - hanlde to file you want to [un]lock file - opened stream for file you want to [un]lock returns: be_* - set of functions: 0 - on success -1 - on fails. See errno for error code and B_* - codes below. beos_* - set of functions: B_OK [0x00000000] - on success other codes on error: B_IO_ERROR (EIO) [0x80000001] - input/output error. For example fstat or fileno on file handles failed. B_NAME_NOT_FOUND [0x80000007] - port_name doesn't name an existing port. Try to unlock non-existing filelock. B_BAD_VALUE (EINVAL) [0x80000005] - port's queue_length is too big or less than zero. Error creating new port. B_NO_MORE_PORTS [0x80001201] - the system couldn't allocate another port. Error creating new port. B_BUSY (EBUSY) [0x8000000E] - file is already locked - port exists. B_BAD_PORT_ID [0x80001200] - port doesn't identify an open port. $Id$ */ int be_lock(int file_handle); int be_unlock(int file_handle); int be_flock(FILE *file); int be_funlock(FILE *file); status_t beos_lock(int file_handle); status_t beos_unlock(int file_handle); status_t beos_flock(FILE *file); status_t beos_funlock(FILE *file); #ifdef __cplusplus } //extern "C" #endif //__cplusplus #endif // __BeLock_H_