/* BeLock.c - implementation of Fido-style message bases lock BeOS library. bases lock BeOS library. This code is written by Siarzhuk Zharski <imker@gmx.li> for free and can be used for any purposes in any form without any warranties. */ #include <stdio.h> #include <errno.h> #include "be_lock.h" static const char rcsid[]="$Id$"; static status_t look_for_port(int file_handle, bool b_create, port_id *port_id_ptr) { status_t status = B_OK; struct stat st = {0}; char name[B_OS_NAME_LENGTH] = {0}; if(fstat(file_handle, &st)) return B_IO_ERROR; sprintf(name, "FidoLock:%08X:%08X", st.st_dev, st.st_ino); *port_id_ptr = find_port(name); if(*port_id_ptr == B_NAME_NOT_FOUND) { if(b_create) { *port_id_ptr = create_port(1, name); if(*port_id_ptr == B_BAD_VALUE || *port_id_ptr == B_NO_MORE_PORTS) status = *port_id_ptr; } else status = B_NAME_NOT_FOUND; } else // already have such lock ... status = B_BUSY; return status; } status_t beos_lock(int file_handle) { port_id pid = 0; return look_for_port(file_handle, true, &pid); } status_t beos_unlock(int file_handle) { port_id pid = 0; status_t status = look_for_port(file_handle, false, &pid); if(status == B_BUSY) status = delete_port(pid); return status; } #define IMPLEMENT_BEOS_FUNC(_FUNC_NAME, _FUNC)\ status_t _FUNC_NAME(FILE *handle) \ { \ int file_handle = fileno(handle); \ if(file_handle == -1) \ return B_IO_ERROR; \ return _FUNC(file_handle); \ } \ IMPLEMENT_BEOS_FUNC(beos_flock, beos_lock) IMPLEMENT_BEOS_FUNC(beos_funlock, beos_unlock) #define IMPLEMENT_BE_FUNC(_FUNC_NAME, _HANDLE_TYPE, _FUNC)\ int _FUNC_NAME(_HANDLE_TYPE handle)\ { \ int ret_value = 0; \ status_t status = _FUNC(handle); \ if(status != B_OK) \ { \ errno = status; \ ret_value = -1; \ } \ return ret_value; \ } \ IMPLEMENT_BE_FUNC(be_lock, int, beos_lock) IMPLEMENT_BE_FUNC(be_unlock, int, beos_unlock) IMPLEMENT_BE_FUNC(be_flock, FILE *, beos_flock) IMPLEMENT_BE_FUNC(be_funlock, FILE *, beos_funlock)