/* * CS354: Operating Systems. * Purdue University * Example that shows how to read one line with simple editing * using raw terminal. */ #include #include #include #include #define MAX_BUFFER_LINE 2048 extern void tty_raw_mode(void); // Buffer where line is stored int line_length; char line_buffer[MAX_BUFFER_LINE]; // Simple history array // This history does not change. // Yours have to be updated. int history_index = 0; char * history [] = { "ls -al | grep x", "ps -e", "cat read-line-example.c", "vi hello.c", "make", "ls -al | grep xxx | grep yyy" }; int history_length = sizeof(history)/sizeof(char *); void read_line_print_usage() { char * usage = "\n" " ctrl-? Print usage\n" " Backspace Deletes last character\n" " up arrow See last command in the history\n"; write(1, usage, strlen(usage)); } /* * Input a line with some basic editing. */ char * read_line() { // Set terminal in raw mode tty_raw_mode(); line_length = 0; // Read one line until enter is typed while (1) { // Read one character in raw mode. char ch; read(0, &ch, 1); if (ch>=32) { // It is a printable character. // Do echo write(1,&ch,1); // If max number of character reached return. if (line_length==MAX_BUFFER_LINE-2) break; // add char to buffer. line_buffer[line_length]=ch; line_length++; } else if (ch==10) { // was typed. Return line // Print newline write(1,&ch,1); break; } else if (ch == 31) { // ctrl-? read_line_print_usage(); line_buffer[0]=0; break; } else if (ch == 8) { // was typed. Remove previous character read. // Go back one character ch = 8; write(1,&ch,1); // Write a space to erase the last character read ch = ' '; write(1,&ch,1); // Go back one character ch = 8; write(1,&ch,1); // Remove one character from buffer line_length--; } else if (ch==27) { // Escape sequence. Read two chars more // // HINT: Use the program "keyboard-example" to // see the ascii code for the different chars typed. // char ch1; char ch2; read(0, &ch1, 1); read(0, &ch2, 1); if (ch1==91 && ch2==65) { // Up arrow. Print next line in history. // Erase old line // Print backspaces int i = 0; for (i =0; i < line_length; i++) { ch = 8; write(1,&ch,1); } // Print spaces on top for (i =0; i < line_length; i++) { ch = ' '; write(1,&ch,1); } // Print backspaces for (i =0; i < line_length; i++) { ch = 8; write(1,&ch,1); } // Copy line from history strcpy(line_buffer, history[history_index]); line_length = strlen(line_buffer); history_index=(history_index+1)%history_length; // echo line write(1, line_buffer, line_length); } } } // Add eol and null char at the end of string line_buffer[line_length]=10; line_length++; line_buffer[line_length]=0; return line_buffer; }