10

Example program

  1. #include <sys/select.h>
  2.  
  3. #include <stdlib.h>
  4. #include <strings.h>
  5. #include <signal.h>
  6. #include <errno.h>
  7. #include <time.h>
  8.  
  9. #include <getopt.h>
  10.  
  11. #include <errno.h>
  12.  
  13. #include "scheduler.h"
  14. #include "task.h"
  15. #include "debug.h"
  16. #include "shell.h"
  17.  
  18. #if defined( DEBUG )
  19. int debug = 0;
  20. #endif
  21.  
  22. struct _tictac {
  23.     shell shell;
  24.     scheduler sched;
  25.     task t1, t2, t3;
  26. } tictac;
  27.  
  28. static int tic_tac_is_started( ) {
  29.     return tictac.t1 && tictac.t2 && task_isqueued( tictac.t1 ) && task_isqueued( tictac.t2 );
  30. }
  31.  
  32. static void tic_tac( char *s ) {
  33.     time_t clock = time( (time_t *)0 );
  34.     struct tm *tm = localtime( &clock );
  35.  
  36.     fprintf( stdout, "\007%s", s ); /* beep */
  37.     fprintf( stdout, "%02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec );
  38.     fflush( stdout );
  39. }
  40.  
  41. static void tic_tac_start( int period, int count ) {
  42.     if ( !tic_tac_is_started() ) {
  43.         time_t now = time( 0 );
  44.         task t1 = tictac.t1, t2 = tictac.t2;
  45.  
  46.         /* lazy init */
  47.         if ( !t1 )
  48.             tictac.t1 = t1 = task_new( "TIC", 0, 0, 0, (void (*)( void * ))tic_tac, "<tic>" );
  49.         if ( !t2 )
  50.             tictac.t2 = t2 = task_new( "TAC", 0, 0, 0, (void (*)( void * ))tic_tac, "<tac>" );
  51.  
  52.         task_setattime( t1, now + period);
  53.         task_setattime( t2, now + (2 * period));
  54.  
  55.         task_setperiod( t1, (2 * period)), task_setcount( t1, count );
  56.         task_setperiod( t2, (2 * period)), task_setcount( t2, count );
  57.  
  58.         scheduler_addtask( tictac.sched, t1 );
  59.         scheduler_addtask( tictac.sched, t2 );
  60.     }
  61. }
  62.  
  63. static void tic_tac_stop( char *reason ) {
  64.     if ( tic_tac_is_started() ) {
  65.         scheduler_rmtask( tictac.sched, tictac.t1 );
  66.         scheduler_rmtask( tictac.sched, tictac.t2 );
  67.  
  68.         /* if interrupted, check for a queued stop */
  69.         if ( tictac.t3 && task_isqueued( tictac.t3 ) )
  70.             scheduler_rmtask( tictac.sched, tictac.t3 );
  71.  
  72.         if ( reason ) {
  73.             fprintf( stdout, "%s\n", reason );
  74.             fflush( stdout );
  75.         }
  76.     }
  77. }
  78.  
  79. static void tic_tac_handle_signal( int sig ) {
  80.     signal( sig, tic_tac_handle_signal ); /* catch again */
  81.     tic_tac_stop( "<interrupted>");
  82. }
  83.  
  84. static void cmd_start( int argc, char **argv ) {
  85.     int period = 1, count = 0; /* every sec forever */
  86.  
  87.     switch( argc ) {
  88.     case 3:
  89.         count = atoi( argv[ 2 ] );
  90.         /* fall thru */
  91.     case 2:
  92.         period = atoi( argv[ 1 ] );
  93.         if ( period == 0 )
  94.             period = 1;
  95.         break;
  96.     case 1:
  97.     default:
  98.         break;
  99.     }
  100.     tic_tac_start( period, count );
  101. }
  102.  
  103. static void cmd_stop( int argc, char **argv ) {
  104.     int delay = 0; /* kill by default */
  105.     time_t now = time( 0 );
  106.  
  107.     switch( argc ) {
  108.     case 2:
  109.         delay = atoi( argv[ 1 ] );
  110.         break;
  111.     case 1:
  112.     default:
  113.         break;
  114.     }
  115.     if ( tictac.t3 && task_isqueued( tictac.t3 ))   /* being stopped */
  116.         scheduler_rmtask( tictac.sched, tictac.t3 );
  117.     if ( !tictac.t3 )
  118.         tictac.t3 = task_new( "STOP", 0, 0, 0, (void (*)( void * ))tic_tac_stop, "<stopped>" );
  119.     task_setattime( tictac.t3, now + delay );
  120.     scheduler_addtask( tictac.sched, tictac.t3 );
  121. }
  122.  
  123. static void cmd_quit( int argc, char **argv ) {
  124.     exit( 0 );
  125. }
  126.  
  127. #if defined( DEBUG )
  128.  
  129. #include "debug.h"
  130.  
  131. static void cmd_debug( int argc, char **argv ) {
  132.     switch ( argc ) {
  133.     case 2:
  134.         debug = atoi( argv[ 1 ] );
  135.         break;
  136.     case 1:
  137.         fprintf( stdout, "%i\n", debug );
  138.         break;
  139.     default:
  140.         fprintf( stderr, "%s [level]\n", argv[ 0 ] );
  141.         break;
  142.     }
  143. }
  144.  
  145. #endif
  146.  
  147. void main_loop( ) {
  148.     fd_set read_fds;
  149.     int n_fds = 1;
  150.  
  151.     struct timeval time_out, *tp = 0;
  152.     time_t next_time;
  153.  
  154.     long delay = 0L;
  155.  
  156.     for ( ;; ) {    /* forever */
  157.         FD_ZERO( &read_fds );
  158.         FD_SET( 0, &read_fds );
  159.  
  160.         switch( select( n_fds, &read_fds, 0, 0, tp )) {
  161.         case -1:    /* trouble */
  162.             if( errno != EINTR )
  163.                 exit( 1 );
  164.             break;
  165.         case 0: /* time out */
  166.             break;
  167.         default:    /* event */
  168.             if( FD_ISSET( 0, &read_fds ))
  169.                 shell_input( tictac.shell, 0 );
  170.             break;
  171.         }
  172.         /* anything else to do ? */
  173.         if( (next_time = scheduler_run( tictac.sched )) ) {
  174.             /* wake up for next job on schedule */
  175.             if( (delay = next_time - time( (time_t *)0 )) < 0 )
  176.                 delay = 0;  /* just to be sure */
  177.             ONDEBUG1( printf( "[delay=%ld]\n", delay ));
  178.             time_out.tv_sec = delay;
  179.             time_out.tv_usec = 0L;
  180.             tp = &time_out;
  181.         }
  182.         else
  183.             tp = 0;
  184.     }
  185. }
  186.  
  187. int main( int argc, char **argv ) {
  188.     extern int opterr;
  189.     int c;
  190.  
  191.     tictac.shell = shell_new( );
  192.     tictac.sched = scheduler_new( );
  193.  
  194.     opterr = 0;
  195.  
  196. #if defined( DEBUG )
  197.     while ( (c = getopt( argc, argv, "D:" )) != -1 )
  198. #else
  199.     while ( (c = getopt( argc, argv, "" )) != -1 )
  200. #endif
  201.         switch ( c ) {
  202. #if defined( DEBUG )
  203.         case 'D':
  204.             debug = atoi( optarg );
  205.             break;
  206. #endif
  207.         case '?':
  208.         default:
  209. #if defined( DEBUG )
  210.             fprintf( stderr, "%s [-D level]\n", argv[ 0 ] );
  211. #else
  212.             fprintf( stderr, "%s\n", argv[ 0 ] );
  213. #endif
  214.             exit( 1 );
  215.         }
  216.  
  217.     shell_addcmd( tictac.shell, "start",    "start [period] [count]",   cmd_start );
  218.     shell_addcmd( tictac.shell, "stop",     "stop [delay]",             cmd_stop );
  219. #if defined( DEBUG )
  220.     shell_addcmd( tictac.shell, "debug",    "debug [level]",            cmd_debug );
  221. #endif
  222.     shell_addcmd( tictac.shell, "quit",     "quit | exit",              cmd_quit );
  223.     shell_addcmd( tictac.shell, "exit",     "exit | quit",              cmd_quit );
  224.  
  225.     /* catch ^C */
  226.     signal( SIGINT, tic_tac_handle_signal );
  227.  
  228. #if defined( DEBUG )
  229.     setbuf( stdout, 0 );
  230. #endif
  231.  
  232.     main_loop( );
  233. }

To compile the program:

$ make tictac
gcc -Wall -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c list.c
gcc -Wall -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c shell.c
gcc -Wall -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c task.c
gcc -Wall -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c scheduler.c
gcc -Wall -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c dump.c
ar rc libctk.a list.o shell.o task.o scheduler.o dump.o
gcc -Wall -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c tictac.c
gcc tictac.o -o tictac libctk.a -lreadline

Comments

Your comment:
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip help 2000

Enter a maximum of 2000 characters.
Improve the presentation of your text with the following formatting tags:
[p]paragraph[/p], [b]bold[/b], [i]italics[/i], [u]underline[/u], [s]strike[/s], [quote]citation[/quote], [pre]as is[/pre], [br]line break,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]command[/code], [code=language]source code in c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].