GIF89a=( �' 7IAXKgNgYvYx\%wh&h}t�h%�s%x�}9�R��&�0%� (�.��5�SD��&�a)�x5��;ͣ*ȡ&ղ)ׯ7׵<ѻ4�3�H֧KͯT��Y�aq��q��F� !� ' !� NETSCAPE2.0 , =( ��pH,�Ȥr�l:xШtJ�Z�جv��z��xL.:��z�n���|N�����~�������& !�0`9R�}��"�"a:S�~x��������g���E�������R���E����B�� ��ȸ��D���"�Ů� �H��L��D٫D�B�����D���T���H �G��A R�ڐ |�� ٭&��E8�S�kG�A�px�a��� R2XB��E8I���6X�:vT)�~��q�賥��"F~%x� � 4#Z�0O|-4Bs�X:= Q� Sal��yXJ`GȦ|s h��K3l7�B|�$'7Jީܪ0!��D�n=�P� ����0`�R�lj����v>���5 �.69�ϸd�����nlv�9��f{���Pbx �l5}�p� ��� �3a���I�O����!ܾ���i��9��#��)p�a ޽ �{�)vm��%D~ 6f��s}Œ�D�W E�`!� �&L8x� �ܝ{)x`X/>�}m��R�*|`D�=�_ ^�5 !_&'a�O�7�c��`DCx`�¥�9�Y�F���`?��"� �n@`�} lď��@4>�d S �v�xN��"@~d��=�g�s~G��� ���ud &p8Q�)ƫlXD����A~H�ySun�j���k*D�LH�] ��C"J��Xb~ʪwSt}6K,��q�S:9ت:���l�@�`�� �.۬�t9�S�[:��=`9N����{¿�A !R�:���6��x�0�_ �;������^���#����!����U���;0L1�����p% A��U̬ݵ��%�S��!���~`�G���� ���=4�np�3���������u�u�ٮ|%2�I��r�#0��J``8�@S@5� ���^`8E�]�.�S���7 � �0�j S�D� z���i�S�����!���l��w9*�D�I�nEX��� &A�Go�Qf��F��;���}�J����F5��Q|���X��T��y���]� o ��C=��:���PB@ D׽S�(>�C�x}`��xJЬ�۠��p+eE0`�}`A �/NE�� �9@��� H�7�!%B0`�l*��!8 2�%� �:�1�0E��ux%nP1�!�C)�P81l�ɸF#Ƭ{����B0>�� �b�`��O3��()yRpb��E.ZD8�H@% �Rx+%���c� ���f��b�d�`F�"8�XH"��-�|1�6iI, 2�$+](A*j� QT�o0.�U�`�R�}`�SN����yae�����b��o~ S)�y�@��3 �tT�0�&�+~L�f"�-|�~��>!�v��~�\Q1)}@�}h#aP72�"�$ !� " , =( &7IAXG]KgNgYvYxR"k\%w]'}h}t�h%�g+�s%r.m3ax3�x�}9��&��+�!7�0%� (�.�SD��&��;�"&ײ)׻4��6�K� �@pH,�Ȥr�l:xШtJ�Z�جv��z��xL.:��z�n���|N�����~�������& !�0`9R�}��"�"a:S�~x��������g �� E �� �������E �´��C���ǶR��D��"Ʒ�ʱH��M��GڬD�B����D��T����G���C�C� l&�~:'�tU�6ɹ#��)�'�.6�&��Ȼ K(8p0N�?!�2"��NIJX>R��OM '��2�*x�>#n� �@<[:�I�f ��T���Cdb��[�}E�5MBo��@�`@��tW-3 �x�B���jI�&E�9[T&$��ﯧ&"s��ȳ����dc�UUρ#���ldj?����`\}���u|3'�R]�6 �S#�!�FKL�*N E���`$�:e�YD�q�.�촁�s \-�jA 9�����-��M[�x(�s��x�|���p��}k�T�DpE@W� ��]k`1� ���Yb ��0l��*n0��"~zBd�~u�7�0Bl��0-�x~|U�U0 �h�*HS�|��e"#"?vp�i`e6^�+q��`m8 #V�� ��VS|`��"m"сSn|@:U���~`pb�G�ED����2F�I�? >�x� R� ��%~jx��<�a�9ij�2�D��&: Z`�]w���:�6��B�7eFJ|�ҧ�,���FǮcS�ʶ+B�,�ܺN���>PAD�HD��~���n��}�#�� Q��S���2�X�{�k�lQ�2�����w�|2� h9��G�,m���3��6-��E�L��I�³*K���q�`DwV�QXS��peS��� qܧTS����R�u �<�a�*At�lmE� � ��N[P1�ۦ��$��@`��Dpy�yXvCAy�B`}D� 0QwG#� �a[^�� $���Ǧ{L�"[��K�g�;�S~��GX.�goT.��ư��x���?1z��x~:�g�|�L� ��S`��0S]P�^p F<""�?!,�!N4&P� ����:T�@h�9%t��:�-~�I<`�9p I&.)^ 40D#p@�j4�ج:�01��rܼF2oW�#Z ;$Q q  �K��Nl#29 !F@�Bh�ᏬL!XF�LHKh�.�hE&J�G��<"WN!�����Y@� >R~19J"�2,/ &.GXB%�R�9B6�W]���W�I�$��9�RE8Y� ��"�A5�Q.axB�&ة�J�! �t)K%tS-�JF b�NMxL��)�R��"���6O!TH�H� 0 !� ) , =( &AXKgNgYvYxR"k\%wh&h}h%�g+�s%r.x3�x�}9��&��+�R,�!7�0%� (�.��5��&�a)��;�"&ף*Ȳ)ׯ7׻4�3��6�H֧KͻH�T��Y��q��h� ��pH,�Ȥr�l:xШtJ�Z�جv��z��xL.:��z�n���|N�����~�������& !�0`9R�}��"�"a:S�~x��������g �� E$����� � ����$E$��"��D� � ������R��C��� E ��H�M��G�D� �B��ϾD��a��`1r��Ӑ�� �o~�zU!L�C'�yW�UGt����ll�0���uG�)A�s[��x� �xO%��X2�  P�n:R/��aHae+�Dm?# ǣ6�8�J�x�Di�M���j���5oQ7�- <! *�l��R2r/a!l)d� A"�E���� &� ;��c �%����b��pe~C"B���H�eF2��`8qb�t_`ur`e� w�u3��Pv�h""�`�Íx�LĹ��3� �~ֺ�:���MDfJ� �۵�W�%�S�X �؁)�@��:E��w�u�Sxb8y\m�zS��Zb�E�L��w!y(>�"w�=�|��s�d �C�W)H�cC$�L �7r.�\{)@�`@ �X�$PD `aaG:���O�72E�amn]�"Rc�x�R� &dR8`g��i�xLR!�P &d����T���i�|�_ � Qi�#�`g:��:noM� :V �)p����W&a=�e�k� j���1߲s�x�W�jal|0��B0�, \j۴:6���C ��W��|��9���zĸV {�;��n��V�m�I��.��PN� ����C��+��By�ѾHŸ:��� 7�Y�FTk�SaoaY$D�S���29R�kt� ��f� ��:��Sp�3�I��DZ� �9���g��u�*3)O��[_hv ,���Et x�BH� �[��64M@�S�M7d�l�ܶ5-��U܍��z�R3Ԭ3~ ��P��5�g: ���kN�&0�j4���#{��3S�2�K�'ợl���2K{� {۶?~m𸧠�I�nE�='����^���_�=��~�#O���'���o..�Y�n��CSO��a��K��o,���b�����{�C�� "�{�K ��w��Ozdը�:$ ���v�] A#� ���a�z)Rx׿ƥ�d``�w-�y�f�K!����|��P��=�`�(f��'Pa ��BJa%��f�%`�}F����6>��`G"�}�=�!o`�^FP�ةQ�C���`(�}\�ݮ ��$<��n@dĠE#��U�I�!� #l��9`k���'Rr��Z�NB�MF �[�+9���-�wj���8�r� ,V�h"�|�S=�G_��"E� 0i*%̲��da0mVk�):;&6p>�jK ��# �D�:�c?:R Ӭf��I-�"�<�="��7�3S��c2RW ,�8(T"P0F¡Jh�" ; 403WebShell
403Webshell
Server IP : 173.249.157.85  /  Your IP : 3.144.103.205
Web Server : Apache
System : Linux server.frogzhost.com 3.10.0-1127.19.1.el7.x86_64 #1 SMP Tue Aug 25 17:23:54 UTC 2020 x86_64
User : econtech ( 1005)
PHP Version : 7.3.33
Disable Function : NONE
MySQL : OFF  |  cURL : OFF  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /bin/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /bin/niceload
#!/usr/bin/perl -w

# Copyright (C) 2004,2005,2006,2006,2008,2009,2010 Ole Tange,
# http://ole.tange.dk
#
# Copyright (C) 2010,2011,2012,2013,2014,2015 Ole Tange,
# http://ole.tange.dk and Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>
# or write to the Free Software Foundation, Inc., 51 Franklin St,
# Fifth Floor, Boston, MA 02110-1301 USA

use strict;
use Getopt::Long;
$Global::progname="niceload";
$Global::version = 20160222;
Getopt::Long::Configure("bundling","require_order");
get_options_from_array(\@ARGV) || die_usage();
if($opt::version) {
    version();
    exit 0;
}
if($opt::help) {
    help();
    exit 0;
}
if($opt::factor and $opt::suspend) {
    # You cannot have --suspend and --factor
    help();
    exit;
}

if(not (defined $opt::start_io or defined $opt::run_io
	or defined $opt::start_load or defined $opt::run_load
	or defined $opt::start_mem or defined $opt::run_mem
	or defined $opt::start_noswap or defined $opt::run_noswap
	or defined $opt::io or defined $opt::load
	or defined $opt::mem or defined $opt::noswap)) {
    # Default is --runload=1
    $opt::run_load = 1;
}

if(not defined $opt::start_io) { $opt::start_io = $opt::io; }
if(not defined $opt::run_io) { $opt::run_io = $opt::io; }
if(not defined $opt::start_load) { $opt::start_load = $opt::load; }
if(not defined $opt::run_load) { $opt::run_load = $opt::load; }
if(not defined $opt::start_mem) { $opt::start_mem = $opt::mem; }
if(not defined $opt::run_mem) { $opt::run_mem = $opt::mem; }
if(not defined $opt::start_noswap) { $opt::start_noswap = $opt::noswap; }
if(not defined $opt::run_noswap) { $opt::run_noswap = $opt::noswap; }

if(defined $opt::load) { multiply_binary_prefix($opt::load); }

my $limit = Limit->new();
my $process = Process->new($opt::nice,@ARGV);
$::exitstatus = 0;
if(@opt::prg) {
    # Find all pids of prg
    my $out = `pidof -x @opt::prg`;
    $process->set_pid(split /\s+/,$out);
    $::resume_process = $process;
    $SIG{TERM} = $SIG{INT} = \&resume;
} elsif(@opt::pid) {
    $process->set_pid(@opt::pid);
    $::resume_process = $process;
    $SIG{TERM} = $SIG{INT} = \&resume;
} elsif (@ARGV) {
    # Wait until limit is below start_limit and run_limit
    while($limit->over_start_limit()
	  or
	  ($limit->hard() and $limit->over_run_limit())) {
	$limit->sleep_for_recheck();
    }
    $process->start();
}

while($process->is_alive()) {
    if($limit->over_run_limit()) {
	$process->suspend();
	$limit->sleep_for_recheck();
	if(not $limit->hard()) {
	    $process->resume();
	    $limit->sleep_while_running();
	}
    } else {
	$process->resume();
	$limit->sleep_while_running();
    }
}

exit($::exitstatus);

sub resume {
    $::resume_process->resume();
    exit(0);
}

sub uniq {
    # Remove duplicates and return unique values
    return keys %{{ map { $_ => 1 } @_ }};
}

sub multiply_binary_prefix {
    # Evalualte numbers with binary prefix
    # k=10^3, m=10^6, g=10^9, t=10^12, p=10^15, e=10^18, z=10^21, y=10^24
    # K=2^10, M=2^20, G=2^30, T=2^40, P=2^50, E=2^70, Z=2^80, Y=2^80
    # Ki=2^10, Mi=2^20, Gi=2^30, Ti=2^40, Pi=2^50, Ei=2^70, Zi=2^80, Yi=2^80
    # ki=2^10, mi=2^20, gi=2^30, ti=2^40, pi=2^50, ei=2^70, zi=2^80, yi=2^80
    # 13G = 13*1024*1024*1024 = 13958643712
    my $s = shift;
    $s =~ s/k/*1000/g;
    $s =~ s/M/*1000*1000/g;
    $s =~ s/G/*1000*1000*1000/g;
    $s =~ s/T/*1000*1000*1000*1000/g;
    $s =~ s/P/*1000*1000*1000*1000*1000/g;
    $s =~ s/E/*1000*1000*1000*1000*1000*1000/g;
    $s =~ s/Z/*1000*1000*1000*1000*1000*1000*1000/g;
    $s =~ s/Y/*1000*1000*1000*1000*1000*1000*1000*1000/g;
    $s =~ s/X/*1000*1000*1000*1000*1000*1000*1000*1000*1000/g;

    $s =~ s/Ki?/*1024/gi;
    $s =~ s/Mi?/*1024*1024/gi;
    $s =~ s/Gi?/*1024*1024*1024/gi;
    $s =~ s/Ti?/*1024*1024*1024*1024/gi;
    $s =~ s/Pi?/*1024*1024*1024*1024*1024/gi;
    $s =~ s/Ei?/*1024*1024*1024*1024*1024*1024/gi;
    $s =~ s/Zi?/*1024*1024*1024*1024*1024*1024*1024/gi;
    $s =~ s/Yi?/*1024*1024*1024*1024*1024*1024*1024*1024/gi;
    $s =~ s/Xi?/*1024*1024*1024*1024*1024*1024*1024*1024*1024/gi;
    $s = eval $s;
    return $s;
}

sub get_options_from_array {
    # Run GetOptions on @array
    # Returns:
    #   true if parsing worked
    #   false if parsing failed
    #   @array is changed
    my $array_ref = shift;
    # A bit of shuffling of @ARGV needed as GetOptionsFromArray is not
    # supported everywhere
    my @save_argv;
    my $this_is_ARGV = (\@::ARGV == $array_ref);
    if(not $this_is_ARGV) {
	@save_argv = @::ARGV;
	@::ARGV = @{$array_ref};
    }
    my @retval = GetOptions
	("debug|D" => \$opt::debug,
	 "factor|f=s" => \$opt::factor,
	 "hard|H" => \$opt::hard,
	 "soft|S" => \$opt::soft,
	 "sensor=s" => \$opt::sensor,

	 "si|sio|startio|start-io=s" => \$opt::start_io,
	 "ri|rio|runio|run-io=s" => \$opt::run_io,
	 "io|I=s" => \$opt::io,

	 "sl|startload|start-load=s" => \$opt::start_load,
	 "rl|runload|run-load=s" => \$opt::run_load,
	 "load|L|l=s" => \$opt::load,

	 "sm|startmem|start-mem=s" => \$opt::start_mem,
	 "rm|runmem|run-mem=s" => \$opt::run_mem,
	 "mem|M=s" => \$opt::mem,

	 "sn|startnoswap|start-noswap|start-no-swap" => \$opt::start_noswap,
	 "rn|runnoswap|run-noswap|run-no-swap" => \$opt::run_noswap,
	 "noswap|N" => \$opt::noswap,

	 # niceload -l -1 --sensor 'cat /sys/class/power_supply/BAT0/status /proc/acpi/battery/BAT0/state 2>/dev/null |grep -i -q discharging; echo $?'
	 "battery|B" => \$opt::battery,

	 "nice|n=i" => \$opt::nice,
	 "program|prg=s" => \@opt::prg,
	 "process|pid|p=s" => \@opt::pid,
	 "suspend|s=s" => \$opt::suspend,
	 "recheck|t=s" => \$opt::recheck,
	 "quote|q" => \$opt::quote,
	 "help|h" => \$opt::help,
	 "verbose|v" => \$opt::verbose,
	 "version|V" => \$opt::version,
	);
    if(not $this_is_ARGV) {
	@{$array_ref} = @::ARGV;
	@::ARGV = @save_argv;
    }
    return @retval;
}


sub die_usage {
    help();
    exit 1;
}


sub help {
    print q{
Usage:
   niceload [-v] [-n niceness] [-L loadavg] [-I io] [-N] [-M mem]
            [-s suspend_sec|-f factor] [-H] [-S]
            command or -p pid
};
}


sub die_bug {
    my $bugid = shift;
    print STDERR
	("$Global::progname: This should not happen. You have found a bug.\n",
	 "Please contact <parallel\@gnu.org> and include:\n",
	 "* The version number: $Global::version\n",
	 "* The bugid: $bugid\n",
	 "* The command line being run\n",
	 "* The files being read (put the files on a webserver if they are big)\n",
	 "\n",
	 "If you get the error on smaller/fewer files, please include those instead.\n");
    exit(255);
}


sub usleep {
    # Sleep this many milliseconds.
    my $secs = shift;
    ::debug("Sleeping ",$secs," millisecs\n");
    select(undef, undef, undef, $secs/1000);
}


sub debug {
    if($opt::debug) {
	print STDERR @_;
    }
}


sub my_dump {
    # Returns:
    #   ascii expression of object if Data::Dump(er) is installed
    #   error code otherwise
    my @dump_this = (@_);
    eval "use Data::Dump qw(dump);";
    if ($@) {
        # Data::Dump not installed
        eval "use Data::Dumper;";
        if ($@) {
            my $err =  "Neither Data::Dump nor Data::Dumper is installed\n".
                "Not dumping output\n";
            print STDERR $err;
            return $err;
        } else {
            return Dumper(@dump_this);
        }
    } else {
        eval "use Data::Dump qw(dump);";
        return (Data::Dump::dump(@dump_this));
    }
}


sub version {
    # Returns: N/A
    print join("\n",
	       "GNU $Global::progname $Global::version",
	       "Copyright (C) 2004,2005,2006,2007,2008,2009 Ole Tange",
	       "Copyright (C) 2010,2011 Ole Tange and Free Software Foundation, Inc.",
	       "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>",
	       "This is free software: you are free to change and redistribute it.",
	       "GNU $Global::progname comes with no warranty.",
	       "",
	       "Web site: http://www.gnu.org/software/parallel\n"
	);
}


sub max {
    # Returns:
    #   Maximum value of array
    my $max;
    for (@_) {
        # Skip undefs
        defined $_ or next;
        defined $max or do { $max = $_; next; }; # Set $_ to the first non-undef
        $max = ($max > $_) ? $max : $_;
    }
    return $max;
}

sub min {
    # Returns:
    #   Minimum value of array
    my $min;
    for (@_) {
        # Skip undefs
        defined $_ or next;
        defined $min or do { $min = $_; next; }; # Set $_ to the first non-undef
        $min = ($min < $_) ? $min : $_;
    }
    return $min;
}


package Process;

sub new {
    my $class = shift;
    my $nice = shift;
    my @ARGV = @_;
    if($nice) {
	unshift(@ARGV, "nice", "-n", $nice);
    }
    return bless {
	'running' => 0, # Is the process running now?
	'command' => [@ARGV],
    }, ref($class) || $class;
}

sub pgrp {
    my $self = shift;
    my @pgrp;
    if(not $self->{'pgrp'}) {
	for(@{$self->{'pids'}}) {
	    push @pgrp,-getpgrp($_);
	}
	@pgrp = ::uniq(@pgrp);
	@{$self->{'pgrp'}} = @pgrp;
    }
    return @{$self->{'pgrp'}};
}

sub set_pid {
    my $self = shift;
    push(@{$self->{'pids'}},@_);
    $self->{'running'} = 1;
    $::exitstatus = 0;
}

sub start {
    # Start the program
    my $self = shift;
    ::debug("Starting @{$self->{'command'}}\n");
    $self->{'running'} = 1;
    if($self->{'pid'} = fork) {
	# set signal handler to kill children if parent is killed
	push @{$self->{'pids'}}, $self->{'pid'};
	$Global::process = $self;
	$SIG{CHLD} = \&REAPER;
	$SIG{INT}=\&kill_child_INT;
	$SIG{TSTP}=\&kill_child_TSTP;
	$SIG{CONT}=\&kill_child_CONT;
 	sleep 1; # Give child time to setpgrp(0,0);
    } else {
 	setpgrp(0,0);
 	::debug("Child pid: $$, pgrp: ",getpgrp $$,"\n");
 	::debug("@{$self->{'command'}}\n");
	if($opt::quote) {
	    system(@{$self->{'command'}});
	} else {
	    system("@{$self->{'command'}}");
	}
	$::exitstatus = $? >> 8;
	$::exitsignal = $? & 127;
	::debug("Child exit $::exitstatus\n");
	exit($::exitstatus);
    }
}

use POSIX ":sys_wait_h";
use POSIX qw(:sys_wait_h);

sub REAPER {
    my $stiff;
    while (($stiff = waitpid(-1, &WNOHANG)) > 0) {
        # do something with $stiff if you want
        $::exitstatus = $? >> 8;
        $::exitsignal = $? & 127;
    }
    $SIG{CHLD} = \&REAPER;                  # install *after* calling waitpid
}


sub kill_child_CONT {
    my $self = $Global::process;
    ::debug("SIGCONT received. Killing @{$self->{'pgrp'}}\n");
    kill CONT => $self->pgrp();
}


sub kill_child_TSTP {
    my $self = $Global::process;
    ::debug("SIGTSTP received. Killing $self->{'pid'} and self ($$)\n");
    kill TSTP => $self->pgrp();
    kill STOP => -$$;
    kill STOP => $$;
}


sub kill_child_INT {
    my $self = $Global::process;
    ::debug("SIGINT received.\n");
    if(not @opt::pid) {
	::debug("Killing $self->{'pid'} Exit\n");
	kill INT => $self->pgrp();
    } else {
	::debug("Continue pids $self->{'pid'} Exit\n");
	kill CONT => $self->pgrp();
    }
    exit;
}


sub resume {
    my $self = shift;
    ::debug("Resume @{$self->{'pids'}}\n");
    if(not $self->{'running'}) {
	# - = PID group
	map { kill "CONT", -$_ } @{$self->{'pids'}};
	# If using -p it is not in a group
	map { kill "CONT", $_ } @{$self->{'pids'}};
	$self->{'running'} = 1;
    }
}


sub suspend {
    my $self = shift;
    ::debug("Suspend @{$self->{'pids'}}\n");
    if($self->{'running'}) {
	# - = PID group
	map { kill "STOP", -$_ } @{$self->{'pids'}};
	# If using -p it is not in a group
	map { kill "STOP", $_ } @{$self->{'pids'}};
	$self->{'running'} = 0;
    }
}


sub is_alive {
    # The process is dead if none of the pids exist
    my $self = shift;
    my ($exists) = 0;
    for my $pid (@{$self->{'pids'}}) {
	if(kill 0 => $pid) { $exists++ }
    }
    ::debug("is_alive: $exists\n");
    return $exists;
}


package Limit;

sub new {
    my $class = shift;
    my %limits = @_;
    my $hard = $opt::soft ? 0 : $opt::hard;
    my $runio = $opt::run_io ? ::multiply_binary_prefix($opt::run_io) : 0;
    my $startio = $opt::start_io ? ::multiply_binary_prefix($opt::start_io) : 0;
    my $runload = $opt::run_load ? ::multiply_binary_prefix($opt::run_load) : 0;
    my $startload = $opt::start_load ? ::multiply_binary_prefix($opt::start_load) : 0;
    my $runmem = $opt::run_mem ? ::multiply_binary_prefix($opt::run_mem) : 0;
    my $startmem = $opt::start_mem ? ::multiply_binary_prefix($opt::start_mem) : 0;
    my $runnoswap = $opt::run_noswap ? ::multiply_binary_prefix($opt::run_noswap) : 0;
    my $startnoswap = $opt::start_noswap ? ::multiply_binary_prefix($opt::start_noswap) : 0;
    my $recheck = $opt::recheck ? ::multiply_binary_prefix($opt::recheck) : 1; # Default
    my $runtime = $opt::suspend ? ::multiply_binary_prefix($opt::suspend) : 1; # Default

    return bless {
	'hard' => $hard,
	'recheck' => $recheck,
	'runio' => $runio,
	'startio' => $startio,
	'runload' => $runload,
	'startload' => $startload,
	'runmem' => $runmem,
	'startmem' => $startmem,
	'runnoswap' => $runnoswap,
	'startnoswap' => $startnoswap,
	'factor' => $opt::factor || 1,
	'recheck' => $recheck,
	'runtime' => $runtime,
	'over_run_limit' => 1,
	'over_start_limit' => 1,
	'verbose' => $opt::verbose,
    }, ref($class) || $class;
}


sub over_run_limit {
    my $self = shift;
    my $status = 0;
    if($self->{'runmem'}) {
	# mem should be between 0-10ish
	# 100% available => 0 (1-1)
	# 50% available => 1 (2-1)
	# 10% available => 9 (10-1)
	my $mem = $self->mem_status();
	::debug("Run memory: $self->{'runmem'}/$mem\n");
	$status += (::max(1,$self->{'runmem'}/$mem)-1);
    }
    if($self->{'runload'}) {
	# If used with other limits load should be between 0-10ish
	no warnings 'numeric';
	my $load = $self->load_status();
	if($self->{'runload'} > 0) {
	    # Stop if the load is above the limit
	    $status += ::max(0,$load - $self->{'runload'});
	} else {
	    # Stop if the load is below the limit (for sensor)
	    $status += ::max(0,-$load - $self->{'runload'});
	}
    }
    if($self->{'runnoswap'}) {
	# swap should be between 0-10ish
	# swap in or swap out or no swap = 0
	# else log(swapin*swapout)
	my $swap = $self->swap_status();
	$status += log(::max(1, $swap - $self->{'runnoswap'}));
    }
    if($self->{'runio'}) {
	my $io = $self->io_status();
	$status += ::max(0,$io - $self->{'runio'});
    }
    $self->{'over_run_limit'} = $status;
    if(not $opt::recheck) {
	$self->{'recheck'} = $self->{'factor'} * $self->{'over_run_limit'};
    }
    ::debug("over_run_limit: $status\n");
    return $self->{'over_run_limit'};
}

sub over_start_limit {
    my $self = shift;
    my $status = 0;
    if($self->{'startmem'}) {
	# mem should be between 0-10ish
	# 100% available => 0 (1-1)
	# 50% available => 1 (2-1)
	# 10% available => 9 (10-1)
	my $mem = $self->mem_status();
	::debug("Start memory: $self->{'startmem'}/$mem\n");
	$status += (::max(1,$self->{'startmem'}/$mem)-1);
    }
    if($self->{'startload'}) {
	# load should be between 0-10ish
	# 0 load => 0
	no warnings 'numeric';
	my $load = $self->load_status();
	if($self->{'startload'} > 0) {
	    # Stop if the load is above the limit
	    $status += ::max(0,$load - $self->{'startload'});
	} else {
	    # Stop if the load is below the limit (for sensor)
	    $status += ::max(0,-$load - $self->{'startload'});
	}
    }
    if($self->{'startnoswap'}) {
	# swap should be between 0-10ish
	# swap in or swap out or no swap = 0
	# else log(swapin*swapout)
	my $swap = $self->swap_status();
	$status += log(::max(1, $swap - $self->{'startnoswap'}));
    }
    if($self->{'startio'}) {
	my $io = $self->io_status();
	$status += ::max(0,$io - $self->{'startio'});
    }
    $self->{'over_start_limit'} = $status;
    if(not $opt::recheck) {
	$self->{'recheck'} = $self->{'factor'} * $self->{'over_start_limit'};
    }
    ::debug("over_start_limit: $status\n");
    return $self->{'over_start_limit'};
}


sub hard {
    my $self = shift;
    return $self->{'hard'};
}


sub verbose {
    my $self = shift;
    return $self->{'verbose'};
}


sub sleep_for_recheck {
    my $self = shift;
    if($self->{'recheck'} < 0.01) {
	# Never sleep less than 0.01 sec
	$self->{'recheck'} = 0.01;
    }
    if($self->verbose()) {
	$self->{'recheck'} = int($self->{'recheck'}*100)/100;
	print STDERR "Sleeping $self->{'recheck'}s\n";
    }
    ::debug("recheck in $self->{'recheck'}s\n");
    ::usleep(1000*$self->{'recheck'});
}


sub sleep_while_running {
    my $self = shift;
    ::debug("check in $self->{'runtime'}s\n");
    if($self->verbose()) {
	$self->{'runtime'} = int($self->{'runtime'}*100)/100;
	print STDERR "Running $self->{'runtime'}s\n";
    }
    ::usleep(1000*$self->{'runtime'});
}


sub nonblockGetLines {
    # An non-blocking filehandle read that returns an array of lines read
    # Returns:  ($eof,@lines)
    # Example: --sensor 'vmstat 1 | perl -ane '\''$|=1; 4..0 and print $F[8],"\n"'\'
    my ($fh,$timeout) = @_;

    $timeout = 0 unless defined $timeout;
    my $rfd = '';
    $::nonblockGetLines_last{$fh} = ''
        unless defined $::nonblockGetLines_last{$fh};

    vec($rfd,fileno($fh),1) = 1;
    return unless select($rfd, undef, undef, $timeout)>=0;
    # I'm not sure the following is necessary?
    return unless vec($rfd,fileno($fh),1);
    my $buf = '';
    my $n = sysread($fh,$buf,1024*1024);

    my $eof = eof($fh);
    # If we're done, make sure to send the last unfinished line
    return ($eof,$::nonblockGetLines_last{$fh}) unless $n;
    # Prepend the last unfinished line
    $buf = $::nonblockGetLines_last{$fh}.$buf;
    # And save any newly unfinished lines
    $::nonblockGetLines_last{$fh} =
        (substr($buf,-1) !~ /[\r\n]/ && $buf =~ s/([^\r\n]*)$//)
	? $1 : '';
    $buf ? ($eof,split(/\n/,$buf)) : ($eof);
}

sub read_sensor {
    my $self = shift;
    ::debug("read_sensor");
    my $fh = $self->{'sensor_fh'};
    if(not $fh) {
	# Start the sensor
	open($fh, "-|", $opt::sensor) || ::die_bug("Cannot open: $opt::sensor");
	$self->{'sensor_fh'} = $fh;
    }
    # Read as much as we can (non_block)
    my ($eof,@lines) = nonblockGetLines($fh);
    
    # new load = last full line
    foreach my $line (@lines) {
	if(defined $line) {
	    ::debug("Pipe saw: $eof [$line]\n");
	    $Global::last_sensor_reading = $line;
	}
    }
    if($eof) {
	# End of file => Restart the sensor
	close $fh;
	open($fh, "-|", $opt::sensor) || ::die_bug("Cannot open: $opt::sensor");
	$self->{'sensor_fh'} = $fh;
    }

    return $Global::last_sensor_reading;
}

sub load_status {
    # Returns:
    #   loadavg or sensor measurement
    my $self = shift;

    if($opt::sensor) {
	if(not defined $self->{'load_status'} or
	   $self->{'load_status_cache_time'} + $self->{'recheck'} < time) {
	    $self->{'load_status'} = $self->read_sensor();
	    while (not defined $self->{'load_status'}) {
		sleep 1;
		$self->{'load_status'} = $self->read_sensor();
	    } 
	    $self->{'load_status_cache_time'} = time - 0.001;
	}
    } else {
	# Normal load avg
	# Cache for some seconds
	if(not defined $self->{'load_status'} or
	   $self->{'load_status_cache_time'} + $self->{'recheck'} < time) {
	    $self->{'load_status'} = load_status_linux() if $^O ne 'darwin';
	    $self->{'load_status'} = load_status_darwin() if $^O eq 'darwin';
	    $self->{'load_status_cache_time'} = time;
	}
    }
    ::debug("load_status: ".$self->{'load_status'}."\n");
    return $self->{'load_status'};
}

sub undef_as_zero {
    my $a = shift;
    return $a ? $a : 0;
}


sub load_status_linux {
    my ($loadavg);
    if(open(IN,"/proc/loadavg")) {
	# Linux specific (but fast)
	my $upString = <IN>;
	if($upString =~ m/^(\d+\.\d+)/) {
	    $loadavg = $1;
	} else {
	    ::die_bug("proc_loadavg");
	}
	close IN;
    } elsif (open(IN,"uptime|")) {
	my $upString = <IN>;
	if($upString =~ m/averages?.\s*(\d+\.\d+)/) {
	    $loadavg = $1;
	} else {
	    ::die_bug("uptime");
	}	
	close IN;
    }
    return $loadavg;
}

sub load_status_darwin {
    my $loadavg = `sysctl vm.loadavg`;
    if($loadavg =~ /vm\.loadavg: { ([0-9.]+) ([0-9.]+) ([0-9.]+) }/) {
	$loadavg = $1;
    } elsif (open(IN,"LANG=C uptime|")) {
	my $upString = <IN>;
	if($upString =~ m/averages?.\s*(\d+\.\d+)/) {
	    $loadavg = $1;
	} else {
	    ::die_bug("uptime");
	}
	close IN;
    }
    return $loadavg;
}


sub swap_status {
    # Returns:
    #   (swap in)*(swap out) kb
    my $self = shift;
    my $status;
    # Cache for some seconds
    if(not defined $self->{'swap_status'} or
       $self->{'swap_status_cache_time'}+$self->{'recheck'} < time) {
	$status = swap_status_linux() if $^O ne 'darwin';
	$status = swap_status_darwin() if $^O eq 'darwin';
	$self->{'swap_status'} = ::max($status,0);
	$self->{'swap_status_cache_time'} = time;
    }
    ::debug("swap_status: $self->{'swap_status'}\n");
    return $self->{'swap_status'};
}


sub swap_status_linux {
    my $swap_activity;
    $swap_activity = "vmstat 1 2 | tail -n1 | awk '{print \$7*\$8}'";
    # Run swap_activity measuring.
    return qx{ $swap_activity };
}

sub swap_status_darwin {
    # Mach Virtual Memory Statistics: (page size of 4096 bytes, cache hits 0%)
    #   free active   spec inactive   wire   faults     copy    0fill reactive  pageins  pageout
    # 298987 251463 162637    69437 265724 29730558   299022  2308237        1   110058        0
    # 298991 251479 162637    69437 265726       43        4       16        0        0        0
    my ($pagesize, $pageins, $pageouts);
    my @vm_stat = `vm_stat 1 | head -n4`;
    $pagesize = $1 if $vm_stat[0] =~ m/page size of (\d+) bytes/;
    $pageins = (split(/\s+/,$vm_stat[3]))[9];
    $pageouts = (split(/\s+/,$vm_stat[3]))[10];
    return ($pageins*$pageouts*$pagesize)/1024;
}


sub mem_status {
    # Returns:
    #   number of bytes (free+cache)
    my $self = shift;
    # Cache for one second
    if(not defined $self->{'mem_status'} or
       $self->{'mem_status_cache_time'}+$self->{'recheck'} < time) {
	$self->{'mem_status'} = mem_status_linux() if $^O ne 'darwin';
	$self->{'mem_status'} = mem_status_darwin() if $^O eq 'darwin';
	$self->{'mem_status_cache_time'} = time;
    }
    ::debug("mem_status: $self->{'mem_status'}\n");
    return $self->{'mem_status'};
}


sub mem_status_linux {
    #              total       used       free     shared    buffers     cached
    # Mem:       3366496    2901664     464832          0     179228    1850692
    # -/+ buffers/cache:     871744    2494752
    # Swap:      6445476    1396860    5048616
    my @free = `free`;
    my $free = (split(/\s+/,$free[2]))[3];
    return $free*1024;
}

sub mem_status_darwin {
    # Mach Virtual Memory Statistics: (page size of 4096 bytes, cache hits 0%)
    #   free active   spec inactive   wire   faults     copy    0fill reactive  pageins  pageout
    # 298987 251463 162637    69437 265724 29730558   299022  2308237        1   110058        0
    # 298991 251479 162637    69437 265726       43        4       16        0        0        0
    my ($pagesize, $pages_free, $pages_speculative);
    my @vm_stat = `vm_stat 1 | head -n4`;
    $pagesize = $1 if $vm_stat[0] =~ m/page size of (\d+) bytes/;
    $pages_free = (split(/\s+/,$vm_stat[3]))[0];
    $pages_speculative = (split(/\s+/,$vm_stat[3]))[2];
    return ($pages_free+$pages_speculative)*$pagesize;
}


sub io_status {
    # Returns:
    #   max percent for all devices
    my $self = shift;
    # Cache for one second
    if(not defined $self->{'io_status'} or
       $self->{'io_status_cache_time'}+$self->{'recheck'} < time) {
	$self->{'io_status'} = io_status_linux() if $^O ne 'darwin';
	$self->{'io_status'} = io_status_darwin() if $^O eq 'darwin';
	$self->{'io_status_cache_time'} = time;
    }
    ::debug("io_status: $self->{'io_status'}\n");
    return $self->{'io_status'};
}


sub io_status_linux {
    # Device: rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
    # sda       0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    my @iostat_out = `LANG=C iostat -x 1 2`;
    # throw away all execpt the last Device:-section
    my @iostat;
    for(reverse @iostat_out) {
	/Device:/ and last;
	push @iostat, (split(/\s+/,$_))[13];
    }
    my $io = ::max(@iostat);
    return undef_as_zero($io)/10;
}

sub io_status_darwin {
    #           disk0           disk1           disk2
    #     KB/t tps  MB/s     KB/t tps  MB/s     KB/t tps  MB/s
    #    14.95  15  0.22    11.18  35  0.38     2.00   0  0.00
    #     0.00   0  0.00     0.00   0  0.00     0.00   0  0.00
    my @iostat_out = `LANG=C iostat -d -w 1 -c 2`;
    # return the MB/s of the last second (not the %util)
    my @iostat = split(/\s+/, $iostat_out[3]);
    my $io = $iostat[3] + $iostat[6] + $iostat[9];
    return ::min($io, 10);
}

$::exitsignal = $::exitstatus = $opt::battery = 0; # Dummy

Youez - 2016 - github.com/yon3zu
LinuXploit