mutexes, correct disconnect/out

This commit is contained in:
Edward Emelianov 2020-12-23 11:18:11 +03:00
parent b87fb2e22a
commit a33179c02a
3 changed files with 59 additions and 42 deletions

20
main.c
View File

@ -28,11 +28,15 @@
static ttyd dtty = {.dev = NULL, .mutex = PTHREAD_MUTEX_INITIALIZER}; static ttyd dtty = {.dev = NULL, .mutex = PTHREAD_MUTEX_INITIALIZER};
//FILE *fd;
void signals(int signo){ void signals(int signo){
if(dtty.dev){ if(dtty.dev){
pthread_mutex_lock(&dtty.mutex); pthread_mutex_lock(&dtty.mutex);
close_tty(&dtty.dev); close_tty(&dtty.dev);
} }
//fprintf(fd, "stop\n");
//fflush(fd);
deinit_ncurses(); deinit_ncurses();
deinit_readline(); deinit_readline();
exit(signo); exit(signo);
@ -48,6 +52,8 @@ int main(int argc, char **argv){
WARN("Can't open device %s", G->ttyname); WARN("Can't open device %s", G->ttyname);
signals(1); signals(1);
} }
//fd = fopen("loglog", "w");
//fprintf(fd, "start\n");
init_ncurses(); init_ncurses();
init_readline(); init_readline();
const char *EOL = "\n"; const char *EOL = "\n";
@ -69,9 +75,9 @@ int main(int argc, char **argv){
if(pthread_create(&writer, NULL, cmdline, (void*)&dtty)) ERR("pthread_create()"); if(pthread_create(&writer, NULL, cmdline, (void*)&dtty)) ERR("pthread_create()");
settimeout(G->tmoutms); settimeout(G->tmoutms);
while(1){ while(1){
//if(0 == pthread_mutex_lock(&dtty.mutex)){ if(0 == pthread_mutex_lock(&dtty.mutex)){
int l = Read_tty(dtty.dev); int l = Read_tty(dtty.dev);
if(l){ if(l > 0){
char *buf = dtty.dev->buf; char *buf = dtty.dev->buf;
char *eol = NULL, *estr = buf + l; char *eol = NULL, *estr = buf + l;
do{ do{
@ -84,9 +90,13 @@ int main(int argc, char **argv){
add_ttydata(buf); add_ttydata(buf);
} }
}while(eol && buf < estr); }while(eol && buf < estr);
}else if(l < 0) signals(9); }else if(l < 0){
// pthread_mutex_unlock(&dtty.mutex); pthread_mutex_unlock(&dtty.mutex);
//} ERRX("Device disconnected");
}
pthread_mutex_unlock(&dtty.mutex);
usleep(1000);
}
} }
// never reached // never reached
return 0; return 0;

View File

@ -112,32 +112,6 @@ static void msg_win_redisplay(bool for_resize){
else wrefresh(msg_win); else wrefresh(msg_win);
} }
void add_ttydata(const char *text){
if(!text) return;
if(!*text) text = " "; // empty string
Line *lp = malloc(sizeof(Line));
lp->contents = strdup(text);
lp->prev = curr;
lp->next = NULL;
lp->Nline = nr_lines++;
if(!curr || !head){
head = curr = firstline = lp;
}else
curr->next = lp;
curr = lp;
// roll back to show last input
if(curr->prev){
firstline = curr;
int totalln = (strlen(firstline->contents) - 1)/COLS + 1;
while(firstline->prev){
totalln += (strlen(firstline->prev->contents) - 1)/COLS + 1;
if(totalln > LINES-2) break;
firstline = firstline->prev;
}
}
msg_win_redisplay(false);
}
static void cmd_win_redisplay(bool for_resize){ static void cmd_win_redisplay(bool for_resize){
int cursor_col = 2 + rl_point; // "> " width is 2 int cursor_col = 2 + rl_point; // "> " width is 2
werase(cmd_win); werase(cmd_win);
@ -168,6 +142,34 @@ static void show_mode(bool for_resize){
cmd_win_redisplay(for_resize); cmd_win_redisplay(for_resize);
} }
void add_ttydata(const char *text){
if(!text) return;
if(!*text) text = " "; // empty string
Line *lp = malloc(sizeof(Line));
lp->contents = strdup(text);
lp->prev = curr;
lp->next = NULL;
lp->Nline = nr_lines++;
if(!curr || !head){
head = curr = firstline = lp;
}else
curr->next = lp;
curr = lp;
// roll back to show last input
if(curr->prev){
firstline = curr;
int totalln = (strlen(firstline->contents) - 1)/COLS + 1;
while(firstline->prev){
totalln += (strlen(firstline->prev->contents) - 1)/COLS + 1;
if(totalln > LINES-2) break;
firstline = firstline->prev;
}
}
msg_win_redisplay(true);
show_mode(true);
doupdate();
}
static void resize(){ static void resize(){
if(LINES > 2){ if(LINES > 2){
wresize(msg_win, LINES - 2, COLS); wresize(msg_win, LINES - 2, COLS);
@ -217,26 +219,27 @@ void init_ncurses(){
} }
void deinit_ncurses(){ void deinit_ncurses(){
visual_mode = false;
delwin(msg_win); delwin(msg_win);
delwin(sep_win); delwin(sep_win);
delwin(cmd_win); delwin(cmd_win);
endwin(); endwin();
visual_mode = false;
} }
static void got_command(char *line){ static void got_command(char *line){
bool err = false;
if(!line) // Ctrl-D pressed on empty line if(!line) // Ctrl-D pressed on empty line
should_exit = true; should_exit = true;
else{ else{
if(!*line) return; // zero length if(!*line) return; // zero length
add_history(line); add_history(line);
if(dtty && dtty->dev){ if(dtty && dtty->dev){
if(0 == pthread_mutex_lock(&dtty->mutex)){
//if(0 == pthread_mutex_lock(&dtty->mutex)){ if(write_tty(dtty->dev->comfd, line, strlen(line))) err = true;
if(write_tty(dtty->dev->comfd, line, strlen(line))) signals(9); else if(write_tty(dtty->dev->comfd, dtty->eol, dtty->eollen)) err = true;
if(write_tty(dtty->dev->comfd, dtty->eol, dtty->eollen)) signals(9); pthread_mutex_unlock(&dtty->mutex);
// pthread_mutex_unlock(&dtty->mutex); if(err) ERRX("Device disconnected");
//} }
} }
free(line); free(line);
} }
@ -289,6 +292,8 @@ void *cmdline(void* arg){
keypad(cmd_win, insert_mode); // enable/disable reaction @ special characters keypad(cmd_win, insert_mode); // enable/disable reaction @ special characters
insert_mode = !insert_mode; insert_mode = !insert_mode;
show_mode(false); show_mode(false);
if(insert_mode) curs_set(2);
else curs_set(0);
break; break;
case KEY_RESIZE: case KEY_RESIZE:
resize(); resize();

10
tty.c
View File

@ -31,8 +31,10 @@ void settimeout(int tmout){
usec = tmout * 1000L; usec = tmout * 1000L;
} }
//extern FILE *fd;
int Read_tty(TTY_descr *d){ int Read_tty(TTY_descr *d){
if(d->comfd < 0) return 0; if(!d || d->comfd < 0) return 0;
size_t L = 0; size_t L = 0;
ssize_t l; ssize_t l;
size_t length = d->bufsz; size_t length = d->bufsz;
@ -46,11 +48,11 @@ int Read_tty(TTY_descr *d){
FD_SET(d->comfd, &rfds); FD_SET(d->comfd, &rfds);
tv.tv_sec = sec; tv.tv_usec = usec; tv.tv_sec = sec; tv.tv_usec = usec;
retval = select(d->comfd + 1, &rfds, NULL, NULL, &tv); retval = select(d->comfd + 1, &rfds, NULL, NULL, &tv);
if (!retval) break; if(!retval) break;
if(retval < 0) return -1;
if(FD_ISSET(d->comfd, &rfds)){ if(FD_ISSET(d->comfd, &rfds)){
l = read(d->comfd, ptr, length); l = read(d->comfd, ptr, length);
if(l < 0) return -1; if(l < 1) return -1; // disconnected
if(l == 0) break;
ptr += l; L += l; ptr += l; L += l;
length -= l; length -= l;
} }