Print this page
make: remove SCCS ident stuff
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/make/lib/makestate/src/lock.c
+++ new/usr/src/cmd/make/lib/makestate/src/lock.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 -/*
26 - * @(#)lock.c 1.5 06/12/12
27 - */
28 25
29 26 #include <stdio.h>
30 27 #include <stdlib.h>
31 28 #include <unistd.h>
32 29 #include <string.h>
33 30 #include <fcntl.h>
34 31 #include <sys/types.h>
35 32 #include <sys/param.h>
36 33 #include <sys/stat.h>
37 34 #include <sys/errno.h>
38 35 #include <errno.h> /* errno */
39 36
40 37 #if defined(_LP64)
41 38 /*
42 39 * The symbols _sys_errlist and _sys_nerr are not visible in the
43 40 * LP64 libc. Use strerror(3C) instead.
44 41 */
45 42 #else /* #_LP64 */
46 43 extern char * sys_errlist[];
47 44 extern int sys_nerr;
48 45 #endif /* #_LP64 */
49 46
50 47 static void file_lock_error();
51 48
52 49 /*
53 50 * This code stolen from the NSE library and changed to not depend
54 51 * upon any NSE routines or header files.
55 52 *
56 53 * Simple file locking.
57 54 * Create a symlink to a file. The "test and set" will be
58 55 * atomic as creating the symlink provides both functions.
59 56 *
60 57 * The timeout value specifies how long to wait for stale locks
61 58 * to disappear. If the lock is more than 'timeout' seconds old
62 59 * then it is ok to blow it away. This part has a small window
63 60 * of vunerability as the operations of testing the time,
64 61 * removing the lock and creating a new one are not atomic.
65 62 * It would be possible for two processes to both decide to blow
66 63 * away the lock and then have process A remove the lock and establish
67 64 * its own, and then then have process B remove the lock which accidentily
68 65 * removes A's lock rather than the stale one.
69 66 *
70 67 * A further complication is with the NFS. If the file in question is
71 68 * being served by an NFS server, then its time is set by that server.
72 69 * We can not use the time on the client machine to check for a stale
73 70 * lock. Therefore, a temp file on the server is created to get
74 71 * the servers current time.
75 72 *
76 73 * Returns an error message. NULL return means the lock was obtained.
77 74 *
78 75 */
79 76 char *
80 77 file_lock(char * name, char * lockname, int timeout)
81 78 {
82 79 int r;
83 80 int fd;
84 81 struct stat statb;
85 82 struct stat fs_statb;
86 83 char tmpname[MAXPATHLEN];
87 84 static char msg[MAXPATHLEN];
88 85
89 86 if (timeout <= 0) {
90 87 timeout = 15;
91 88 }
92 89 for (;;) {
93 90 r = symlink(name, lockname);
94 91 if (r == 0) {
95 92 return (NULL);
96 93 }
97 94 if (errno != EEXIST) {
98 95 file_lock_error(msg, name,
99 96 (const char *)"symlink(%s, %s)", name, lockname);
100 97 return (msg);
101 98 }
102 99 for (;;) {
103 100 (void) sleep(1);
104 101 r = lstat(lockname, &statb);
105 102 if (r == -1) {
106 103 /*
107 104 * The lock must have just gone away - try
108 105 * again.
109 106 */
110 107 break;
111 108 }
112 109
113 110 /*
114 111 * With the NFS the time given a file is the time on
115 112 * the file server. This time may vary from the
116 113 * client's time. Therefore, we create a tmpfile in
117 114 * the same directory to establish the time on the
118 115 * server and use this time to see if the lock has
119 116 * expired.
120 117 */
121 118 (void) sprintf(tmpname, "%s.XXXXXX", lockname);
122 119 (void) mktemp(tmpname);
123 120 fd = creat(tmpname, 0666);
124 121 if (fd != -1) {
125 122 (void) close(fd);
126 123 } else {
127 124 file_lock_error(msg, name,
128 125 (const char *)"creat(%s)", tmpname);
129 126 return (msg);
130 127 }
131 128 if (stat(tmpname, &fs_statb) == -1) {
132 129 file_lock_error(msg, name,
133 130 (const char *)"stat(%s)", tmpname);
134 131 return (msg);
135 132 }
136 133 (void) unlink(tmpname);
137 134 if (statb.st_mtime + timeout < fs_statb.st_mtime) {
138 135 /*
139 136 * The lock has expired - blow it away.
140 137 */
141 138 (void) unlink(lockname);
142 139 break;
143 140 }
144 141 }
145 142 }
146 143 /* NOTREACHED */
147 144 }
148 145
149 146 /*
150 147 * Format a message telling why the lock could not be created.
151 148 */
152 149 /* VARARGS4 */
153 150 static void
154 151 file_lock_error(char * msg, char * file, const char * str, char * arg1,
155 152 char * arg2)
156 153 {
157 154 int len;
158 155
159 156 (void) sprintf(msg, "Could not lock file `%s'; ", file);
160 157 len = strlen(msg);
161 158 (void) sprintf(&msg[len], str, arg1, arg2);
162 159 (void) strcat(msg, " failed - ");
163 160 #if defined(_LP64)
164 161 /* Needs to be changed to use strerror(3C) instead. */
165 162 len = strlen(msg);
166 163 (void) sprintf(&msg[len], "errno %d", errno);
167 164 #else /* #_LP64 */
168 165 if (errno < sys_nerr) {
169 166 (void) strcat(msg, sys_errlist[errno]);
170 167 } else {
171 168 len = strlen(msg);
172 169 (void) sprintf(&msg[len], "errno %d", errno);
173 170 }
174 171 #endif /* #_LP64 */
175 172 }
↓ open down ↓ |
138 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX