/* For memorial by double */ #include <stdio.h> #include <unistd.h> #include <termios.h> int get_choice(char * str, char ** menu, FILE * in, FILE * out); void check_redirect(void); int set_new_terminal_attr(struct termios * init_attr, struct termios * new_attr, int fd); int restore_terminal_attr(struct termios * init_attr, int fd); int main(void) { char * menu[] = { "a. Add", "c. Change", "d. Delete", NULL }; int choice; FILE * in_file, * out_file; struct termios init_termios, new_termios; check_redirect(); in_file = fopen("/dev/tty", "r"); out_file = fopen("/dev/tty", "w"); if (!in_file || !out_file) { fprintf(stderr, "Unable to open /dev/tty/n"); return 1; } set_new_terminal_attr(&init_termios, &new_termios, fileno(in_file)); do { choice = get_choice("Please Make Your Choice:", menu, in_file, out_file); fprintf(out_file, "/nYou have chosen: %c/n/n", choice); }while(choice != 'q'); restore_terminal_attr(&init_termios, fileno(in_file)); fclose(in_file); fclose(out_file); return 0; } int get_choice(char * str, char ** menu, FILE * in, FILE * out) { int choice; for (; *menu; ++menu) { fprintf(out, "%s/n", *menu); } fprintf(out, "%s", str); fflush(out); do { choice = fgetc(in); }while(choice == '/n' || choice == '/r'); return choice; } void check_redirect(void) { if (!isatty(fileno(stdout))) fprintf(stderr, "----------You are not a terminal----------/n"); return ; } int set_new_terminal_attr(struct termios * init_attr, struct termios * new_attr, int fd) { if(tcgetattr(fd, init_attr)) { fprintf(stderr, "tcgetattr error/n"); return 1; } * new_attr = * init_attr; new_attr->c_lflag &= ~ICANON; new_attr->c_lflag &= ~ECHO; /* signal must be ignored, in case user press ^C when program running, which will lost the initial setting*/ new_attr->c_lflag &= ~ISIG; /* This is important */ new_attr->c_cc[VMIN] = 1; new_attr->c_cc[VTIME] = 0; tcsetattr(fd, TCSAFLUSH, new_attr); return 0; } int restore_terminal_attr(struct termios * init_attr, int fd) { if (!tcsetattr(fd, TCSANOW, init_attr)) { return 0; } return 1; }