home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / mtools_3.6.src.lzh / MTOOLS_3.6 / tty.c < prev    next >
C/C++ Source or Header  |  1997-11-13  |  4KB  |  195 lines

  1. #include "sysincludes.h"
  2. #include "mtools.h"
  3.  
  4. static FILE *tty=NULL;
  5. static int notty=0;    
  6. static int ttyfd=-1;
  7. static int tty_mode = -1; /* 1 for raw, 0 for cooked, -1 for initial */
  8. static int need_tty_reset = 0;
  9. static int handlerIsSet = 0;
  10. int    mtools_raw_tty = 1;
  11.  
  12.  
  13. #ifdef TCSANOW
  14.  
  15. /* we have tcsetattr & tcgetattr. Good */
  16. #define stty(a,b)        (void)tcsetattr(a,TCSANOW,b)
  17. #define gtty(a,b)        (void)tcgetattr(a,b)
  18. #ifdef TCIFLUSH
  19. #define discard_input(a) tcflush(a,TCIFLUSH)
  20. #else
  21. #define discard_input(a) /**/
  22. #endif
  23.  
  24. #else /* TCSANOW */
  25.  
  26. #ifndef TCSETS
  27. #define TCSETS TCSETA
  28. #define TCGETS TCGETA
  29. #define termios termio
  30. #endif
  31.  
  32. #define stty(a,b) (void)ioctl(a,TCSETS,(char *)b)
  33. #define gtty(a,b) (void)ioctl(a,TCGETS,(char *)b)
  34.  
  35. #ifdef TCIFLUSH
  36. #define discard_input(a) (void)ioctl(a,TCFLSH,TCIFLUSH)
  37. #else
  38. #define discard_input(a) /**/
  39. #endif
  40.  
  41. #endif /* TCSANOW */
  42.  
  43. #define restore_tty(a) stty(STDIN,a)
  44.  
  45.  
  46. #define STDIN ttyfd
  47. #define FAIL (-1)
  48. #define DONE 0
  49. #ifndef _OSK
  50. static struct termios in_orig;
  51. #endif
  52.  
  53. /*--------------- Signal Handler routines -------------*/
  54.  
  55. static void tty_time_out(void)
  56. {
  57.     int exit_code;
  58. #ifndef _OSK
  59.     signal(SIGALRM, SIG_IGN);
  60.     if(tty && need_tty_reset)
  61.         restore_tty (&in_orig);    
  62. #if future
  63.     if (fail_on_timeout)
  64.         exit_code=SHFAIL;
  65.     else {
  66.         if (default_choice && mode_defined) {
  67.             if (yes_no) {
  68.                 if ('Y' == default_choice)
  69.                     exit_code=0;
  70.                 else
  71.                     exit_code=1;
  72.             } else
  73.                 exit_code=default_choice-minc+1;
  74.         } else
  75.             exit_code=DONE;
  76.     }
  77. #else
  78.     exit_code = DONE;
  79. #endif
  80. #else
  81.     exit_code = DONE;
  82. #endif
  83.     exit(exit_code);
  84. }
  85.  
  86. static void cleanup_tty(void)
  87. #ifndef _OSK
  88.     if(tty && need_tty_reset) {
  89.         restore_tty (&in_orig);
  90.         signal (SIGHUP, SIG_IGN);
  91.         signal (SIGINT, SIG_IGN);
  92.         signal (SIGTERM, SIG_IGN);
  93.         signal (SIGALRM, SIG_IGN);
  94.     }
  95. #endif
  96. }
  97.  
  98. static void fail(void)
  99. {
  100.     exit(1);
  101. }
  102.  
  103. static void set_raw_tty(int mode)
  104. {
  105. #ifndef _OSK
  106.     struct termios in_raw;
  107.  
  108.     if(mode != tty_mode && mode != -1) {
  109.         /* Determine existing TTY settings */
  110.         gtty (STDIN, &in_orig);
  111.         need_tty_reset = 1;
  112.         if(!handlerIsSet) {
  113.             atexit(cleanup_tty);
  114.             handlerIsSet = 1;
  115.         }
  116.  
  117.         /*------ Restore original TTY settings on exit --------*/
  118.         signal (SIGHUP, (SIG_CAST) fail);
  119.         signal (SIGINT, (SIG_CAST) fail);
  120.         signal (SIGTERM, (SIG_CAST) fail);
  121.         signal (SIGALRM, (SIG_CAST) tty_time_out);
  122.     
  123.         /* Change STDIN settings to raw */
  124.  
  125.         gtty (STDIN, &in_raw);
  126.         if(mode) {
  127.             in_raw.c_lflag &= ~ICANON;
  128.             in_raw.c_cc[VMIN]=1;
  129.             in_raw.c_cc[VTIME]=0;
  130.             stty (STDIN, &in_raw);
  131.         } else {
  132.             in_raw.c_lflag |= ICANON;
  133.             stty (STDIN, &in_raw);
  134.         }
  135.         tty_mode = mode;
  136.         discard_input(STDIN);
  137.     }
  138. #endif
  139. }
  140.  
  141. FILE *opentty(int mode)
  142. {
  143. #ifndef _OSK
  144.     if(notty)
  145.         return NULL;
  146. /* BeOS does not have a working /dev/tty, so we use stdin */
  147. #ifndef __BEOS__
  148.     if (tty == NULL) {
  149.         ttyfd = open("/dev/tty", O_RDONLY);
  150.         if(ttyfd >= 0) {
  151.             tty = fdopen(ttyfd, "r");
  152.         }
  153.     }
  154. #endif
  155.     if  (tty == NULL){
  156.         if ( !isatty(0) ){
  157.             notty = 1;
  158.             return NULL;
  159.         }
  160.         ttyfd = 0;
  161.         tty = stdin;
  162.     }
  163.  
  164.     set_raw_tty(mode);
  165.     return tty;
  166. #else
  167.     return stdin;
  168. #endif
  169. }
  170.  
  171. int ask_confirmation(const char *format, const char *p1, const char *p2)
  172. {
  173.     char ans[10];
  174.  
  175.     if(!opentty(-1))
  176.         return 0;
  177.  
  178.     while (1) {
  179.         fprintf(stderr, format, p1, p2);
  180.         fflush(stderr);
  181.         fflush(opentty(-1));
  182.         if (mtools_raw_tty) {
  183.             ans[0] = fgetc(opentty(1));
  184.             fputs("\n", stderr);
  185.         } else {
  186.             fgets(ans,9, opentty(0));
  187.         }
  188.         if (ans[0] == 'y' || ans[0] == 'Y')
  189.             return 0;
  190.         if (ans[0] == 'n' || ans[0] == 'N')
  191.             return -1;
  192.     }
  193. }
  194.