xfstests updates - rework build to be like other xfs packages, revive some old fs...
[xfstests-dev.git] / lib / file_lock.c
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., 59
21  * Temple Place - Suite 330, Boston MA 02111-1307, 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
45 #ifndef EFSEXCLWR
46 #define EFSEXCLWR       503
47 #endif
48
49 /*
50  * String containing the last system call.
51  *
52  */
53 char Fl_syscall_str[128];
54
55 static 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  ***********************************************************************/
62 int
63 file_lock(fd, flags, errormsg)
64 int fd;
65 int flags;
66 char **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  ***********************************************************************/
137 int
138 record_lock(fd, flags, start, len, errormsg)
139 int fd;
140 int flags;
141 int start;
142 int len;
143 char **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