Import NetBSD flock(1)
Also fix the MINIX3 libc flock(3) implementation. Change-Id: Ia80280029968786d7f029940ec02e942057701bd
This commit is contained in:
parent
875abb8724
commit
9488aa4c04
6 changed files with 442 additions and 7 deletions
|
@ -331,6 +331,7 @@
|
||||||
./usr/bin/fix minix-sys
|
./usr/bin/fix minix-sys
|
||||||
./usr/bin/flex++ minix-sys
|
./usr/bin/flex++ minix-sys
|
||||||
./usr/bin/flex minix-sys
|
./usr/bin/flex minix-sys
|
||||||
|
./usr/bin/flock minix-sys
|
||||||
./usr/bin/fold minix-sys
|
./usr/bin/fold minix-sys
|
||||||
./usr/bin/format minix-sys
|
./usr/bin/format minix-sys
|
||||||
./usr/bin/fpr minix-sys
|
./usr/bin/fpr minix-sys
|
||||||
|
@ -2405,6 +2406,7 @@
|
||||||
./usr/man/man1/finger.1 minix-sys
|
./usr/man/man1/finger.1 minix-sys
|
||||||
./usr/man/man1/flex.1 minix-sys
|
./usr/man/man1/flex.1 minix-sys
|
||||||
./usr/man/man1/flexdoc.1 minix-sys
|
./usr/man/man1/flexdoc.1 minix-sys
|
||||||
|
./usr/man/man1/flock.1 minix-sys
|
||||||
./usr/man/man1/fold.1 minix-sys
|
./usr/man/man1/fold.1 minix-sys
|
||||||
./usr/man/man1/for.1 minix-sys obsolete
|
./usr/man/man1/for.1 minix-sys obsolete
|
||||||
./usr/man/man1/format.1 minix-sys
|
./usr/man/man1/format.1 minix-sys
|
||||||
|
|
|
@ -21,14 +21,15 @@
|
||||||
int flock(int fd, int mode)
|
int flock(int fd, int mode)
|
||||||
{
|
{
|
||||||
struct flock lck;
|
struct flock lck;
|
||||||
register int retcode;
|
|
||||||
|
|
||||||
memset((void *) &lck, 0, sizeof(struct flock));
|
memset((void *) &lck, 0, sizeof(struct flock));
|
||||||
lck.l_type = mode & ~LOCK_NB;
|
switch (mode & ~LOCK_NB) {
|
||||||
lck.l_pid = getpid();
|
case LOCK_SH: lck.l_type = F_RDLCK; break;
|
||||||
if ((retcode = fcntl(fd, mode & LOCK_NB ? F_SETLK : F_SETLKW, &lck)) < 0 && errno == EAGAIN)
|
case LOCK_EX: lck.l_type = F_WRLCK; break;
|
||||||
errno = EWOULDBLOCK;
|
case LOCK_UN: lck.l_type = F_UNLCK; break;
|
||||||
return retcode;
|
default: errno = EINVAL; return -1;
|
||||||
|
}
|
||||||
|
return fcntl(fd, mode & LOCK_NB ? F_SETLK : F_SETLKW, &lck);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** flock.c **/
|
/** flock.c **/
|
||||||
|
|
|
@ -10,7 +10,7 @@ SUBDIR= asa \
|
||||||
column comm csplit ctags cut \
|
column comm csplit ctags cut \
|
||||||
deroff dirname du \
|
deroff dirname du \
|
||||||
env expand \
|
env expand \
|
||||||
false find finger fold fpr from \
|
false find finger flock fold fpr from \
|
||||||
fsplit ftp genassym getopt \
|
fsplit ftp genassym getopt \
|
||||||
head hexdump id indent infocmp join jot \
|
head hexdump id indent infocmp join jot \
|
||||||
lam last ldd leave \
|
lam last ldd leave \
|
||||||
|
|
8
usr.bin/flock/Makefile
Normal file
8
usr.bin/flock/Makefile
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# $NetBSD: Makefile,v 1.1 2012/11/01 23:30:19 christos Exp $
|
||||||
|
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||||
|
|
||||||
|
PROG= flock
|
||||||
|
#LDADD+= -lutil
|
||||||
|
#DPADD+= ${LIBUTIL}
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
100
usr.bin/flock/flock.1
Normal file
100
usr.bin/flock/flock.1
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
.\" $NetBSD: flock.1,v 1.9 2013/09/21 15:01:14 khorben Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
.\" by Christos Zoulas.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\"
|
||||||
|
.Dd November 2, 2012
|
||||||
|
.Dt FLOCK 1
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm flock
|
||||||
|
.Nd Provide locking API for shell scripts
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op Fl dnosvx
|
||||||
|
.Op Fl w Ar timeout
|
||||||
|
.Ar lockfile|lockdir
|
||||||
|
.Op Fl c Ar command
|
||||||
|
|
|
||||||
|
.Op Ar command ...
|
||||||
|
.Nm
|
||||||
|
.Op Fl dnsuvx
|
||||||
|
.Op Fl w Ar timeout
|
||||||
|
.Ar lockfd
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility provides
|
||||||
|
.Xr flock 2
|
||||||
|
access to the command line or scripts.
|
||||||
|
The first form locks a file or directory while the command provided is executed.
|
||||||
|
If the file or directory does not exist, then a file is created.
|
||||||
|
.Pp
|
||||||
|
The second form can use an arbitrary file descriptor that is provided from a
|
||||||
|
shell script for example:
|
||||||
|
.Bd -literal
|
||||||
|
(
|
||||||
|
flock -s 100
|
||||||
|
# commands to be executed under the lock
|
||||||
|
) 100> /path/to/lockfile
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The following options are available:
|
||||||
|
.Bl -tag -width "XXXXXXXXXXXXXXXXX"
|
||||||
|
.It Fl c Ar command
|
||||||
|
Pass a command to a the shell.
|
||||||
|
.It Fl d , Fl Fl debug
|
||||||
|
Provide debugging output.
|
||||||
|
.It Fl n , Fl Fl nb , Fl Fl nonblock
|
||||||
|
Don't block and fail immediately if the lock could not be obtained.
|
||||||
|
.It Fl o , Fl Fl close
|
||||||
|
Close the file before executing the command.
|
||||||
|
This is useful if the child forks and should not be holding the lock.
|
||||||
|
.It Fl s , Fl Fl shared
|
||||||
|
Obtain a shared lock.
|
||||||
|
.It Fl u , Fl Fl unlock
|
||||||
|
Unlock an existing lock.
|
||||||
|
This is available only for a file descriptor.
|
||||||
|
.It Fl v , Fl Fl verbose
|
||||||
|
On error print an explanation of the failure.
|
||||||
|
.It Fl w , Fl Fl wait , Fl Fl timeout Ar seconds
|
||||||
|
Fail if the lock could not be obtained after
|
||||||
|
.Ar seconds .
|
||||||
|
.It Fl x , Fl Fl exclusive
|
||||||
|
Obtain an exclusive lock.
|
||||||
|
.El
|
||||||
|
.Sh EXIT STATUS
|
||||||
|
.Ex -std
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr shlock 1 ,
|
||||||
|
.Xr flock 2
|
||||||
|
.Sh HISTORY
|
||||||
|
An
|
||||||
|
.Nm
|
||||||
|
utility appeared in
|
||||||
|
.Nx 6.1 .
|
324
usr.bin/flock/flock.c
Normal file
324
usr.bin/flock/flock.c
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
/* $NetBSD: flock.c,v 1.8 2013/10/29 16:02:15 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Christos Zoulas.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
__RCSID("$NetBSD: flock.c,v 1.8 2013/10/29 16:02:15 christos Exp $");
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <paths.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
static struct option flock_longopts[] = {
|
||||||
|
{ "debug", no_argument, 0, 'd' },
|
||||||
|
{ "help", no_argument, 0, 'h' },
|
||||||
|
{ "nonblock", no_argument, 0, 'n' },
|
||||||
|
{ "nb", no_argument, 0, 'n' },
|
||||||
|
{ "close", no_argument, 0, 'o' },
|
||||||
|
{ "shared", no_argument, 0, 's' },
|
||||||
|
{ "exclusive", no_argument, 0, 'x' },
|
||||||
|
{ "unlock", no_argument, 0, 'u' },
|
||||||
|
{ "verbose", no_argument, 0, 'v' },
|
||||||
|
{ "command", required_argument, 0, 'c' },
|
||||||
|
{ "wait", required_argument, 0, 'w' },
|
||||||
|
{ "timeout", required_argument, 0, 'w' },
|
||||||
|
{ NULL, 0, 0, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static sig_atomic_t timeout_expired;
|
||||||
|
|
||||||
|
static __dead void
|
||||||
|
usage(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
if (fmt) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
fprintf(stderr, "%s: ", getprogname());
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
fputc('\n', stderr);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Usage: %s [-dnosvx] [-w timeout] lockfile|lockdir "
|
||||||
|
"[-c command]|command ...\n\t%s [-dnsuvx] [-w timeout] lockfd\n",
|
||||||
|
getprogname(), getprogname());
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sigalrm(int sig)
|
||||||
|
{
|
||||||
|
timeout_expired++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
lock2name(int l)
|
||||||
|
{
|
||||||
|
static char buf[1024];
|
||||||
|
int nb = l & LOCK_NB;
|
||||||
|
|
||||||
|
l &= ~LOCK_NB;
|
||||||
|
if (nb)
|
||||||
|
strlcpy(buf, "LOCK_NB|", sizeof(buf));
|
||||||
|
else
|
||||||
|
buf[0] = '\0';
|
||||||
|
|
||||||
|
switch (l) {
|
||||||
|
case LOCK_SH:
|
||||||
|
strlcat(buf, "LOCK_SH", sizeof(buf));
|
||||||
|
return buf;
|
||||||
|
case LOCK_EX:
|
||||||
|
strlcat(buf, "LOCK_EX", sizeof(buf));
|
||||||
|
return buf;
|
||||||
|
case LOCK_UN:
|
||||||
|
strlcat(buf, "LOCK_UN", sizeof(buf));
|
||||||
|
return buf;
|
||||||
|
default:
|
||||||
|
snprintf(buf, sizeof(buf), "*%d*", l | nb);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char
|
||||||
|
lockchar(int l)
|
||||||
|
{
|
||||||
|
switch (l & ~LOCK_NB) {
|
||||||
|
case LOCK_SH:
|
||||||
|
return 's';
|
||||||
|
case LOCK_EX:
|
||||||
|
return 'x';
|
||||||
|
case LOCK_UN:
|
||||||
|
return 'u';
|
||||||
|
default:
|
||||||
|
return '*';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
cmdline(char **av)
|
||||||
|
{
|
||||||
|
char *v = NULL;
|
||||||
|
while (*av)
|
||||||
|
if (v) {
|
||||||
|
if (asprintf(&v, "%s %s", v, *av++) < 0)
|
||||||
|
err(EXIT_FAILURE, "malloc");
|
||||||
|
} else {
|
||||||
|
if ((v = strdup(*av++)) == NULL)
|
||||||
|
err(EXIT_FAILURE, "strdup");
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
int lock = 0;
|
||||||
|
double timeout = 0;
|
||||||
|
int cls = 0;
|
||||||
|
int fd = -1;
|
||||||
|
int debug = 0;
|
||||||
|
int verbose = 0;
|
||||||
|
char *mcargv[] = {
|
||||||
|
__UNCONST(_PATH_BSHELL), __UNCONST("-c"), NULL, NULL
|
||||||
|
};
|
||||||
|
char **cmdargv = NULL, *v;
|
||||||
|
#ifndef __minix
|
||||||
|
timer_t tm;
|
||||||
|
#else /* __minix */
|
||||||
|
struct itimerval it;
|
||||||
|
#endif /* __minix */
|
||||||
|
|
||||||
|
setprogname(argv[0]);
|
||||||
|
|
||||||
|
while ((c = getopt_long(argc, argv, "+dnosuvw:x", flock_longopts, NULL))
|
||||||
|
!= -1)
|
||||||
|
switch (c) {
|
||||||
|
case 'd':
|
||||||
|
debug++;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
#define T(l) (lock & ~LOCK_NB) != (l) && (lock & ~LOCK_NB) != 0
|
||||||
|
if (T(LOCK_EX))
|
||||||
|
goto badlock;
|
||||||
|
lock |= LOCK_EX;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
lock |= LOCK_NB;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
if (T(LOCK_SH))
|
||||||
|
goto badlock;
|
||||||
|
lock |= LOCK_SH;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
if (T(LOCK_UN))
|
||||||
|
goto badlock;
|
||||||
|
lock |= LOCK_UN;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
timeout = strtod(optarg, NULL);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
verbose = 1;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
cls = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage("Invalid option '%c'", c);
|
||||||
|
badlock:
|
||||||
|
usage("-%c can't be used with -%c", c, lockchar(lock));
|
||||||
|
}
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if ((lock & ~LOCK_NB) == 0)
|
||||||
|
usage("Missing lock type flag");
|
||||||
|
|
||||||
|
switch (argc) {
|
||||||
|
case 0:
|
||||||
|
usage("Missing lock file argument");
|
||||||
|
case 1:
|
||||||
|
if (cls)
|
||||||
|
usage("Close is valid only for descriptors");
|
||||||
|
fd = strtol(argv[0], NULL, 0); // XXX: error checking
|
||||||
|
if (debug) {
|
||||||
|
fprintf(stderr, "descriptor %s lock %s\n",
|
||||||
|
argv[0], lock2name(lock));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if ((lock & LOCK_NB) == LOCK_UN)
|
||||||
|
usage("Unlock is only valid for descriptors");
|
||||||
|
if (strcmp(argv[1], "-c") == 0 ||
|
||||||
|
strcmp(argv[1], "--command") == 0) {
|
||||||
|
if (argc == 2)
|
||||||
|
usage("Missing argument to %s", strcmp(argv[1],
|
||||||
|
"-c") == 0 ? "-c" : "--command");
|
||||||
|
mcargv[2] = argv[2];
|
||||||
|
cmdargv = mcargv;
|
||||||
|
} else
|
||||||
|
cmdargv = argv + 1;
|
||||||
|
|
||||||
|
if ((fd = open(argv[0], O_RDONLY)) == -1) {
|
||||||
|
if (errno != ENOENT ||
|
||||||
|
(fd = open(argv[0], O_RDWR|O_CREAT, 0600)) == -1)
|
||||||
|
err(EXIT_FAILURE, "Cannot open `%s'", argv[0]);
|
||||||
|
}
|
||||||
|
if (debug) {
|
||||||
|
fprintf(stderr, "file %s lock %s command %s ...\n",
|
||||||
|
argv[0], lock2name(lock), v = cmdline(cmdargv));
|
||||||
|
free(v);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeout) {
|
||||||
|
#ifndef __minix
|
||||||
|
struct sigevent ev;
|
||||||
|
struct itimerspec it;
|
||||||
|
#endif /* !__minix */
|
||||||
|
struct sigaction sa;
|
||||||
|
|
||||||
|
#ifndef __minix
|
||||||
|
timespecclear(&it.it_interval);
|
||||||
|
it.it_value.tv_sec = timeout;
|
||||||
|
it.it_value.tv_nsec = (timeout - it.it_value.tv_sec) *
|
||||||
|
1000000000;
|
||||||
|
|
||||||
|
memset(&ev, 0, sizeof(ev));
|
||||||
|
ev.sigev_notify = SIGEV_SIGNAL;
|
||||||
|
ev.sigev_signo = SIGALRM;
|
||||||
|
|
||||||
|
if (timer_create(CLOCK_REALTIME, &ev, &tm) == -1)
|
||||||
|
err(EXIT_FAILURE, "timer_create");
|
||||||
|
|
||||||
|
if (timer_settime(tm, TIMER_RELTIME, &it, NULL) == -1)
|
||||||
|
err(EXIT_FAILURE, "timer_settime");
|
||||||
|
#else /* __minix */
|
||||||
|
memset(&it.it_interval, 0, sizeof(it.it_interval));
|
||||||
|
it.it_value.tv_sec = timeout;
|
||||||
|
it.it_value.tv_usec = (timeout - it.it_value.tv_sec) * 1000000;
|
||||||
|
|
||||||
|
if (setitimer(ITIMER_REAL, &it, NULL) == -1)
|
||||||
|
err(EXIT_FAILURE, "setitimer");
|
||||||
|
|
||||||
|
memset(&it, 0, sizeof(it)); /* for the reset later */
|
||||||
|
#endif /* __minix */
|
||||||
|
|
||||||
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
sa.sa_handler = sigalrm;
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sa.sa_flags = 0;
|
||||||
|
if (sigaction(SIGALRM, &sa, NULL) == -1)
|
||||||
|
err(EXIT_FAILURE, "sigaction");
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
fprintf(stderr, "alarm %g\n", timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (flock(fd, lock) == -1) {
|
||||||
|
if (errno == EINTR && timeout_expired == 0)
|
||||||
|
continue;
|
||||||
|
if (verbose)
|
||||||
|
err(EXIT_FAILURE, "flock(%d, %s)", fd, lock2name(lock));
|
||||||
|
else
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeout)
|
||||||
|
#ifndef __minix
|
||||||
|
timer_delete(tm);
|
||||||
|
#else /* __minix */
|
||||||
|
setitimer(ITIMER_REAL, &it, NULL);
|
||||||
|
#endif /* __minix */
|
||||||
|
|
||||||
|
if (cls)
|
||||||
|
(void)close(fd);
|
||||||
|
|
||||||
|
if (cmdargv != NULL) {
|
||||||
|
execvp(cmdargv[0], cmdargv);
|
||||||
|
err(EXIT_FAILURE, "execvp '%s'", v = cmdline(cmdargv));
|
||||||
|
free(v);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue