/* * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Further, this software is distributed without any warranty that it is * free of the rightful claim of any third person regarding infringement * or the like. Any license provided herein, whether implied or * otherwise, applies only to this software file. Patent licenses, if * any, provided herein do not apply to combinations of this program with * other software, or any other product whatsoever. * * You should have received a copy of the GNU General Public License along * with this program; if not, write the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, * Mountain View, CA 94043, or: * * http://www.sgi.com * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ */ #include <sys/types.h> #include <sys/stat.h> #include <sys/file.h> #include <sys/param.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <errno.h> #include <sys/sysmacros.h> #include <string.h> /* memset, strerror */ #include "file_lock.h" #ifndef EFSEXCLWR #define EFSEXCLWR 503 #endif /* * String containing the last system call. * */ char Fl_syscall_str[128]; static char errmsg[256]; /*********************************************************************** * * Test interface to the fcntl system call. * It will loop if the LOCK_NB flags is NOT set. ***********************************************************************/ int file_lock(int fd, int flags, char **errormsg) { register int cmd, ret; struct flock flocks; memset(&flocks, 0, sizeof(struct flock)); if (flags & LOCK_NB) cmd = F_SETLK; else cmd = F_SETLKW; flocks.l_whence = 0; flocks.l_start = 0; flocks.l_len = 0; if (flags & LOCK_UN) flocks.l_type = F_UNLCK; else if (flags & LOCK_EX) flocks.l_type = F_WRLCK; else if (flags & LOCK_SH) flocks.l_type = F_RDLCK; else { errno = EINVAL; if (errormsg != NULL) { sprintf(errmsg, "Programmer error, called file_lock with in valid flags\n"); *errormsg = errmsg; } return -1; } sprintf(Fl_syscall_str, "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n", fd, cmd, flocks.l_type, flocks.l_whence, (long long)flocks.l_start, (long long)flocks.l_len); while (1) { ret = fcntl(fd, cmd, &flocks); if (ret < 0) { if (cmd == F_SETLK) switch (errno) { /* these errors are okay */ case EACCES: /* Permission denied */ case EINTR: /* interrupted system call */ #ifdef EFILESH case EFILESH: /* file shared */ #endif case EFSEXCLWR: /* File is write protected */ continue; /* retry getting lock */ } if (errormsg != NULL) { sprintf(errmsg, "fcntl(%d, %d, &flocks): errno:%d %s\n", fd, cmd, errno, strerror(errno)); *errormsg = errmsg; } return -1; } break; } return ret; } /* end of file_lock */ /*********************************************************************** * * Test interface to the fcntl system call. * It will loop if the LOCK_NB flags is NOT set. ***********************************************************************/ int record_lock(int fd, int flags, int start, int len, char **errormsg) { register int cmd, ret; struct flock flocks; memset(&flocks, 0, sizeof(struct flock)); if (flags & LOCK_NB) cmd = F_SETLK; else cmd = F_SETLKW; flocks.l_whence = 0; flocks.l_start = start; flocks.l_len = len; if (flags & LOCK_UN) flocks.l_type = F_UNLCK; else if (flags & LOCK_EX) flocks.l_type = F_WRLCK; else if (flags & LOCK_SH) flocks.l_type = F_RDLCK; else { errno = EINVAL; if (errormsg != NULL) { sprintf(errmsg, "Programmer error, called record_lock with in valid flags\n"); *errormsg = errmsg; } return -1; } sprintf(Fl_syscall_str, "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n", fd, cmd, flocks.l_type, flocks.l_whence, (long long)flocks.l_start, (long long)flocks.l_len); while (1) { ret = fcntl(fd, cmd, &flocks); if (ret < 0) { if (cmd == F_SETLK) switch (errno) { /* these errors are okay */ case EACCES: /* Permission denied */ case EINTR: /* interrupted system call */ #ifdef EFILESH case EFILESH: /* file shared */ #endif case EFSEXCLWR: /* File is write protected */ continue; /* retry getting lock */ } if (errormsg != NULL) { sprintf(errmsg, "fcntl(%d, %d, &flocks): errno:%d %s\n", fd, cmd, errno, strerror(errno)); *errormsg = errmsg; } return -1; } break; } return ret; } /* end of record_lock */