Module Name: src Committed By: riz Date: Wed Nov 28 21:35:01 UTC 2012
Modified Files: src/distrib/sets/lists/base [netbsd-6]: mi src/distrib/sets/lists/comp [netbsd-6]: mi src/distrib/sets/lists/man [netbsd-6]: mi src/usr.bin [netbsd-6]: Makefile Added Files: src/usr.bin/flock [netbsd-6]: Makefile flock.1 flock.c Log Message: Pull up following revision(s) (requested by christos in ticket #719): distrib/sets/lists/base/mi: revision 1.1011 usr.bin/flock/Makefile: revision 1.1 usr.bin/flock/flock.1: revision 1.1 distrib/sets/lists/man/mi: revision 1.1404 usr.bin/flock/flock.c: revision 1.1 distrib/sets/lists/comp/mi: revision 1.1786 usr.bin/Makefile: revision 1.211 add flock(1) Add an flock program inspired by the linux one with the same name. To generate a diff of this commit: cvs rdiff -u -r1.984.2.11 -r1.984.2.12 src/distrib/sets/lists/base/mi cvs rdiff -u -r1.1738.2.12 -r1.1738.2.13 src/distrib/sets/lists/comp/mi cvs rdiff -u -r1.1379.2.7 -r1.1379.2.8 src/distrib/sets/lists/man/mi cvs rdiff -u -r1.207 -r1.207.2.1 src/usr.bin/Makefile cvs rdiff -u -r0 -r1.1.4.2 src/usr.bin/flock/Makefile cvs rdiff -u -r0 -r1.8.4.2 src/usr.bin/flock/flock.1 cvs rdiff -u -r0 -r1.6.4.2 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/distrib/sets/lists/base/mi diff -u src/distrib/sets/lists/base/mi:1.984.2.11 src/distrib/sets/lists/base/mi:1.984.2.12 --- src/distrib/sets/lists/base/mi:1.984.2.11 Sun Nov 18 22:38:30 2012 +++ src/distrib/sets/lists/base/mi Wed Nov 28 21:34:30 2012 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.984.2.11 2012/11/18 22:38:30 riz Exp $ +# $NetBSD: mi,v 1.984.2.12 2012/11/28 21:34:30 riz Exp $ # # Note: Don't delete entries from here - mark them as "obsolete" instead, # unless otherwise stated below. @@ -455,6 +455,7 @@ ./usr/bin/fincore base-util-bin ./usr/bin/find base-util-bin ./usr/bin/finger base-util-bin +./usr/bin/flock base-util-bin ./usr/bin/fmt base-util-bin ./usr/bin/fold base-util-bin ./usr/bin/from base-mail-bin Index: src/distrib/sets/lists/comp/mi diff -u src/distrib/sets/lists/comp/mi:1.1738.2.12 src/distrib/sets/lists/comp/mi:1.1738.2.13 --- src/distrib/sets/lists/comp/mi:1.1738.2.12 Tue Nov 20 22:33:37 2012 +++ src/distrib/sets/lists/comp/mi Wed Nov 28 21:34:43 2012 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.1738.2.12 2012/11/20 22:33:37 riz Exp $ +# $NetBSD: mi,v 1.1738.2.13 2012/11/28 21:34:43 riz Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -3599,6 +3599,7 @@ ./usr/libdata/debug/usr/bin/fincore.debug comp-util-debug debug ./usr/libdata/debug/usr/bin/find.debug comp-util-debug debug ./usr/libdata/debug/usr/bin/finger.debug comp-util-debug debug +./usr/libdata/debug/usr/bin/flock.debug comp-util-debug debug ./usr/libdata/debug/usr/bin/fmt.debug comp-util-debug debug ./usr/libdata/debug/usr/bin/fold.debug comp-util-debug debug ./usr/libdata/debug/usr/bin/fort77.debug comp-fortran-debug gcc=3,gcccmds,debug Index: src/distrib/sets/lists/man/mi diff -u src/distrib/sets/lists/man/mi:1.1379.2.7 src/distrib/sets/lists/man/mi:1.1379.2.8 --- src/distrib/sets/lists/man/mi:1.1379.2.7 Fri Jun 15 08:48:47 2012 +++ src/distrib/sets/lists/man/mi Wed Nov 28 21:34:37 2012 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.1379.2.7 2012/06/15 08:48:47 sborrill Exp $ +# $NetBSD: mi,v 1.1379.2.8 2012/11/28 21:34:37 riz Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -159,6 +159,7 @@ ./usr/share/man/cat1/fincore.0 man-util-catman .cat ./usr/share/man/cat1/find.0 man-util-catman .cat ./usr/share/man/cat1/finger.0 man-util-catman .cat +./usr/share/man/cat1/flock.0 man-util-catman .cat ./usr/share/man/cat1/fmt.0 man-util-catman .cat ./usr/share/man/cat1/fold.0 man-util-catman .cat ./usr/share/man/cat1/foreach.0 man-util-catman .cat @@ -3111,6 +3112,7 @@ ./usr/share/man/html1/fincore.html man-util-htmlman html ./usr/share/man/html1/find.html man-util-htmlman html ./usr/share/man/html1/finger.html man-util-htmlman html +./usr/share/man/html1/flock.html man-util-htmlman html ./usr/share/man/html1/fmt.html man-util-htmlman html ./usr/share/man/html1/fold.html man-util-htmlman html ./usr/share/man/html1/foreach.html man-util-htmlman html @@ -5680,6 +5682,7 @@ ./usr/share/man/man1/fincore.1 man-util-man .man ./usr/share/man/man1/find.1 man-util-man .man ./usr/share/man/man1/finger.1 man-util-man .man +./usr/share/man/man1/flock.1 man-util-man .man ./usr/share/man/man1/fmt.1 man-util-man .man ./usr/share/man/man1/fold.1 man-util-man .man ./usr/share/man/man1/foreach.1 man-util-man .man Index: src/usr.bin/Makefile diff -u src/usr.bin/Makefile:1.207 src/usr.bin/Makefile:1.207.2.1 --- src/usr.bin/Makefile:1.207 Tue Feb 7 19:13:31 2012 +++ src/usr.bin/Makefile Wed Nov 28 21:35:00 2012 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.207 2012/02/07 19:13:31 joerg Exp $ +# $NetBSD: Makefile,v 1.207.2.1 2012/11/28 21:35:00 riz Exp $ # from: @(#)Makefile 8.3 (Berkeley) 1/7/94 .include <bsd.own.mk> @@ -10,7 +10,7 @@ SUBDIR= apply asa at audio audiocfg \ column comm compress config crunch csplit ctags cut \ deroff db dirname du \ eject elf2aout elf2ecoff env error expand extattr \ - false fdformat fgen fincore find finger fmt fold fpr from \ + false fdformat fgen fincore find finger flock fmt fold fpr from \ fsplit fstat ftp gcore genassym gencat getconf getent getopt gprof \ head hexdump iconv id indent infocmp innetgr ipcrm ipcs join jot \ kdump ktrace ktruss lam last lastcomm ldd leave \ Added files: Index: src/usr.bin/flock/Makefile diff -u /dev/null src/usr.bin/flock/Makefile:1.1.4.2 --- /dev/null Wed Nov 28 21:35:02 2012 +++ src/usr.bin/flock/Makefile Wed Nov 28 21:34:36 2012 @@ -0,0 +1,8 @@ +# $NetBSD: Makefile,v 1.1.4.2 2012/11/28 21:34:36 riz Exp $ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= flock +#LDADD+= -lutil +#DPADD+= ${LIBUTIL} + +.include <bsd.prog.mk> Index: src/usr.bin/flock/flock.1 diff -u /dev/null src/usr.bin/flock/flock.1:1.8.4.2 --- /dev/null Wed Nov 28 21:35:02 2012 +++ src/usr.bin/flock/flock.1 Wed Nov 28 21:34:36 2012 @@ -0,0 +1,100 @@ +.\" $NetBSD: flock.1,v 1.8.4.2 2012/11/28 21:34:36 riz 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 7.0 . Index: src/usr.bin/flock/flock.c diff -u /dev/null src/usr.bin/flock/flock.c:1.6.4.2 --- /dev/null Wed Nov 28 21:35:02 2012 +++ src/usr.bin/flock/flock.c Wed Nov 28 21:34:36 2012 @@ -0,0 +1,296 @@ +/* $NetBSD: flock.c,v 1.6.4.2 2012/11/28 21:34:36 riz 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.6.4.2 2012/11/28 21:34:36 riz 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 = LOCK_EX; + 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; + timer_t tm; + + setprogname(argv[0]); + + while ((c = getopt_long(argc, argv, "+dnosuvw:x", flock_longopts, NULL)) + != -1) + switch (c) { + case 'd': + debug++; + break; + case 'x': + if (lock & ~LOCK_NB) + goto badlock; + lock |= LOCK_EX; + break; + case 'n': + lock |= LOCK_NB; + break; + case 's': + if (lock & ~LOCK_NB) + goto badlock; + lock |= LOCK_SH; + break; + case 'u': + if (lock & ~LOCK_NB) + 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; + + 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)); + 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) { + 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 %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) + timer_delete(tm); + + if (cls) + (void)close(fd); + + if (cmdargv != NULL) { + execvp(cmdargv[0], cmdargv); + err(EXIT_FAILURE, "execvp '%s'", v = cmdline(cmdargv)); + free(v); + } + return 0; +}