/*
* This is the loony process that picks siblings at random and tries to kill
* them. Otherwise it sleeps, and after it's done this a while it dies.
*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <iostream>
#include <fstream>
#include <array>
#include <vector>
#include <string>
#include "find_siblings.h"
using namespace std;
/*
* Error exit.
*/
void die(string descr, bool addsystem = true)
{
cerr << descr;
if(addsystem) cerr << ": " << strerror(errno);
cerr << endl;
exit(2);
}
/*
* Run this program with a string name on the command line which is used
* in printouts.
*/
int main(int argc, char **argv)
{
const char *name = argc > 1 ? argv[1] : "pgm";
// List of signals to send.
std::array<int,3> siglist = { SIGINT, SIGQUIT, SIGTERM };
// This keeps loonies from leaving core files when they die. It does
// this by setting the limit on the process' core file resource to zero.
// This change effects only this process. (It would also effect its
// children if it created any.)
struct rlimit none = { 0, 0 };
setrlimit(RLIMIT_CORE, &none);
// Make the loonies behave differently.
srandom(time(0)+getpid());
// Choose a liftime, ms.
int life = random() % 6000 + 2000;
while(1) {
// How long before we kill something (ms)?
int sleepy = random() % 2500 + 500;
// If we're not going to live that long, go ahead and
// croak now.
if(sleepy > life) break;
life -= sleepy;
// Now I'm going to go to sleep for a while
struct timespec ts = { sleepy / 1000, 1000000*(sleepy%1000) };
nanosleep(&ts, 0);
// Pick someone to kill. If there isn't anyone, go back
// to sleep.
vector<pid_t> sibs = siblings();
if(sibs.size() == 0) continue;
pid_t victim = sibs[random() % sibs.size()];
// Choose a signal to send.
int bullet = siglist[random() % siglist.size()];
cout << name << " throwing " << strsignal(bullet) << " at "
<< (int)victim << endl;
kill(victim, bullet);
// See if it's time to do some other stupid thing.
// May divide by zero.
int z = 100 / (random() % 10);
// One chance in 10 to make an illegal memory reference.
if(random() % 10 == 1) *(char *)19 = 71;
}
// If we actually made it this far, choose an exit code.
// The calculation gives about 50% chance of a normal exit code
// (zero), otherwise some exit code 1-10.
int code = random() % 20;
if(code > 10) code = 0;
cout << name << " exiting code " << code << "." << endl;
exit(code);
}