1 /* 2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it is 13 * free of the rightful claim of any third person regarding infringement 14 * or the like. Any license provided herein, whether implied or 15 * otherwise, applies only to this software file. Patent licenses, if 16 * any, provided herein do not apply to combinations of this program with 17 * other software, or any other product whatsoever. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write the Free Software Foundation, Inc., 21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 24 * Mountain View, CA 94043, or: 25 * 26 * http://www.sgi.com 27 * 28 * For further information regarding this notice, see: 29 * 30 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ 31 */ 32 #include <sys/types.h> 33 #include <sys/stat.h> 34 #include <sys/file.h> 35 #include <sys/param.h> 36 #include <fcntl.h> 37 #include <unistd.h> 38 #include <stdio.h> 39 #include <errno.h> 40 #include <sys/sysmacros.h> 41 #include <string.h> /* memset, strerror */ 42 #include "file_lock.h" 43 44 #ifndef EFSEXCLWR 45 #define EFSEXCLWR 503 46 #endif 47 48 /* 49 * String containing the last system call. 50 * 51 */ 52 char Fl_syscall_str[128]; 53 54 static char errmsg[256]; 55 56 /*********************************************************************** 57 * 58 * Test interface to the fcntl system call. 59 * It will loop if the LOCK_NB flags is NOT set. 60 ***********************************************************************/ 61 int file_lock(int fd, int flags, char **errormsg) 62 { 63 register int cmd, ret; 64 struct flock flocks; 65 66 memset(&flocks, 0, sizeof(struct flock)); 67 68 if (flags & LOCK_NB) 69 cmd = F_SETLK; 70 else 71 cmd = F_SETLKW; 72 73 flocks.l_whence = 0; 74 flocks.l_start = 0; 75 flocks.l_len = 0; 76 77 if (flags & LOCK_UN) 78 flocks.l_type = F_UNLCK; 79 else if (flags & LOCK_EX) 80 flocks.l_type = F_WRLCK; 81 else if (flags & LOCK_SH) 82 flocks.l_type = F_RDLCK; 83 else { 84 errno = EINVAL; 85 if (errormsg != NULL) { 86 sprintf(errmsg, 87 "Programmer error, called file_lock with in valid flags\n"); 88 *errormsg = errmsg; 89 } 90 return -1; 91 } 92 93 sprintf(Fl_syscall_str, 94 "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n", 95 fd, cmd, flocks.l_type, flocks.l_whence, 96 (long long)flocks.l_start, (long long)flocks.l_len); 97 98 while (1) { 99 ret = fcntl(fd, cmd, &flocks); 100 101 if (ret < 0) { 102 if (cmd == F_SETLK) 103 switch (errno) { 104 /* these errors are okay */ 105 case EACCES: /* Permission denied */ 106 case EINTR: /* interrupted system call */ 107 #ifdef EFILESH 108 case EFILESH: /* file shared */ 109 #endif 110 case EFSEXCLWR: /* File is write protected */ 111 continue; /* retry getting lock */ 112 } 113 if (errormsg != NULL) { 114 sprintf(errmsg, 115 "fcntl(%d, %d, &flocks): errno:%d %s\n", 116 fd, cmd, errno, strerror(errno)); 117 *errormsg = errmsg; 118 } 119 return -1; 120 } 121 break; 122 } 123 124 return ret; 125 126 } /* end of file_lock */ 127 128 /*********************************************************************** 129 * 130 * Test interface to the fcntl system call. 131 * It will loop if the LOCK_NB flags is NOT set. 132 ***********************************************************************/ 133 int record_lock(int fd, int flags, int start, int len, char **errormsg) 134 { 135 register int cmd, ret; 136 struct flock flocks; 137 138 memset(&flocks, 0, sizeof(struct flock)); 139 140 if (flags & LOCK_NB) 141 cmd = F_SETLK; 142 else 143 cmd = F_SETLKW; 144 145 flocks.l_whence = 0; 146 flocks.l_start = start; 147 flocks.l_len = len; 148 149 if (flags & LOCK_UN) 150 flocks.l_type = F_UNLCK; 151 else if (flags & LOCK_EX) 152 flocks.l_type = F_WRLCK; 153 else if (flags & LOCK_SH) 154 flocks.l_type = F_RDLCK; 155 else { 156 errno = EINVAL; 157 if (errormsg != NULL) { 158 sprintf(errmsg, 159 "Programmer error, called record_lock with in valid flags\n"); 160 *errormsg = errmsg; 161 } 162 return -1; 163 } 164 165 sprintf(Fl_syscall_str, 166 "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n", 167 fd, cmd, flocks.l_type, flocks.l_whence, 168 (long long)flocks.l_start, (long long)flocks.l_len); 169 170 while (1) { 171 ret = fcntl(fd, cmd, &flocks); 172 173 if (ret < 0) { 174 if (cmd == F_SETLK) 175 switch (errno) { 176 /* these errors are okay */ 177 case EACCES: /* Permission denied */ 178 case EINTR: /* interrupted system call */ 179 #ifdef EFILESH 180 case EFILESH: /* file shared */ 181 #endif 182 case EFSEXCLWR: /* File is write protected */ 183 continue; /* retry getting lock */ 184 } 185 if (errormsg != NULL) { 186 sprintf(errmsg, 187 "fcntl(%d, %d, &flocks): errno:%d %s\n", 188 fd, cmd, errno, strerror(errno)); 189 *errormsg = errmsg; 190 } 191 return -1; 192 } 193 break; 194 } 195 196 return ret; 197 198 } /* end of record_lock */ 199