Loony Program
/* * 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); }