Module Name: src Committed By: christos Date: Fri Nov 2 12:47:23 UTC 2012
Modified Files: src/usr.bin/flock: flock.c Log Message: - use modern timer functions to handler fractional wait - add a function to print the full command line - use sigaction so signals interrupt us To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/usr.bin/flock/flock.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/flock/flock.c diff -u src/usr.bin/flock/flock.c:1.4 src/usr.bin/flock/flock.c:1.5 --- src/usr.bin/flock/flock.c:1.4 Thu Nov 1 22:07:19 2012 +++ src/usr.bin/flock/flock.c Fri Nov 2 08:47:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: flock.c,v 1.4 2012/11/02 02:07:19 wiz Exp $ */ +/* $NetBSD: flock.c,v 1.5 2012/11/02 12:47:23 christos Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: flock.c,v 1.4 2012/11/02 02:07:19 wiz Exp $"); +__RCSID("$NetBSD: flock.c,v 1.5 2012/11/02 12:47:23 christos Exp $"); #include <stdio.h> #include <string.h> @@ -43,6 +43,7 @@ __RCSID("$NetBSD: flock.c,v 1.4 2012/11/ #include <errno.h> #include <getopt.h> #include <paths.h> +#include <time.h> struct option flock_longopts[] = { { "debug", no_argument, 0, 'd' }, @@ -65,9 +66,9 @@ static sig_atomic_t timeout_expired; static __dead void usage(void) { - fprintf(stderr, "Usage: %s [-dnosvx] [-w timeout] lockfile|lockdir [-c command]| " - "command ...\n\t%s [-dnsuvx] [-w timeout] lockfd\n", getprogname(), - getprogname()); + 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); } @@ -105,6 +106,21 @@ lock2name(int l) } } +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[]) { @@ -117,11 +133,12 @@ main(int argc, char *argv[]) char *mcargv[] = { __UNCONST(_PATH_BSHELL), __UNCONST("-c"), NULL, NULL }; - char **cmdargv = NULL; + char **cmdargv = NULL, *v; + timer_t tm; setprogname(argv[0]); - while ((c = getopt_long(argc, argv, "+dnosuw:x", flock_longopts, NULL)) + while ((c = getopt_long(argc, argv, "+dnosuvw:x", flock_longopts, NULL)) != -1) switch (c) { case 'd': @@ -182,17 +199,43 @@ main(int argc, char *argv[]) (fd = open(argv[0], O_RDWR|O_CREAT, 0600)) == -1) err(EXIT_FAILURE, "Cannot open `%s'", argv[0]); } - if (debug) + if (debug) { fprintf(stderr, "file %s lock %s command %s ...\n", - argv[0], lock2name(lock), cmdargv[0]); + argv[0], lock2name(lock), v = cmdline(cmdargv)); + free(v); + } break; } if (timeout) { - signal(SIGALRM, sigalrm); - alarm((int)timeout); // XXX: User timer_create() + struct sigevent ev; + struct itimerspec it; + struct sigaction sa; + + 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"); + + 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 %d\n", (int)timeout); + fprintf(stderr, "alarm %g\n", timeout); } while (flock(fd, lock) == -1) { @@ -205,14 +248,15 @@ main(int argc, char *argv[]) } if (timeout) - alarm(0); + timer_delete(tm); if (cls) (void)close(fd); if (cmdargv != NULL) { execvp(cmdargv[0], cmdargv); - err(EXIT_FAILURE, "execvp '%s'", cmdargv[0]); + err(EXIT_FAILURE, "execvp '%s'", v = cmdline(cmdargv)); + free(v); } return 0; }