dolock 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #! /usr/bin/perl
  2. # $OpenBSD: dolock,v 1.5 2015/05/14 11:15:29 espie Exp $
  3. # Copyright (c) 2004 Marc Espie <espie@openbsd.org>
  4. #
  5. # Permission to use, copy, modify, and distribute this software for any
  6. # purpose with or without fee is hereby granted, provided that the above
  7. # copyright notice and this permission notice appear in all copies.
  8. #
  9. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. use strict;
  17. use warnings;
  18. use Fcntl;
  19. use File::Basename;
  20. use Getopt::Std;
  21. my %opts;
  22. if (!getopts('m:g:', \%opts)) {
  23. exit(1);
  24. }
  25. if (@ARGV == 0) {
  26. exit(1);
  27. }
  28. my $p = {};
  29. if ($opts{g}) {
  30. $p->{group} = $opts{g};
  31. } else {
  32. $( =~ m/^(\d+)/ and $p->{group} = $1;
  33. }
  34. if ($opts{m}) {
  35. $p->{mode} = oct($opts{m});
  36. }
  37. my $fname = shift;
  38. my $dname = dirname $fname;
  39. my $done = 0;
  40. unless (-e $dname) {
  41. require File::Path;
  42. if ($p->{mode}) {
  43. my $m = umask(0);
  44. File::Path::make_path($dname, $p);
  45. umask($m);
  46. } else {
  47. File::Path::make_path($dname, $p);
  48. }
  49. }
  50. if (!-d $dname) {
  51. print STDERR "lock directory location $dname is not a directory\n";
  52. exit(1);
  53. }
  54. if (!-w _) {
  55. print STDERR "you don't have permission to write into $dname ($<, $()\n";
  56. exit(1);
  57. }
  58. while(1) {
  59. if (sysopen my $handle, $fname, O_WRONLY | O_EXCL | O_CREAT, 0666) {
  60. if (@ARGV) {
  61. print $handle join("\n", @ARGV), "\n";
  62. }
  63. close($handle);
  64. exit(0);
  65. }
  66. unless ($done) {
  67. print STDERR "Awaiting lock $fname\n";
  68. $done = 1;
  69. }
  70. sleep(1);
  71. }