blob: 52c89471281cf68756772dda35a56d2056d0c0d6 [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
Wanlong Gaofed96412012-10-24 10:10:29 +080020 * with this program; if not, write the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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>
Wanlong Gao354ebb42012-12-07 10:10:04 +080041#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#ifndef EFSEXCLWR
45#define EFSEXCLWR 503
46#endif
47
48/*
49 * String containing the last system call.
50 *
51 */
52char Fl_syscall_str[128];
53
54static 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 ***********************************************************************/
Wanlong Gao354ebb42012-12-07 10:10:04 +080061int file_lock(fd, flags, errormsg)
whrb973f2b2000-05-05 19:34:50 +000062int fd;
63int flags;
64char **errormsg;
65{
Wanlong Gao354ebb42012-12-07 10:10:04 +080066 register int cmd, ret;
67 struct flock flocks;
whrb973f2b2000-05-05 19:34:50 +000068
Wanlong Gao354ebb42012-12-07 10:10:04 +080069 memset(&flocks, 0, sizeof(struct flock));
whrb973f2b2000-05-05 19:34:50 +000070
Wanlong Gao354ebb42012-12-07 10:10:04 +080071 if (flags & LOCK_NB)
72 cmd = F_SETLK;
73 else
74 cmd = F_SETLKW;
whrb973f2b2000-05-05 19:34:50 +000075
Wanlong Gao354ebb42012-12-07 10:10:04 +080076 flocks.l_whence = 0;
77 flocks.l_start = 0;
78 flocks.l_len = 0;
whrb973f2b2000-05-05 19:34:50 +000079
Wanlong Gao354ebb42012-12-07 10:10:04 +080080 if (flags & LOCK_UN)
81 flocks.l_type = F_UNLCK;
82 else if (flags & LOCK_EX)
83 flocks.l_type = F_WRLCK;
84 else if (flags & LOCK_SH)
85 flocks.l_type = F_RDLCK;
86 else {
87 errno = EINVAL;
88 if (errormsg != NULL) {
89 sprintf(errmsg,
90 "Programmer error, called file_lock with in valid flags\n");
91 *errormsg = errmsg;
92 }
93 return -1;
94 }
whrb973f2b2000-05-05 19:34:50 +000095
96 sprintf(Fl_syscall_str,
Wanlong Gao354ebb42012-12-07 10:10:04 +080097 "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n",
98 fd, cmd, flocks.l_type, flocks.l_whence,
whrb973f2b2000-05-05 19:34:50 +000099 (long long)flocks.l_start, (long long)flocks.l_len);
100
101 while (1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800102 ret = fcntl(fd, cmd, &flocks);
whrb973f2b2000-05-05 19:34:50 +0000103
Wanlong Gao354ebb42012-12-07 10:10:04 +0800104 if (ret < 0) {
105 if (cmd == F_SETLK)
106 switch (errno) {
107 /* these errors are okay */
108 case EACCES: /* Permission denied */
109 case EINTR: /* interrupted system call */
whrb973f2b2000-05-05 19:34:50 +0000110#ifdef EFILESH
Wanlong Gao354ebb42012-12-07 10:10:04 +0800111 case EFILESH: /* file shared */
whrb973f2b2000-05-05 19:34:50 +0000112#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800113 case EFSEXCLWR: /* File is write protected */
114 continue; /* retry getting lock */
115 }
116 if (errormsg != NULL) {
117 sprintf(errmsg,
118 "fcntl(%d, %d, &flocks): errno:%d %s\n",
119 fd, cmd, errno, strerror(errno));
120 *errormsg = errmsg;
121 }
122 return -1;
123 }
124 break;
whrb973f2b2000-05-05 19:34:50 +0000125 }
126
Wanlong Gao354ebb42012-12-07 10:10:04 +0800127 return ret;
whrb973f2b2000-05-05 19:34:50 +0000128
Wanlong Gao354ebb42012-12-07 10:10:04 +0800129} /* end of file_lock */
whrb973f2b2000-05-05 19:34:50 +0000130
131/***********************************************************************
132 *
133 * Test interface to the fcntl system call.
134 * It will loop if the LOCK_NB flags is NOT set.
135 ***********************************************************************/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800136int record_lock(fd, flags, start, len, errormsg)
whrb973f2b2000-05-05 19:34:50 +0000137int fd;
138int flags;
139int start;
140int len;
141char **errormsg;
142{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800143 register int cmd, ret;
144 struct flock flocks;
whrb973f2b2000-05-05 19:34:50 +0000145
Wanlong Gao354ebb42012-12-07 10:10:04 +0800146 memset(&flocks, 0, sizeof(struct flock));
whrb973f2b2000-05-05 19:34:50 +0000147
Wanlong Gao354ebb42012-12-07 10:10:04 +0800148 if (flags & LOCK_NB)
149 cmd = F_SETLK;
150 else
151 cmd = F_SETLKW;
whrb973f2b2000-05-05 19:34:50 +0000152
Wanlong Gao354ebb42012-12-07 10:10:04 +0800153 flocks.l_whence = 0;
154 flocks.l_start = start;
155 flocks.l_len = len;
whrb973f2b2000-05-05 19:34:50 +0000156
Wanlong Gao354ebb42012-12-07 10:10:04 +0800157 if (flags & LOCK_UN)
158 flocks.l_type = F_UNLCK;
159 else if (flags & LOCK_EX)
160 flocks.l_type = F_WRLCK;
161 else if (flags & LOCK_SH)
162 flocks.l_type = F_RDLCK;
163 else {
164 errno = EINVAL;
165 if (errormsg != NULL) {
166 sprintf(errmsg,
167 "Programmer error, called record_lock with in valid flags\n");
168 *errormsg = errmsg;
169 }
170 return -1;
171 }
whrb973f2b2000-05-05 19:34:50 +0000172
173 sprintf(Fl_syscall_str,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800174 "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n",
175 fd, cmd, flocks.l_type, flocks.l_whence,
whrb973f2b2000-05-05 19:34:50 +0000176 (long long)flocks.l_start, (long long)flocks.l_len);
177
178 while (1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800179 ret = fcntl(fd, cmd, &flocks);
whrb973f2b2000-05-05 19:34:50 +0000180
Wanlong Gao354ebb42012-12-07 10:10:04 +0800181 if (ret < 0) {
182 if (cmd == F_SETLK)
183 switch (errno) {
184 /* these errors are okay */
185 case EACCES: /* Permission denied */
186 case EINTR: /* interrupted system call */
whrb973f2b2000-05-05 19:34:50 +0000187#ifdef EFILESH
Wanlong Gao354ebb42012-12-07 10:10:04 +0800188 case EFILESH: /* file shared */
whrb973f2b2000-05-05 19:34:50 +0000189#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800190 case EFSEXCLWR: /* File is write protected */
191 continue; /* retry getting lock */
192 }
193 if (errormsg != NULL) {
194 sprintf(errmsg,
195 "fcntl(%d, %d, &flocks): errno:%d %s\n",
196 fd, cmd, errno, strerror(errno));
197 *errormsg = errmsg;
198 }
199 return -1;
200 }
201 break;
whrb973f2b2000-05-05 19:34:50 +0000202 }
203
Wanlong Gao354ebb42012-12-07 10:10:04 +0800204 return ret;
whrb973f2b2000-05-05 19:34:50 +0000205
Wanlong Gao354ebb42012-12-07 10:10:04 +0800206} /* end of record_lock */