144 lines
5.1 KiB
C
144 lines
5.1 KiB
C
|
/*
|
||
|
|
||
|
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 <OS.h>
|
||
|
|
||
|
#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_
|