#!perl

our $DATE = '2019-05-23'; # DATE
our $VERSION = '0.207'; # VERSION

use 5.010;
use strict;
use warnings;

use Getopt::Long;
use Proc::Govern;

my @SAVE_ARGV = @ARGV;

my %opts = (
    log_stderr_size      => 10*1024*1024,
    log_stderr_histories => 10,
    log_stdout_size      => 10*1024*1024,
    log_stdout_histories => 10,
);
Getopt::Long::Configure("gnu_getopt", "no_ignore_case");
my $success = GetOptions(
    "help|h|?"               => \$opts{-help},
    "version|v"              => \$opts{-version},

    "name|n=s"               => \$opts{name},
    "nice=i"                 => \$opts{nice},
    "single-instance"        => \$opts{single_instance},
    "restart"                => \$opts{restart},
    "show-stderr!"           => \$opts{show_stderr},
    "log-stderr-dir=s"       => \$opts{log_stderr_dir},
    "log-stderr-size=i"      => \$opts{log_stderr_size},
    "log-stderr-histories=i" => \$opts{log_stderr_histories},
    "log-stderr-period=s"    => \$opts{log_stderr_period},
    "show-stdout!"           => \$opts{show_stdout},
    "log-stdout-dir=s"       => \$opts{log_stdout_dir},
    "log-stdout-size=i"      => \$opts{log_stdout_size},
    "log-stdout-histories=i" => \$opts{log_stdout_histories},
    "log-stdout-period=s"    => \$opts{log_stdout_period},
    "timeout=i"              => \$opts{timeout},
    "pid-dir=s"              => \$opts{pid_dir},
    "on-multiple-instance=s" => \$opts{on_multiple_instance},
    "load-watch"             => \$opts{load_watch},
    "load-high=f"            => sub { $opts{load_watch} = 1; $opts{load_high_limit}  = $_[1] },
    "load-low=f"             => sub { $opts{load_watch} = 1; $opts{load_low_limit}   = $_[1] },
    "load-every=i"           => sub { $opts{load_watch} = 1; $opts{load_check_every} = $_[1] },
    "killfam"                => sub { $opts{killfam} = 1 },
    "no-screensaver"         => \$opts{no_screensaver},
    "euid=s"                 => \$opts{euid},
    "egid=s"                 => \$opts{egid},
);
unless ($success) {
    warn "govproc: Errors in getting command-line options, aborting\n";
    exit 99;
}

if ($opts{-version}) {
    say "govproc version ", ($Proc::Govern::VERSION // "?");
    exit 0;
} elsif ($opts{-help} || !@ARGV) {
    print <<_;
Run child process and govern its various aspects

Usage: govproc [OPTS] -- [COMMAND ...]

Options:
  --name=S                  Set process name.
  --nice=I                  Set nice level/priority.
  --single-instance         Prevent running multiple instances simultaneously.
  --restart                 Restart when child process dies/exits.
  --no-show-stderr          Hide stderr output (but you can still log it).
  --log-stderr-dir=S        Enable logging of stderr and set log directory.
  --log-stderr-size=N       Set log file size limit, in bytes, default 10MB.
  --log-stderr-histories=N  Set number of rotated log files to keep, default 10.
  --log-stderr-period=S     Enable periodic rotation (daily/monthly/yearly).
  --no-show-stdout          Hide stdout output (but you can still log it).
  --log-stdout-dir=S        Enable logging of stdout and set log directory.
  --log-stdout-size=N       Set log file size limit, in bytes, default 10MB.
  --log-stdout-histories=N  Set number of rotated log files to keep, default 10.
  --log-stdout-period=S     Enable periodic rotation (daily/monthly/yearly).
  --timeout=N               Set execution time limit, in seconds.
  --pid-dir=S               Directory to put PID file, if --single-instance set.
  --on-multiple-instance=S  Can be set to 'exit' to silently exit when another
                              instance is already running.
  --load-watch              Enable load watching (suspend when system load is
                              too high, resume when load returns to low).
  --load-high=N             Set load high limit (default: 1.25).
  --load-low=N              Set load low limit (default: 0.25).
  --load-every=N            Set load watch checking frequency, in seconds
                              (default: 10).
  --killfam                 Use killfam instead of kill, to kill process family.
  --no-screensaver          Prevent screensaver from activating.
  --euid=I                  Set EUID of child process.
  --egid=S                  Set EGIDs of child process.

_
    exit 0;
}

my %ga = (
    command         => \@ARGV,
    name            => $opts{name},
    (nice            => $opts{nice}) x !!(defined $opts{nice}),
    single_instance => $opts{single_instance},
    restart         => $opts{restart},
    pid_dir         => $opts{pid_dir},
    timeout         => $opts{timeout},
    on_multiple_instance => $opts{on_multiple_instance},
    (no_screensaver  => $opts{no_screensaver}) x !!$opts{no_screensaver},
    (euid            => $opts{euid}) x !!(defined $opts{euid}),
    (egid            => $opts{egid}) x !!(defined $opts{euid}),
);
$ga{show_stderr} = $opts{show_stderr};
if ($opts{log_stderr_dir}) {
    $ga{log_stderr} = {
        dir       => $opts{log_stderr_dir},
        size      => $opts{log_stderr_size},
        histories => $opts{log_stderr_histories},
        period    => $opts{log_stderr_period},
    };
}
$ga{show_stdout} = $opts{show_stdout};
if ($opts{log_stdout_dir}) {
    $ga{log_stdout} = {
        dir       => $opts{log_stdout_dir},
        size      => $opts{log_stdout_size},
        histories => $opts{log_stdout_histories},
        period    => $opts{log_stdout_period},
    };
}
if ($opts{load_watch}) {
    $ga{load_watch} = 1;
    $ga{load_high_limit}  = $opts{load_high_limit};
    $ga{load_low_limit}   = $opts{load_low_limit};
    $ga{load_check_every} = $opts{load_check_every};
}
if ($opts{killfam}) {
    $ga{killfam} = 1;
}

# show nicer text in 'ps', instead of '/usr/bin/perl /usr/local/bin/govprov
# --opt CMD --cmdopt', show 'govproc --opt'
$0 = "govproc" . " " . join(" ", @SAVE_ARGV[0..(@SAVE_ARGV-@ARGV-1)]);

exit Proc::Govern::govern_process(%ga);

# ABSTRACT: Run child process and govern its various aspects
# PODNAME: govproc

__END__

=pod

=encoding UTF-8

=head1 NAME

govproc - Run child process and govern its various aspects

=head1 VERSION

This document describes version 0.207 of govproc (from Perl distribution Proc-Govern), released on 2019-05-23.

=head1 SYNOPSIS

 % govproc [options] <command>...

See C<govproc --help> for list of options.

=head1 DESCRIPTION

This script is a command-line interface for L<Proc::Govern>.

=head1 EXIT CODES

99 on command-line options error.

=head1 ENVIRONMENT

=head2 DEBUG => bool

If set to true, will display debugging output to STDERR, e.g. when
stopping/starting a process.

=head1 HOMEPAGE

Please visit the project's homepage at L<https://metacpan.org/release/Proc-Govern>.

=head1 SOURCE

Source repository is at L<https://github.com/perlancar/perl-Proc-Govern>.

=head1 BUGS

Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Proc-Govern>

When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.

=head1 SEE ALSO

L<Proc::Govern>

L<after>

=head1 AUTHOR

perlancar <perlancar@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2019, 2018, 2017, 2016, 2015, 2014, 2013, 2012 by perlancar@cpan.org.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut