Lines 50-55
Link Here
|
50 |
static const char *lockname; |
50 |
static const char *lockname; |
51 |
static int lockfd = -1; |
51 |
static int lockfd = -1; |
52 |
static int keep; |
52 |
static int keep; |
|
|
53 |
static int fdlock; |
53 |
static volatile sig_atomic_t timed_out; |
54 |
static volatile sig_atomic_t timed_out; |
54 |
|
55 |
|
55 |
/* |
56 |
/* |
Lines 88-96
Link Here
|
88 |
usage(); |
89 |
usage(); |
89 |
} |
90 |
} |
90 |
} |
91 |
} |
91 |
if (argc - optind < 2) |
92 |
|
92 |
usage(); |
|
|
93 |
lockname = argv[optind++]; |
93 |
lockname = argv[optind++]; |
|
|
94 |
|
95 |
if (atoi(lockname) > 2) |
96 |
fdlock = 1; |
97 |
else |
98 |
fdlock = 0; |
99 |
|
100 |
if (argc - optind < 1 - fdlock) |
101 |
usage(); |
102 |
|
94 |
argc -= optind; |
103 |
argc -= optind; |
95 |
argv += optind; |
104 |
argv += optind; |
96 |
if (waitsec > 0) { /* Set up a timeout. */ |
105 |
if (waitsec > 0) { /* Set up a timeout. */ |
Lines 126-132
Link Here
|
126 |
*/ |
135 |
*/ |
127 |
lockfd = acquire_lock(lockname, flags | O_NONBLOCK); |
136 |
lockfd = acquire_lock(lockname, flags | O_NONBLOCK); |
128 |
while (lockfd == -1 && !timed_out && waitsec != 0) { |
137 |
while (lockfd == -1 && !timed_out && waitsec != 0) { |
129 |
if (keep) |
138 |
if (keep || fdlock) |
130 |
lockfd = acquire_lock(lockname, flags); |
139 |
lockfd = acquire_lock(lockname, flags); |
131 |
else { |
140 |
else { |
132 |
wait_for_lock(lockname); |
141 |
wait_for_lock(lockname); |
Lines 140-146
Link Here
|
140 |
exit(EX_TEMPFAIL); |
149 |
exit(EX_TEMPFAIL); |
141 |
errx(EX_TEMPFAIL, "%s: already locked", lockname); |
150 |
errx(EX_TEMPFAIL, "%s: already locked", lockname); |
142 |
} |
151 |
} |
|
|
152 |
|
143 |
/* At this point, we own the lock. */ |
153 |
/* At this point, we own the lock. */ |
|
|
154 |
|
155 |
/* Nothing else to do for FD lock, just exit */ |
156 |
if (fdlock) |
157 |
return 0; |
158 |
|
144 |
if (atexit(cleanup) == -1) |
159 |
if (atexit(cleanup) == -1) |
145 |
err(EX_OSERR, "atexit failed"); |
160 |
err(EX_OSERR, "atexit failed"); |
146 |
if ((child = fork()) == -1) |
161 |
if ((child = fork()) == -1) |
Lines 161-167
Link Here
|
161 |
} |
176 |
} |
162 |
|
177 |
|
163 |
/* |
178 |
/* |
164 |
* Try to acquire a lock on the given file, creating the file if |
179 |
* Try to acquire a lock on the given file/fd, creating the file if |
165 |
* necessary. The flags argument is O_NONBLOCK or 0, depending on |
180 |
* necessary. The flags argument is O_NONBLOCK or 0, depending on |
166 |
* whether we should wait for the lock. Returns an open file descriptor |
181 |
* whether we should wait for the lock. Returns an open file descriptor |
167 |
* on success, or -1 on failure. |
182 |
* on success, or -1 on failure. |
Lines 171-182
Link Here
|
171 |
{ |
186 |
{ |
172 |
int fd; |
187 |
int fd; |
173 |
|
188 |
|
174 |
if ((fd = open(name, O_RDONLY|O_EXLOCK|flags, 0666)) == -1) { |
189 |
if ((fd = atoi(name)) > 0) { |
175 |
if (errno == EAGAIN || errno == EINTR) |
190 |
if (flock(fd, LOCK_EX | LOCK_NB) == -1) { |
176 |
return (-1); |
191 |
if (errno == EAGAIN || errno == EINTR) |
177 |
else if (errno == ENOENT && (flags & O_CREAT) == 0) |
192 |
return (-1); |
178 |
err(EX_UNAVAILABLE, "%s", name); |
193 |
err(EX_CANTCREAT, "cannot lock FD %d", fd); |
179 |
err(EX_CANTCREAT, "cannot open %s", name); |
194 |
} |
|
|
195 |
} else { |
196 |
if ((fd = open(name, O_RDONLY|O_EXLOCK|flags, 0666)) == -1) { |
197 |
if (errno == EAGAIN || errno == EINTR) |
198 |
return (-1); |
199 |
else if (errno == ENOENT && (flags & O_CREAT) == 0) |
200 |
err(EX_UNAVAILABLE, "%s", name); |
201 |
err(EX_CANTCREAT, "cannot open %s", name); |
202 |
} |
180 |
} |
203 |
} |
181 |
return (fd); |
204 |
return (fd); |
182 |
} |
205 |
} |
Lines 188-194
Link Here
|
188 |
cleanup(void) |
211 |
cleanup(void) |
189 |
{ |
212 |
{ |
190 |
|
213 |
|
191 |
if (keep) |
214 |
if (keep || lockfd) |
192 |
flock(lockfd, LOCK_UN); |
215 |
flock(lockfd, LOCK_UN); |
193 |
else |
216 |
else |
194 |
unlink(lockname); |
217 |
unlink(lockname); |