163 lines
4.6 KiB
C
163 lines
4.6 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/types.h>
|
|
#include <pty.h>
|
|
#include <sysexits.h>
|
|
#include <fcntl.h>
|
|
#include <readline/readline.h>
|
|
#include <readline/history.h>
|
|
|
|
#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);
|
|
}
|
|
}
|
|
|