play_again_extended.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /* play_again4.c
  2. * purpose: ask if user wants another transaction
  3. * method: set tty into chr-by-chr, no-echo mode
  4. * set tty into no-delay mode
  5. * read char, return result
  6. * resets terminal modes on SIGINT, ignores SIGQUIT
  7. * returns: 0=>yes, 1=>no, 2=>timeout
  8. * better: reset terminal mode on Interrupt
  9. */
  10. #include <stdio.h>
  11. #include <termios.h>
  12. #include <fcntl.h>
  13. #include <string.h>
  14. #include <signal.h>
  15. #include <time.h>
  16. #define ASK "Do you want another transaction"
  17. #define TRIES 3 /* max tries */
  18. #define SLEEPTIME 2 /* time per try */
  19. #define BEEP putchar('\a') /* alert user */
  20. main()
  21. {
  22. int response;
  23. void ctrl_c_handler(int);
  24. tty_mode(0); /* save current mode */
  25. set_cr_noecho_mode(); /* set -icanon, -echo */
  26. set_nodelay_mode(); /* noinput => EOF */
  27. signal( SIGINT, ctrl_c_handler ); /* handle INT */
  28. signal( SIGQUIT, SIG_IGN ); /* ignore QUIT signals */
  29. response = get_response(ASK, TRIES); /* get some answer */
  30. tty_mode(1); /* reset orig mode */
  31. return response;
  32. }
  33. get_response( char *question , int maxtries)
  34. /*
  35. * purpose: ask a question and wait for a y/n answer or timeout
  36. * method: use getchar and complain about non-y/n input
  37. * returns: 0=>yes, 1=>no
  38. */
  39. {
  40. int input;
  41. printf("%s (y/n)?", question); /* ask */
  42. fflush(stdout); /* force output */
  43. //while ( 1 ){
  44. //sleep(SLEEPTIME); /* wait a bit */
  45. input = tolower(get_ok_char()); /* get next chr */
  46. if ( input == 'y' )
  47. return 0;
  48. if ( input == 'n' )
  49. return 1;
  50. if ( maxtries-- == 0 ) /* outatime? */
  51. return 2; /* sayso */
  52. BEEP;
  53. //}
  54. }
  55. /*
  56. * skip over non-legal chars and return y,Y,n,N or EOF
  57. */
  58. get_ok_char()
  59. {
  60. int c = 0;
  61. time_t keypressed_time = time(0);
  62. printf("\nkeypressed time first update: %d\n", keypressed_time);
  63. //while( ( c = getchar() ) != EOF && strchr("yYnN",c) == NULL ){
  64. while(1){
  65. if( (c=getchar()) != EOF ){ // a key is pressed{
  66. keypressed_time = time(0);
  67. //printf("Key pressed: %x\n", c);
  68. putchar(c);
  69. //printf("keypressed time 2: %d\n", keypressed_time);
  70. }
  71. //if( strchr("yYnN", c) != NULL ){
  72. // printf("Key pressed: %c\n", c);
  73. // return c;
  74. //}
  75. if(keypressed_time + 3 < time(0) ){ //wait 3 seconds
  76. printf("\ncurrent time : %d\n", time(0));
  77. printf("keypressed time 2: %d\n", keypressed_time);
  78. return 'n';
  79. }
  80. }
  81. ;
  82. return c;
  83. }
  84. set_cr_noecho_mode()
  85. /*
  86. * purpose: put file descriptor 0 into chr-by-chr mode and noecho mode
  87. * method: use bits in termios
  88. */
  89. {
  90. struct termios ttystate;
  91. tcgetattr( 0, &ttystate); /* read curr. setting */
  92. ttystate.c_lflag &= ~ICANON; /* no buffering */
  93. ttystate.c_lflag &= ~ECHO; /* no echo either */
  94. ttystate.c_cc[VMIN] = 1; /* get 1 char at a time */
  95. tcsetattr( 0 , TCSANOW, &ttystate); /* install settings */
  96. }
  97. set_nodelay_mode()
  98. /*
  99. * purpose: put file descriptor 0 into no-delay mode
  100. * method: use fcntl to set bits
  101. * notes: tcsetattr() will do something similar, but it is complicated
  102. */
  103. {
  104. int termflags;
  105. termflags = fcntl(0, F_GETFL); /* read curr. settings */
  106. termflags |= O_NDELAY; /* flip on nodelay bit */
  107. fcntl(0, F_SETFL, termflags); /* and install 'em */
  108. }
  109. /* how == 0 => save current mode, how == 1 => restore mode */
  110. /* this version handles termios and fcntl flags */
  111. tty_mode(int how)
  112. {
  113. static struct termios original_mode;
  114. static int original_flags;
  115. static int stored = 0;
  116. if ( how == 0 ){
  117. tcgetattr(0, &original_mode);
  118. original_flags = fcntl(0, F_GETFL);
  119. stored = 1;
  120. }
  121. else if ( stored ) {
  122. tcsetattr(0, TCSANOW, &original_mode);
  123. fcntl( 0, F_SETFL, original_flags);
  124. }
  125. }
  126. void ctrl_c_handler(int signum)
  127. /*
  128. * purpose: called if SIGINT is detected
  129. * action: reset tty and scram
  130. */
  131. {
  132. tty_mode(1);
  133. exit(2);
  134. }