/***********************************************\ * randsleep.c * * * * Sleep for a random amount of time * * * * http://www.linuxtech.ie/ * * * \***********************************************/ /**** * Sleep for a random amount of seconds within bounds. ****/ #include #include #include #include #include #include #include #include #include #include #include #include /***** * Random sleep interrupt handler. As soon as we receive the SIGALARM * interrupt exit the whole program. * The 'count' variable isn't used, it's just to satisfy Xcode building *****/ static void rshandler(int count) { count = 0 ; exit(0) ; } static void Usage(char *CmdName) { fprintf(stderr,"Usage: %s [-v] [seconds upper limit]\n",CmdName) ; fprintf(stderr,"Sleep for a random time between two values.\nIf only one value is specified sleep for that numner of seconds.\n") ; } static void randsleep(double Seconds) { struct itimerval rttimer ; struct itimerval old_rttimer ; unsigned long SecondsInt = (int)Seconds ; unsigned long SecondsMicro = (int)((Seconds-(int)Seconds)*10E5) ; // Trap SIGALRM signal(SIGALRM,rshandler) ; // Tell it when to send the first signal (the only one we're interested in) rttimer.it_value.tv_sec = SecondsInt ; rttimer.it_value.tv_usec = SecondsMicro ; // Tell it when to send subsequent signals. This isn't used in this // code but I didn't want to leave the values unset. rttimer.it_interval.tv_sec = 1 ; rttimer.it_interval.tv_usec = 0 ; setitimer(ITIMER_REAL,&rttimer,&old_rttimer); // Do an ordinary sleep which is guaranteed to be longer than the sleep // we really want. If we didn't have this the code would simply exit. sleep(10+SecondsInt) ; } int main(int argc,char *argv[]) { ushort Verbose=0,ErrorFlag=0 ; /************** Start argument parsing **************/ char optchar,**shift_argv ; int shift_argc ; while((optchar = getopt(argc,argv,"v")) != EOF) switch(optchar) { // If '-v' is specified output the length of the random sleep case 'v': Verbose = 1 ; break ; case '?': ErrorFlag = 1 ; } shift_argc = argc-optind ; shift_argv = &argv[optind] ; // Now the first non-opt argument will be at 0 /************** Finished argument parsing **************/ if(ErrorFlag || shift_argc<1 || shift_argc>2) Usage(argv[0]) ; else { float LowerVal,UpperVal,Handle ; double RandFloat,SleepTime ; unsigned long RandInt=0 ; // Just to be on the safe side. LowerVal = atof(shift_argv[0]) ; if(shift_argc==2) UpperVal = atof(shift_argv[1]) ; else UpperVal = LowerVal ; // If the values are the same then just sleep for that time if(LowerVal==UpperVal) { SleepTime = LowerVal ; } else { // If the arguments are the wrong way around just swap them. if(LowerVal>=UpperVal) { int SwapVals ; // Swap the values SwapVals = LowerVal ; LowerVal = UpperVal ; UpperVal = SwapVals ; } Handle = open("/dev/random",O_RDONLY) ; read(Handle,&RandInt,4) ; // Read 4 random bytes (32 bit) into our unsigned long close(Handle) ; // Divide the random integer by the largest possible 32-bit number RandFloat = (double)RandInt/pow(2,32) ; SleepTime = LowerVal+(UpperVal-LowerVal)*RandFloat ; } if(Verbose) printf("Sleeping for %0.2f seconds\n",SleepTime) ; // Now that we have computed the random value do the sleep itself. randsleep(SleepTime) ; } return(0) ; }