]> git.donarmstrong.com Git - infobot.git/blobdiff - src/Shm.pl
- berkeley dbm support now works! thanks to tim riker.
[infobot.git] / src / Shm.pl
index 6811ff458e26a91a8ef491eb258aaf1819e8385d..ab7e9964538e7549481d5489388b933993a39296 100644 (file)
@@ -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;
@@ -126,10 +153,15 @@ sub addForked {
        my $time        = $forked{$name}{Time};
        my $continue    = 0;
 
-       &DEBUG("PID => $forked{$name}{PID}");
+       $continue++ if ($forked{$name}{PID} == $$);
 
-       if (-d "/proc/$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;
@@ -137,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;
@@ -146,6 +180,7 @@ sub addForked {
     }
 
     $forked{$name}{Time}       = time();
+    $forked{$name}{PID}                = $$;
     $forkedtime                        = time();
     $count{'Fork'}++;
     return 1;
@@ -180,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;