#include #include #include #include #include #include #include #include #include #include #include #include #define BUFCHUNKSIZE 4096 #define BUFSAFEPAD 8 #define KNRM "\x1B[0m" #define KRED "\x1B[31m" #define KGRN "\x1B[32m" #define KYEL "\x1B[33m" #define KBLU "\x1B[34m" #define KMAG "\x1B[35m" #define KCYN "\x1B[36m" #define KWHT "\x1B[37m" #define BKRED "\x1B[41m" #define BKGRN "\x1B[42m" #define BKYEL "\x1B[43m" #define BKBLU "\x1B[44m" #define BKMAG "\x1B[45m" #define BKCYN "\x1B[46m" #define BKWHT "\x1B[47m" #if defined(DEBUG) && DEBUG > 0 #define DEBUG_PRINT(fmt, args...) fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \ __FILE__, __LINE__, __func__, ##args) #define COLORTEST() fprintf(stderr, "Color Palate:\n" \ KRED"KRED"KGRN"KGRN"KYEL"KYEL"KBLU"KBLU"KMAG"KMAG"KCYN"KCYN"KWHT"KWHT"KNRM"\n" \ KRED"▒▒▒▒"KGRN"▒▒▒▒"KYEL"▒▒▒▒"KBLU"▒▒▒▒"KMAG"▒▒▒▒"KCYN"▒▒▒▒"KWHT"▒▒▒▒"KNRM"\n" \ KRED"████"KGRN"████"KYEL"████"KBLU"████"KMAG"████"KCYN"████"KWHT"████"KNRM"\n" \ BKRED"KRED"BKGRN"KGRN"BKYEL"KYEL"BKBLU"KBLU"BKMAG"KMAG"BKCYN"KCYN"BKWHT"KWHT"KNRM"\n" \ ) #else #define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */ #define COLORTEST() #endif void child_process(char *argv[]){ execl(argv[1], argv[1], NULL); } size_t getuserinput(char* input_buffer, size_t max_buffer_size, int fd) { int in_char; size_t total_read_length; ssize_t read_result; //read_result = read(fd, &in_char, 1); while (1) { printf("reading char\n"); in_char = fgetc(stdin); printf("read char\n"); } //if (inchar < 0){ // //error condition // exit(1); //} return 1; } // go through the buffer and find the lines to be edited and print them after int processbufferpop(char *roll_buffer, size_t read_length) { //this is where some optimization could come in with using malloc and then freeing subset of memory; dog garn dynamic memory allocation int found_index; char *found_char = strchr(roll_buffer, '\n'); if (found_char != NULL){ found_index = found_char - roll_buffer; char to_process_string[]; } else { //no more instances } write(STDOUT_FILENO, roll_buffer, read_length); write(STDOUT_FILENO, "\n", 1); return 0; } int main(int argc, char *argv[]) { COLORTEST(); int master; pid_t child_pid; //struct winsize win = { // .ws_col = 80, .ws_row = 24, // .ws_xpixel = 480, .ws_ypixel = 192, //}; if (argc < 2) { printf("Usage: %s cmd [args...]\n", argv[0]); exit(EX_USAGE); } child_pid = forkpty(&master, NULL, NULL, NULL); if (child_pid == -1) { perror("forkpty failed"); exit(EX_OSERR); } if (child_pid == 0) { child_process(argv); exit(0); } //remainder is main is the parent process for processing input and shit fcntl(master, F_SETFL, O_NONBLOCK); char *child_out_roll_buffer = (char*) malloc(sizeof(char) * (BUFCHUNKSIZE+BUFSAFEPAD+1)); usleep(500*1000); while(1){ // ideally I would want to read from the pipe and buffer the output, rewriting the line on change // whenever it sees a newline, it should send it to the processor and print to stdout, with that newline // //CHILD OUTPUT HANDLING memset(child_out_roll_buffer, 0, BUFCHUNKSIZE+BUFSAFEPAD); int cont_read_offset_index = 0; //when we need to continue reading after process leaves us with half filled buffer // treating the buffer as kind of a FIFO stack thing // strip lines from top and then move leftover to top, // then start reading where we left off while(1){ ssize_t read_count = read(master, &child_out_roll_buffer[cont_read_offset_index], BUFCHUNKSIZE - cont_read_offset_index); if (read_count == 0 ) { DEBUG_PRINT("EOF\n"); exit(0); } if (read_count == -1){ if(errno == EAGAIN){ //errored because read would block break; } else { DEBUG_PRINT("I/O \"Error\" (Child Exited?) %d\n", errno); exit(0); } } //process da block then write it cont_read_offset_index = processbufferpop(child_out_roll_buffer, read_count); } //INPUT HANDLING memset(child_out_roll_buffer, 0, BUFCHUNKSIZE); strncpy(child_out_roll_buffer, readline(KGRN"~>"KNRM), BUFCHUNKSIZE-1); //printf("%s\n", child_out_roll_buffer); write(master, child_out_roll_buffer, strlen(child_out_roll_buffer)); write(master, "\n", 1); //memset(child_out_roll_buffer, 0, BUFCHUNKSIZE); //ssize_t count = strlen(child_out_roll_buffer); usleep(200*1000); } }