#! /usr/bin/perl -w
##**************************************************************
##
## Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
## University of Wisconsin-Madison, WI.
## 
## Licensed under the Apache License, Version 2.0 (the "License"); you
## may not use this file except in compliance with the License.  You may
## obtain a copy of the License at
## 
##    http://www.apache.org/licenses/LICENSE-2.0
## 
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
##**************************************************************


##********************************************************************
## Starts the given program with a filelock artifact that an 
## undertaker can check later.
##********************************************************************

#***
# Uses
#***
use strict;
use FindBin;
use lib ($FindBin::Bin, "$FindBin::Bin/lib", "$FindBin::Bin/../lib");
use FileLock;
use Getopt::Long;

#***
# Constant Static Variables
#***
my $USAGE = 
    "Usage: filelock_midwife [--file lockfile] <program> [program_args]\n";

#***
# Non-constant Static Variables
#***
my $lockfile = 'lock.file';
my $help = 0;
my $target_command = 0;
my @target_args = ();

#***
# Main Function
#***

# Parse the command line options
Getopt::Long::Configure ("no_auto_abbrev", 
			 "pass_through", 
			 "require_order");
GetOptions('file=s'=>\$lockfile,
	   'help'=>\$help,

	   );
# Process command line arguments
die $USAGE if( $help || @ARGV < 1 );
$target_command = shift @ARGV;
@target_args = @ARGV;

# Ensure the lock file actually exist
if( !-e $lockfile ){

    # if not,
    # create the file
    open FILE, ">$lockfile"
	or die "FAILED: Could not create $lockfile: $!";
    close FILE;

    # set the permission correctly
    chmod(0644, $lockfile);
    
}
# Acquire a filelock on the lock file
my $lock_handle = &AcquireFLockNB($lockfile, 'X');

# The lock was already held
if( ! defined $lock_handle ){
    die "FAILED: FLock on lock file [$lockfile]".
	" is already held by another process".
	"OR FLocking is not supported on the platform";
}

# Execute the program
# use two parameters to avoid the shell
my $result = system $target_command, @target_args;
if( $result != 0 ){
    my $exit_code = $result >> 8;
    die "Failed to execute command[$target_command]". 
    "with args [@target_args]\n".
    "Exit code of target program: $exit_code\n";
}

# Release the Link Lock
&ReleaseFLock($lock_handle);
