Console input
This commit is contained in:
@@ -27,15 +27,12 @@ void consoleInit() {
|
||||
|
||||
consolePrint(" = Dawn Console = ");
|
||||
|
||||
#if DUSK_CONSOLE_TERMIOS
|
||||
// Create termios session.
|
||||
struct termios newTermios;
|
||||
tcgetattr(STDIN_FILENO, &CONSOLE.originalTermios);
|
||||
#if DUSK_CONSOLE_POSIX
|
||||
|
||||
// Disable canonical mode & echo
|
||||
newTermios.c_lflag &= ~(ICANON | ECHO);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &newTermios);
|
||||
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);// Set stdin to non-blocking
|
||||
|
||||
threadInit(&CONSOLE.thread, consoleInputThread);
|
||||
threadMutexInit(&CONSOLE.execMutex);
|
||||
threadStartRequest(&CONSOLE.thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -80,6 +77,8 @@ void consolePrint(const char_t *message, ...) {
|
||||
}
|
||||
|
||||
void consoleExec(const char_t *line) {
|
||||
threadMutexLock(&CONSOLE.execMutex);
|
||||
|
||||
assertNotNull(line, "line must not be NULL");
|
||||
assertTrue(
|
||||
CONSOLE.execBufferCount < CONSOLE_EXEC_BUFFER_MAX,
|
||||
@@ -279,23 +278,22 @@ void consoleExec(const char_t *line) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
threadMutexUnlock(&CONSOLE.execMutex);
|
||||
}
|
||||
|
||||
// May move these later
|
||||
void consoleUpdate() {
|
||||
#if DUSK_CONSOLE_TERMIOS
|
||||
char_t c;
|
||||
for(;;) {
|
||||
if(!read(STDIN_FILENO, &c, 1)) break;
|
||||
putchar(c);
|
||||
}
|
||||
#if DUSK_CONSOLE_POSIX
|
||||
#endif
|
||||
|
||||
threadMutexLock(&CONSOLE.execMutex);
|
||||
for(uint32_t i = 0; i < CONSOLE.execBufferCount; i++) {
|
||||
consolecmdexec_t *exec = &CONSOLE.execBuffer[i];
|
||||
assertNotNull(exec->cmd, "Command execution has no command.");
|
||||
exec->cmd->function(exec);
|
||||
}
|
||||
threadMutexUnlock(&CONSOLE.execMutex);
|
||||
|
||||
// #if DUSK_KEYBOARD_SUPPORT == 1
|
||||
// uint8_t key;
|
||||
@@ -337,8 +335,63 @@ void consoleUpdate() {
|
||||
}
|
||||
|
||||
void consoleDispose(void) {
|
||||
// Reset termios
|
||||
#if DUSK_CONSOLE_TERMIOS
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &CONSOLE.originalTermios);
|
||||
#if DUSK_CONSOLE_POSIX
|
||||
threadStop(&CONSOLE.thread);
|
||||
threadMutexDispose(&CONSOLE.execMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
consolePrint(" = Console shutting down = ");
|
||||
}
|
||||
|
||||
|
||||
#if DUSK_CONSOLE_POSIX
|
||||
void consoleInputThread(thread_t *thread) {
|
||||
assertNotNull(thread, "Thread cannot be NULL.");
|
||||
|
||||
char_t line[CONSOLE_LINE_MAX];
|
||||
size_t cap = 0;
|
||||
|
||||
struct pollfd pfd = {
|
||||
.fd = STDIN_FILENO,
|
||||
.events = POLLIN
|
||||
};
|
||||
|
||||
while(!threadShouldStop(thread) && ENGINE.running) {
|
||||
int32_t rc = poll(&pfd, 1, DUSK_CONSOLE_POSIX_POLL_RATE);
|
||||
|
||||
if(rc == 0) continue;
|
||||
if(rc < 0) {
|
||||
if(errno == EINTR) continue; // Interrupted by signal, retry
|
||||
assertUnreachable("poll() failed with unexpected error.");
|
||||
}
|
||||
|
||||
// Check for errors or input
|
||||
if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) break;
|
||||
if (!(pfd.revents & POLLIN)) {
|
||||
pfd.revents = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Read a line from stdin
|
||||
if(!fgets(line, CONSOLE_LINE_MAX, stdin)) {
|
||||
if (feof(stdin)) break;
|
||||
clearerr(stdin);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Did we read a full line or did it get truncated?
|
||||
size_t len = strlen(line);
|
||||
int32_t fullLine = len > 0 && line[len - 1] == '\n';
|
||||
|
||||
// Strip trailing newline/CR
|
||||
while(len && (line[len - 1] == '\n' || line[len - 1] == '\r')) {
|
||||
line[--len] = '\0';
|
||||
}
|
||||
|
||||
if(len > 0) consoleExec(line);
|
||||
|
||||
pfd.revents = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user