blob: 8b66ab584c59e636806321d9449182ba3ee8f9cb [file] [log] [blame]
whrb973f2b2000-05-05 19:34:50 +00001/*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
vapier45a8ba02009-07-20 10:59:32 +00003 *
whrb973f2b2000-05-05 19:34:50 +00004 * 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.
vapier45a8ba02009-07-20 10:59:32 +00007 *
whrb973f2b2000-05-05 19:34:50 +00008 * 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.
vapier45a8ba02009-07-20 10:59:32 +000011 *
whrb973f2b2000-05-05 19:34:50 +000012 * 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.
vapier45a8ba02009-07-20 10:59:32 +000018 *
whrb973f2b2000-05-05 19:34:50 +000019 * 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., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
vapier45a8ba02009-07-20 10:59:32 +000022 *
whrb973f2b2000-05-05 19:34:50 +000023 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
vapier45a8ba02009-07-20 10:59:32 +000025 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
whrb973f2b2000-05-05 19:34:50 +000030 * 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 */
alaffincc2e5552000-07-27 17:13:18 +000042#include "file_lock.h"
whrb973f2b2000-05-05 19:34:50 +000043
whrb973f2b2000-05-05 19:34:50 +000044
45#ifndef EFSEXCLWR
46#define EFSEXCLWR 503
47#endif
48
49/*
50 * String containing the last system call.
51 *
52 */
53char Fl_syscall_str[128];
54
55static char errmsg[256];
56
57/***********************************************************************
58 *
59 * Test interface to the fcntl system call.
60 * It will loop if the LOCK_NB flags is NOT set.
61 ***********************************************************************/
62int
63file_lock(fd, flags, errormsg)
64int fd;
65int flags;
66char **errormsg;
67{
68 register int cmd, ret;
69 struct flock flocks;
70
71 memset(&flocks, 0, sizeof(struct flock));
72
73 if (flags&LOCK_NB)
74 cmd = F_SETLK;
75 else
76 cmd = F_SETLKW;
77
78 flocks.l_whence = 0;
79 flocks.l_start = 0;
80 flocks.l_len = 0;
81
82 if (flags&LOCK_UN)
83 flocks.l_type = F_UNLCK;
84 else if (flags&LOCK_EX)
85 flocks.l_type = F_WRLCK;
86 else if (flags&LOCK_SH)
87 flocks.l_type = F_RDLCK;
88 else {
89 errno = EINVAL;
90 if ( errormsg != NULL ) {
91 sprintf(errmsg,
92 "Programmer error, called file_lock with in valid flags\n");
93 *errormsg = errmsg;
94 }
95 return -1;
96 }
97
98 sprintf(Fl_syscall_str,
99 "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n",
100 fd, cmd, flocks.l_type, flocks.l_whence,
101 (long long)flocks.l_start, (long long)flocks.l_len);
102
103 while (1) {
104 ret = fcntl(fd, cmd, &flocks);
105
106 if ( ret < 0 ) {
107 if ( cmd == F_SETLK )
108 switch (errno) {
109 /* these errors are okay */
110 case EACCES: /* Permission denied */
111 case EINTR: /* interrupted system call */
112#ifdef EFILESH
113 case EFILESH: /* file shared */
114#endif
115 case EFSEXCLWR: /* File is write protected */
116 continue; /* retry getting lock */
117 }
118 if ( errormsg != NULL ) {
119 sprintf(errmsg, "fcntl(%d, %d, &flocks): errno:%d %s\n",
120 fd, cmd, errno, strerror(errno));
121 *errormsg = errmsg;
122 }
123 return -1;
124 }
125 break;
126 }
127
128 return ret;
129
130} /* end of file_lock */
131
132/***********************************************************************
133 *
134 * Test interface to the fcntl system call.
135 * It will loop if the LOCK_NB flags is NOT set.
136 ***********************************************************************/
137int
138record_lock(fd, flags, start, len, errormsg)
139int fd;
140int flags;
141int start;
142int len;
143char **errormsg;
144{
145 register int cmd, ret;
146 struct flock flocks;
147
148 memset(&flocks, 0, sizeof(struct flock));
149
150 if (flags&LOCK_NB)
151 cmd = F_SETLK;
152 else
153 cmd = F_SETLKW;
154
155 flocks.l_whence = 0;
156 flocks.l_start = start;
157 flocks.l_len = len;
158
159 if (flags&LOCK_UN)
160 flocks.l_type = F_UNLCK;
161 else if (flags&LOCK_EX)
162 flocks.l_type = F_WRLCK;
163 else if (flags&LOCK_SH)
164 flocks.l_type = F_RDLCK;
165 else {
166 errno = EINVAL;
167 if ( errormsg != NULL ) {
168 sprintf(errmsg,
169 "Programmer error, called record_lock with in valid flags\n");
170 *errormsg = errmsg;
171 }
172 return -1;
173 }
174
175 sprintf(Fl_syscall_str,
176 "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n",
177 fd, cmd, flocks.l_type, flocks.l_whence,
178 (long long)flocks.l_start, (long long)flocks.l_len);
179
180 while (1) {
181 ret = fcntl(fd, cmd, &flocks);
182
183 if ( ret < 0 ) {
184 if ( cmd == F_SETLK )
185 switch (errno) {
186 /* these errors are okay */
187 case EACCES: /* Permission denied */
188 case EINTR: /* interrupted system call */
189#ifdef EFILESH
190 case EFILESH: /* file shared */
191#endif
192 case EFSEXCLWR: /* File is write protected */
193 continue; /* retry getting lock */
194 }
195 if ( errormsg != NULL ) {
196 sprintf(errmsg, "fcntl(%d, %d, &flocks): errno:%d %s\n",
197 fd, cmd, errno, strerror(errno));
198 *errormsg = errmsg;
199 }
200 return -1;
201 }
202 break;
203 }
204
205 return ret;
206
207} /* end of record_lock */
208
209