8
Processeur de commandes avec des arguments
- /*
- * Improved command processor with line arguments.
- *
- * getopt
- */
- #include <sys/select.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <strings.h>
- #include <errno.h>
- #if defined( LINUX )
- #include <string.h>
- #endif
- #include <signal.h>
- #include <unistd.h>
- #include "debug.h"
- #if defined( DEBUG )
- int debug = 0;
- #endif
- #define PROMPT "? "
- struct {
- char *kbd_prompt;
- } app;
- void prompt() {
- fputs( app.kbd_prompt, stdout );
- }
- void usage() {
- static struct _help {
- char *cmd, *desc;
- } *p, help[] = {
- "echo", "text",
- #if defined( DEBUG )
- "debug", "[0-9]",
- #endif
- "quit", "", };
- for ( p = help; p < help + sizeof(help) / sizeof(struct _help); ++p )
- fprintf( stdout, "%s %s\n", p->cmd, p->desc );
- }
- void intr( int sig ) {
- ONDEBUG9( fprintf( stdout, "<sig=%i>\n", sig ); );
- signal(sig, intr); /* catch again */
- }
- void startup() {
- signal(SIGHUP, intr);
- signal(SIGINT, intr);
- signal(SIGTERM, intr);
- prompt();
- }
- void read_input() {
- char line[4096];
- char *tok;
- if (fgets(line, sizeof(line), stdin) == 0)
- exit(0);
- /* command? */
- if ( (tok = strtok(line, " \t\n")) ) {
- ONDEBUG5( fprintf( stdout, "[%s]\n", tok ); );
- if (tok[0] == 'q' && (tok[1] == '\0' || strcmp(tok, "quit") == 0))
- exit(0);
- #if defined( DEBUG )
- if ( tok[ 0 ] == 'd' && (tok[ 1 ] == '\0' || strcmp( tok, "debug" ) == 0) ) {
- tok = strtok( 0, " \t\n" );
- if ( tok )
- debug = atoi( tok );
- else
- fprintf( stdout, "%i\n", debug );
- }
- #endif
- else if (tok[0] == 'e' && (tok[1] == '\0' || strcmp(tok, "echo") == 0))
- fputs(line + strlen(tok) + 1, stdout);
- else
- usage();
- }
- prompt();
- }
- void main_loop() {
- fd_set read_fds;
- int n_fds = FD_SETSIZE;
- for (;;) { /* forever */
- FD_ZERO(&read_fds);
- /* standard input? */
- FD_SET(0, &read_fds);
- switch (select(n_fds, &read_fds, 0, 0, 0)) {
- case -1: /* trouble */
- ONDEBUG8(fprintf(stdout, "<errno=%i>\n", errno));
- if (errno != EINTR) {
- fprintf(stderr, "%s\n", strerror(errno));
- exit( errno);
- }
- break;
- case 0: /* time out */
- break;
- default: /* event */
- if (FD_ISSET(0, &read_fds))
- read_input(); /* from operator */
- break;
- }
- }
- }
- int main(int argc, char **argv) {
- extern int opterr;
- int c;
- app.kbd_prompt = PROMPT;
- opterr = 0;
- #if defined( DEBUG )
- while ( (c = getopt( argc, argv, "D:P:" )) != -1 )
- #else
- while ((c = getopt(argc, argv, "P:")) != -1)
- #endif
- switch (c) {
- #if defined( DEBUG )
- case 'D':
- debug = atoi( optarg );
- break;
- #endif
- case 'P':
- app.kbd_prompt = optarg;
- break;
- default:
- #if defined( DEBUG )
- fprintf( stderr, "%s [-D level] [-P prompt]\n", argv[ 0 ] );
- #else
- fprintf(stderr, "%s [-P prompt]\n", argv[0]);
- #endif
- exit(1);
- }
- setbuf(stdout, 0);
- startup();
- main_loop();
- }
Commentaires