2

Command processor with line arguments

  1. /*
  2.  * Improved command processor with line arguments.
  3.  *
  4.  *   getopt
  5.  */
  6.  
  7. #include <sys/select.h>
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <strings.h>
  12. #include <errno.h>
  13. #if defined( LINUX )
  14. #include <string.h>
  15. #endif
  16.  
  17. #include <signal.h>
  18.  
  19. #include <unistd.h>
  20.  
  21. #include "debug.h"
  22.  
  23. #if defined( DEBUG )
  24. int debug = 0;
  25. #endif
  26.  
  27. #define PROMPT  "? "
  28.  
  29. struct {
  30.     char *kbd_prompt;
  31. } app;
  32.  
  33. void prompt() {
  34.     fputs( app.kbd_prompt, stdout );
  35. }
  36.  
  37. void usage() {
  38.     static struct _help {
  39.         char *cmd, *desc;
  40.     } *p, help[] = {
  41.             "echo", "text",
  42. #if defined( DEBUG )
  43.             "debug", "[0-9]",
  44. #endif
  45.             "quit", "", };
  46.  
  47.     for ( p = help; p < help + sizeof(help) / sizeof(struct _help); ++p )
  48.         fprintf( stdout, "%s %s\n", p->cmd, p->desc );
  49. }
  50.  
  51. void intr( int sig ) {
  52.     ONDEBUG9( fprintf( stdout, "<sig=%i>\n", sig ); );
  53.     signal(sig, intr); /* catch again */
  54. }
  55.  
  56. void startup() {
  57.     signal(SIGHUP, intr);
  58.     signal(SIGINT, intr);
  59.     signal(SIGTERM, intr);
  60.  
  61.     prompt();
  62. }
  63.  
  64. void read_input() {
  65.     char line[4096];
  66.     char *tok;
  67.  
  68.     if (fgets(line, sizeof(line), stdin) == 0)
  69.         exit(0);
  70.     /* command? */
  71.     if ( (tok = strtok(line, " \t\n")) ) {
  72.         ONDEBUG5( fprintf( stdout, "[%s]\n", tok ); );
  73.         if (tok[0] == 'q' && (tok[1] == '\0' || strcmp(tok, "quit") == 0))
  74.             exit(0);
  75. #if defined( DEBUG )
  76.         if ( tok[ 0 ] == 'd' && (tok[ 1 ] == '\0' || strcmp( tok, "debug" ) == 0) ) {
  77.             tok = strtok( 0, " \t\n" );
  78.             if ( tok )
  79.                 debug = atoi( tok );
  80.             else
  81.                 fprintf( stdout, "%i\n", debug );
  82.         }
  83. #endif
  84.         else if (tok[0] == 'e' && (tok[1] == '\0' || strcmp(tok, "echo") == 0))
  85.             fputs(line + strlen(tok) + 1, stdout);
  86.         else
  87.             usage();
  88.     }
  89.     prompt();
  90. }
  91.  
  92. void main_loop() {
  93.     fd_set read_fds;
  94.     int n_fds = FD_SETSIZE;
  95.  
  96.     for (;;) { /* forever */
  97.         FD_ZERO(&read_fds);
  98.  
  99.         /* standard input? */
  100.         FD_SET(0, &read_fds);
  101.  
  102.         switch (select(n_fds, &read_fds, 0, 0, 0)) {
  103.         case -1:    /* trouble */
  104.             ONDEBUG8(fprintf(stdout, "<errno=%i>\n", errno));
  105.             if (errno != EINTR) {
  106.                 fprintf(stderr, "%s\n", strerror(errno));
  107.                 exit( errno);
  108.             }
  109.             break;
  110.         case 0:     /* time out */
  111.             break;
  112.         default:    /* event */
  113.             if (FD_ISSET(0, &read_fds))
  114.                 read_input(); /* from operator */
  115.             break;
  116.         }
  117.     }
  118. }
  119.  
  120. int main(int argc, char **argv) {
  121.     extern int opterr;
  122.  
  123.     int c;
  124.  
  125.     app.kbd_prompt = PROMPT;
  126.  
  127.     opterr = 0;
  128.  
  129. #if defined( DEBUG )
  130.     while ( (c = getopt( argc, argv, "D:P:" )) != -1 )
  131. #else
  132.     while ((c = getopt(argc, argv, "P:")) != -1)
  133. #endif
  134.     switch (c) {
  135. #if defined( DEBUG )
  136.     case 'D':
  137.         debug = atoi( optarg );
  138.         break;
  139. #endif
  140.     case 'P':
  141.         app.kbd_prompt = optarg;
  142.         break;
  143.     default:
  144. #if defined( DEBUG )
  145.         fprintf( stderr, "%s [-D level] [-P prompt]\n", argv[ 0 ] );
  146. #else
  147.         fprintf(stderr, "%s [-P prompt]\n", argv[0]);
  148. #endif
  149.         exit(1);
  150.     }
  151.  
  152.     setbuf(stdout, 0);
  153.  
  154.     startup();
  155.     main_loop();
  156. }

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].