X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=src%2FShm.pl;h=ab7e9964538e7549481d5489388b933993a39296;hb=5f0f5db69087b1279da54b14a62b743a99bc10f9;hp=136bd165b26544daa7a22725c4f37b69af5c8701;hpb=fdfb72946d2c37b39fbe7800ca5d3a91932cc41c;p=infobot.git diff --git a/src/Shm.pl b/src/Shm.pl index 136bd16..ab7e996 100644 --- a/src/Shm.pl +++ b/src/Shm.pl @@ -5,14 +5,17 @@ # Created: 20000124 # -if (&IsParam("useStrict")) { use strict; } - use POSIX qw(_exit); sub openSHM { my $IPC_PRIVATE = 0; my $size = 2000; + if (&IsParam("noSHM")) { + &status("Created shared memory: disabled. [bot may become unreliable]"); + return 0; + } + if (defined( $_ = shmget($IPC_PRIVATE, $size, 0777) )) { &status("Created shared memory (shm) key: [$_]"); return $_; @@ -40,6 +43,8 @@ sub shmRead { my $size = 3*80; my $retval = ''; + return '' if (&IsParam("noSHM")); + if (shmread($key,$retval,$position,$size)) { return $retval; } else { @@ -55,6 +60,8 @@ sub shmWrite { my $position = 0; my $size = 80*3; + return if (&IsParam("noSHM")); + # NULL hack. ### TODO: create shmClear to deal with this. if ($str !~ /^$/) { @@ -92,12 +99,32 @@ sub addForked { } foreach (keys %forked) { - my $time = time() - $forked{$_}{Time}; + my $n = $_; + my $time = time() - $forked{$n}{Time}; next unless ($time > $forker_timeout); ### TODO: use &time2string()? - &WARN("Fork: looks like we lost '$_', executed $time ago."); - delete $forked{$_}; + &WARN("Fork: looks like we lost '$n', executed $time ago"); + + my $pid = $forked{$n}{PID}; + if (!defined $pid) { + &WARN("Fork: no pid for $n."); + delete $forked{$n}; + next; + } + + # don't kill parent! + if ($pid == $$) { + &status("Fork: pid == \$\$ ($$)"); + next; + } + + if ( -d "/proc/$pid") { + &status("Fork: killing $name ($pid)"); + kill 9, $pid; + } + + delete $forked{$n}; } my $count = 0; @@ -117,12 +144,24 @@ sub addForked { $count++; } - if (exists $forked{$name}) { + if (exists $forked{$name} and !scalar keys %{ $forked{$name} }) { + &WARN("addF: forked{$name} exists but is empty; deleting."); + undef $forked{$name}; + } + + if (exists $forked{$name} and scalar keys %{ $forked{$name} }) { my $time = $forked{$name}{Time}; my $continue = 0; - if (-d "/proc/$forked{$name}{PID}") { + $continue++ if ($forked{$name}{PID} == $$); + + if ($continue) { + &WARN("hrm.. fork pid == mypid == $$; how did this happen?"); + + } elsif ( -d "/proc/$forked{$name}{PID}") { &status("fork: still running; good. BAIL OUT."); + return 0; + } else { &WARN("Found dead fork; removing and resetting."); $continue = 1; @@ -130,8 +169,10 @@ sub addForked { if ($continue) { # NOTHING. + } elsif (time() - $time > 900) { # stale fork > 15m. &status("forked: forked{$name} presumably exited without notifying us."); + } else { # fresh fork. &msg($who, "$name is already running ". &Time2String(time() - $time)); return 0; @@ -139,6 +180,7 @@ sub addForked { } $forked{$name}{Time} = time(); + $forked{$name}{PID} = $$; $forkedtime = time(); $count{'Fork'}++; return 1; @@ -154,6 +196,10 @@ sub delForked { POSIX::_exit(0); } + if ($name =~ /\.pl/) { + &WARN("dF: name is name of source file ($name). FIX IT!"); + } + &showProc(); # just for informational purposes. if (exists $forked{$name}) { @@ -169,4 +215,47 @@ sub delForked { POSIX::_exit(0); } +sub shmFlush { + return if ($$ != $::bot_pid); # fork protection. + + if (@_) { + &ScheduleThis(5, "shmFlush"); + return if ($_[0] eq "2"); + } + + my $time; + my $shmmsg = &shmRead($shm); + $shmmsg =~ s/\0//g; # remove padded \0's. + if ($shmmsg =~ s/^(\d+): //) { + $time = $1; + } + + foreach (split '\|\|', $shmmsg) { + next if (/^$/); + &VERB("shm: Processing '$_'.",2); + + if (/^DCC SEND (\S+) (\S+)$/) { + my ($nick,$file) = ($1,$2); + if (exists $dcc{'SEND'}{$who}) { + &msg($nick, "DCC already active."); + } else { + &DEBUG("shm: dcc sending $2 to $1."); + $conn->new_send($1,$2); + $dcc{'SEND'}{$who} = time(); + } + } elsif (/^SET FORKPID (\S+) (\S+)/) { + $forked{$1}{PID} = $2; + } elsif (/^DELETE FORK (\S+)$/) { + delete $forked{$1}; + } elsif (/^EVAL (.*)$/) { + &DEBUG("evaling '$1'."); + eval $1; + } else { + &DEBUG("shm: unknown msg. ($_)"); + } + } + + &shmWrite($shm,"") if ($shmmsg ne ""); +} + 1;