--- old/usr/src/cmd/Makefile	2013-09-14 18:48:47.239608651 +0100
+++ new/usr/src/cmd/Makefile	2013-09-14 18:48:47.244446549 +0100
@@ -231,6 +231,7 @@
 	lgrpinfo	\
 	line		\
 	link		\
+	lockf		\
 	dlmgmtd		\
 	listen		\
 	loadkeys	\
--- /dev/null	2013-09-14 18:48:47.000000000 +0100
+++ new/usr/src/cmd/lockf/Makefile	2013-09-14 18:48:47.436404121 +0100
@@ -0,0 +1,40 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+PROG= 		lockf
+
+include ../Makefile.cmd
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTPROG)
+
+clean:
+
+lint:	lint_PROG
+
+include ../Makefile.targ
--- /dev/null	2013-09-14 18:48:47.000000000 +0100
+++ new/usr/src/cmd/lockf/lockf.c	2013-09-14 18:48:47.531780362 +0100
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2008 Paul Armstrong. All rights reserved.
+ *
+ *  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 AUTHOR 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 AUTHOR 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 <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <wait.h>
+
+#define	SLEEP_TIME 1 /* Sleep time between parent checks */
+
+#if !defined(TEXT_DOMAIN)
+#define	TEXT_DOMAIN "SYS_TEST"
+#endif
+
+/* globals for use in signal handlers */
+int pid = 0;
+boolean_t lock_existed = B_FALSE;
+char *file_name = NULL;
+
+static void
+usage(void)
+{
+	(void) fprintf(stderr,
+	    gettext("Usage: lockf -l|-t|-w -f /path/to/lock | -u pid\n"));
+	exit(EXIT_FAILURE);
+}
+
+/*ARGSUSED*/
+static void
+print_pid(int signal_number)
+{
+	(void) printf("%d\n", pid);
+	exit(EXIT_SUCCESS);
+}
+
+/*ARGSUSED*/
+static void
+cleanup(int signal_handler)
+{
+	if (!lock_existed) {
+		if (-1 == unlink(file_name))
+			perror(file_name);
+	}
+	exit(EXIT_SUCCESS);
+}
+
+int
+main(int argc, char **argv)
+{
+	boolean_t arg_err = B_FALSE;
+	boolean_t lock = B_FALSE, test = B_FALSE;
+	boolean_t unlock = B_FALSE, wait_lock = B_FALSE;
+	extern char *optarg;
+	extern int optind;
+	int calling_pid;
+	int child_status;
+	int filedes;
+	int flag;
+	int return_code;
+	mode_t mode = S_IRUSR | S_IWUSR;
+	struct stat *statbuf;
+
+	(void) setlocale(LC_ALL, "");
+	(void) textdomain(TEXT_DOMAIN);
+
+	while ((flag = getopt(argc, argv, "f:ltu:w")) != -1) {
+		switch (flag) {
+		case 'f':
+			file_name = optarg;
+			break;
+		case 'l':
+			if (unlock || wait_lock || test)
+				arg_err = B_TRUE;
+			lock = B_TRUE;
+			break;
+		case 't':
+			if (unlock || lock)
+				arg_err = B_TRUE;
+			test = B_TRUE;
+			break;
+		case 'u':
+			if (lock || test)
+				arg_err = B_TRUE;
+			unlock = B_TRUE;
+			pid = atoi(optarg);
+			break;
+		case 'w':
+			if (unlock || lock || test)
+				arg_err = B_TRUE;
+			wait_lock = B_TRUE;
+			lock = B_TRUE;
+			break;
+		default:
+			usage();
+		}
+	}
+
+	if (1 == argc)
+		usage();
+
+	argc -= optind;
+	argv -= optind;
+
+	if (1 <= argc)
+		usage();
+
+	if (arg_err) {
+		(void) fprintf(stderr,
+		    gettext("Use only one of -l, -t, -u or -w\n"));
+		usage();
+	}
+
+	if ((lock || test) && (NULL == file_name)) {
+		(void) fprintf(stderr,
+		    gettext("-l, -t and -w require -f\n"));
+		usage();
+	}
+	if (unlock && pid <= 0) {
+		(void) fprintf(stderr,
+		    gettext("-u requires a valid PID\n"));
+		usage();
+	}
+
+	if (unlock) {
+		if (-1 == kill(pid, SIGINT)) {
+			perror("kill");
+			return (EXIT_FAILURE);
+		} else {
+			return (EXIT_SUCCESS);
+		}
+	}
+
+	/* Make test cheap, do it before the fork and return immediately */
+	if (test) {
+		statbuf = malloc(sizeof (struct stat));
+		if (NULL == statbuf) {
+			perror("malloc");
+			exit(EXIT_FAILURE);
+		}
+		if (stat(file_name, statbuf) == -1) {
+			switch (errno) {
+			case ENOENT:
+				exit(EXIT_SUCCESS);
+				/*NOTREACHED*/
+			case EACCES:
+				err(EXIT_FAILURE,
+				    gettext("Bad permissions on lockfile"));
+				/*NOTREACHED*/
+			case ENAMETOOLONG:
+				err(EXIT_FAILURE, "lockfile name too long");
+			}
+		}
+		if ((filedes = open(file_name, O_WRONLY, mode)) == -1) {
+			perror(file_name);
+			return (EXIT_FAILURE);
+		}
+		return_code = lockf(filedes, F_TEST, 0);
+		if (return_code < 0)
+			return (EXIT_FAILURE);
+		return (EXIT_SUCCESS);
+	}
+
+	calling_pid = getppid();
+	if (1 == calling_pid)
+		err(EXIT_FAILURE, "Calling process seems to have died early");
+
+	if ((pid = fork()) < 0) {
+		perror("fork");
+		return (EXIT_FAILURE);
+	}
+
+	if (pid != 0) {
+		(void) signal(SIGUSR1, print_pid);
+
+		if (waitpid(pid, &child_status, 0) != pid) {
+			perror("waitpid");
+			exit(EXIT_FAILURE);
+		}
+
+		return (EXIT_FAILURE);
+	} else {
+
+		(void) close(STDIN_FILENO);
+		(void) close(STDOUT_FILENO);
+
+		return_code = chdir("/");
+		if (return_code < 0) {
+			perror("chdir");
+			return (EXIT_FAILURE);
+		}
+
+		/* Other users shouldn't be trying to write to our lock file */
+		(void) umask(077);
+
+		/*
+		 * Note if the file existed beforehand so we can avoid deleting
+		 * it when we clean up
+		 */
+		if ((filedes =
+		    open(file_name, O_WRONLY | O_CREAT | O_EXCL, mode)) == -1) {
+
+			lock_existed = B_TRUE;
+
+			if ((filedes =
+			    open(file_name, O_WRONLY | O_CREAT, mode)) == -1) {
+				perror(file_name);
+				exit(EXIT_FAILURE);
+			}
+		}
+
+		(void) signal(SIGINT, cleanup);
+		(void) signal(SIGQUIT, cleanup);
+		(void) signal(SIGABRT, cleanup);
+		(void) signal(SIGTERM, cleanup);
+
+		if (wait_lock) {
+			return_code = lockf(filedes, F_LOCK, 0);
+		} else {
+			return_code = lockf(filedes, F_TLOCK, 0);
+		}
+
+		if (return_code < 0)
+			return (EXIT_FAILURE);
+
+		/* Once we have a lock (or not), then kill the parent */
+		if (-1 == kill(getppid(), SIGUSR1)) {
+			perror("kill");
+			return (EXIT_FAILURE);
+		}
+
+		while (calling_pid) {
+			(void) sleep(SLEEP_TIME);
+			if (-1 == kill(calling_pid, 0))
+				calling_pid = 0;
+		}
+
+		cleanup(NULL);
+
+		return (EXIT_SUCCESS);
+	}
+}
--- /dev/null	2013-09-14 18:48:47.000000000 +0100
+++ new/usr/src/cmd/lockf/unittest_lockf	2013-09-14 18:48:47.644944788 +0100
@@ -0,0 +1,125 @@
+#!/bin/bash
+#
+# Copyright (C) 2008 Paul Armstrong. All rights reserved.
+#
+#  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 AUTHOR 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 AUTHOR 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.
+
+# Unit test for lockf(1)
+
+ERROR=""
+LOCK_FILE="`pwd`/test_lock"
+
+err() {
+	echo "$@" >&2
+	ERROR="TRUE"
+}
+
+if [ ! -x lockf ]; then
+	echo "lockf doesn't exist or is not executable. Compile it?" >&2
+	exit 1
+fi
+
+lockf -t -f does_not_exist
+if [ "$?" -ne 0 ]; then
+	err "lockf returned failure for a non-existant lock"
+fi
+
+# /devices is read-only for everyone
+FAILED_WRITE="$(lockf -l -f /devices/test_lock 2>/dev/null)"
+if [ -n "${FAILED_WRITE}" ]; then
+	err "lockf exited successfully on a failed lock creation"
+	kill "${FAILED_WRITE}"
+fi
+
+# all tests after here require this to succeed so it exists immediately on
+# failure
+LOCK_PID="$(lockf -l -f ${LOCK_FILE})"
+if [ -z "${LOCK_PID}" ]; then
+	err "lockf didn't return a PID on lock creation"
+	exit 1
+fi
+
+lockf -l -f "${LOCK_FILE}"
+if [ "$?" -eq 0 ]; then
+	err "lockf returned success for a locked file"
+fi
+
+lockf -t -f "${LOCK_FILE}"
+if [ "$?" -eq 0 ]; then
+	err "lockf returned success for testing a locked file"
+fi
+
+lockf -u "${LOCK_PID}"
+if [ "$?" -ne 0 ]; then
+	err "lockf failed to unlock ${LOCK_PID}"
+fi
+if [ -n "$(ps -eo pid | grep ${LOCK_PID})" ]; then
+	err "Failed to kill child ${LOCK_PID}"
+fi
+
+LOCK_PID=""
+
+# Create a lock so we can test waiting on a lock creation
+LOCK_PID="$(lockf -l -f ${LOCK_FILE})"
+if [ -z "${LOCK_PID}" ]; then
+	err "lockf didn't return a PID on lock creation"
+else
+	(sleep 2; kill ${LOCK_PID})&
+
+	LOCK_PID2="$(alarm 4 lockf -w -f ${LOCK_FILE})"
+	if [ -z "${LOCK_PID2}" ]; then
+		err "Failed to create a lock after a wait"
+	fi
+
+	lockf -u "${LOCK_PID2}"
+	if [ -n "$(ps -eo pid | grep ${LOCK_PID2})" ]; then
+		err "Failed to kill child ${LOCK_PID2}"
+	fi
+fi
+
+# Create a lock so we can test waiting on a lock creation
+LOCK_PID3="$(lockf -l -f ${LOCK_FILE})"
+if [ -z "${LOCK_PID3}" ]; then
+	err "lockf didn't return a PID on lock creation"
+else
+	LOCK_PID4="$(alarm 2 lockf -w -f ${LOCK_FILE})"
+	if [ "$?" -eq 0 ]; then
+		err "alarm should have returned a failure"
+	fi
+	if [ -n "${LOCK_PID4}" ]; then
+		err "Says it created a lock when it should have been waiting"
+	fi
+
+	lockf -u "${LOCK_PID3}"
+	if [ -n "$(ps -eo pid | grep ${LOCK_PID3})" ]; then
+		err "Failed to kill child ${LOCK_PID3}"
+	fi
+fi
+
+if [ -f "${LOCK_FILE}" ]; then
+	rm -f "${LOCK_FILE}"
+fi
+if [ "${ERROR}" = "TRUE" ]; then
+	exit 1
+else
+	exit 0
+fi
--- old/usr/src/man/man1/Makefile	2013-09-14 18:48:47.733576095 +0100
+++ new/usr/src/man/man1/Makefile	2013-09-14 18:48:47.750009217 +0100
@@ -207,6 +207,7 @@
 	 	loadkeys.1			\
 	 	locale.1			\
 	 	localedef.1			\
+		lockf.1				\
 	 	logger.1			\
 	 	login.1				\
 	 	logname.1			\
--- /dev/null	2013-09-14 18:48:47.000000000 +0100
+++ new/usr/src/man/man1/lockf.1	2013-09-14 18:48:47.931626086 +0100
@@ -0,0 +1,204 @@
+'\" t
+.\" Copyright (C) 2008 Paul Armstrong. All rights reserved.
+.\"
+.\"  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 AUTHOR 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 AUTHOR 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.
+
+.TH lockf 1 "2008 Apr 08" "SunOS 5.11" "User Commands"
+.SH NAME
+lockf \- create, test or destroy file locks
+.SH SYNOPSIS
+.LP
+.nf
+\fBlockf\fR [[\fI-l|-t|-w\fR] \fI-f /path/to/lock\fR\fB] | [\fR \fI-u pid\fR]
+.fi
+
+.SH DESCRIPTION
+.sp
+.LP
+The \fBlockf\fR utility creates a lock file and then attempts to lock it using
+lockf(3C) so it is NFS safe and then returns the pid of the lock handler
+process. \fBlockf\fR also checks periodically to ensure that the calling
+process still exists and exits if it does not.
+
+.SH OPTIONS
+.sp
+.LP
+The following options are supported:
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-f\fR file\fR
+.ad
+.RS 10n
+.rt  
+The file to be used for locking. If it exists already, you need to have write
+permissions to the file.  \fBlockf\fR chdir's to / so file \fImust\fR be fully
+pathed. The file will be removed when the lock is removed if it did not exist
+prior to being created by \fBlockf\fR and left otherwise.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-l\fR\fR
+.ad
+.RS 10n
+.rt  
+Lock the file specified with the \fB-f\fR argument. Fails if a lock already
+exists.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-t\fR\fR
+.ad
+.RS 10n
+.rt  
+Test for the existance of a lock on the file specified with \fB-f\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-u\fR pid\fR
+.ad
+.RS 10n
+.rt  
+Kill the lock process at \fBpid\fR (unlocks the file).
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-w\fR\fR
+.ad
+.RS 10n
+.rt  
+Lock the file specified with the \fB-f\fR argument. Waits if a lock already
+exists and returns when a lock is gained.
+.RE
+
+.bp
+
+.SH EXAMPLES
+
+.LP
+\fBExample 1:\fR Creating a lock file, entering the critical section and then
+removing the lock.
+.sp
+.LP
+
+.sp
+.in +2
+.nf
+LOCK_PID="`lockf -l -f ${LOCK_DIR}/lock_file`"
+if [ -z "${LOCK_PID}" ]; then
+  echo "Failed to create lock" >&2
+else
+  critical_section
+  lockf -u "${LOCK_PID}"
+fi
+
+.fi
+.in -2
+.sp
+
+.LP
+\fBExample 2:\fR Testing for a lock on a file
+.sp
+
+.sp
+.in +2
+.nf
+example% \fBlockf -t -f ${PWD}/lock_file\fR
+.fi
+.in -2
+.sp
+
+.LP
+\fBExample 3:\fR Waiting until a lock can be created
+.sp
+
+.sp
+.in +2
+.nf
+example% \fBlockf -w -f ${PWD}/lock_file\fR
+.fi
+.in -2
+.sp
+
+
+.SH ENVIRONMENT VARIABLES
+.sp
+.LP
+See \fBenviron\fR(5) for descriptions of the following environment variables
+that affect the execution of \fBrealpath\fR: \fBLANG\fR, \fBLC_ALL\fR,
+\fBLC_CTYPE\fR,  \fBLC_MESSAGES\fR,  and \fBNLSPATH\fR.
+.SH EXIT STATUS
+.sp
+.LP
+\fBlockf\fR returns 0 if a lock is successfully created, or in the case of a
+test if no lock exists. It returns 1 if an error occurs, or a lock file exists
+and either a lock or test is being attempted.
+.sp
+
+.SH ATTRIBUTES
+.sp
+.LP
+See \fBattributes\fR(5) for descriptions of the following attributes:
+.sp
+
+.sp
+.TS
+tab() box;
+cw(2.75i) |cw(2.75i) 
+lw(2.75i) |lw(2.75i) 
+.
+ATTRIBUTE TYPEATTRIBUTE VALUE
+_
+AvailabilitySUNWesu
+.TE
+
+.SH SEE ALSO
+.sp
+.LP
+\fBlockf\fR(3C), \fBattributes\fR(5), \fBenviron\fR(5)
+.SH NOTES
+.sp
+.LP
+\fBlockf\fR can not be called by init as the case of the parent being init is
+used to check if the original caller died during process start up.
+.sp
+.LP
+While you can use existing files, other processes calling \fBlockf\fR(3C) or
+\fBfcntl\fR(3C) may interfere with the proper operation of \fBlockf\fR(1).
+.sp
+.LP
+\fBlockf\fR will wait indefinitely when called with \fI-w\fR so you may
+consider using \fBalarm\fR(1) to kill it after some reasonable amount of time.
--- old/usr/src/pkg/manifests/system-extended-system-utilities.mf	2013-09-14 18:48:48.013226273 +0100
+++ new/usr/src/pkg/manifests/system-extended-system-utilities.mf	2013-09-14 18:48:48.028049203 +0100
@@ -113,6 +113,7 @@
 file path=usr/bin/last mode=0555
 file path=usr/bin/lastcomm mode=0555
 file path=usr/bin/lgrpinfo mode=0555
+file path=usr/bin/lockf mode=0755
 file path=usr/bin/look mode=0755
 file path=usr/bin/mkfifo mode=0555
 file path=usr/bin/nawk mode=0555
