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;
 }

Reply via email to