diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dirax.c | 73 |
1 files changed, 41 insertions, 32 deletions
diff --git a/src/dirax.c b/src/dirax.c index 37e7b96..0823111 100644 --- a/src/dirax.c +++ b/src/dirax.c @@ -47,7 +47,7 @@ static void dirax_parseline(const char *line, ControlContext *ctx) { copy = strdup(line); for ( i=0; i<strlen(copy); i++ ) { - if ( copy[i] == '\r' ) copy[i]=' '; + if ( copy[i] == '\r' ) copy[i]='r'; if ( copy[i] == '\n' ) copy[i]='\0'; } printf("DX: DirAx: %s\n", copy); @@ -217,8 +217,6 @@ static void dirax_send_next(ControlContext *ctx) { } - fsync(ctx->dirax_pty); - } static gboolean dirax_readable(GIOChannel *dirax, GIOCondition condition, ControlContext *ctx) { @@ -250,17 +248,18 @@ static gboolean dirax_readable(GIOChannel *dirax, GIOCondition condition, Contro DirAxInputType type = DIRAX_INPUT_NONE; /* See if there's a full line in the buffer yet */ - for ( i=0; i<ctx->dirax_rbufpos; i++ ) { /* Means the last value looked at is roffset-1 */ + for ( i=0; i<ctx->dirax_rbufpos-1; i++ ) { /* Means the last value looked at is rbufpos-2 */ - if ( i <= ctx->dirax_rbufpos-7 ) { + /* Is there a prompt in the buffer? */ + if ( i+7 <= ctx->dirax_rbufpos ) { if ( strncmp(ctx->dirax_rbuffer+i, "Dirax> ", 7) == 0 ) { block_ready = 1; type = DIRAX_INPUT_PROMPT; break; } } - - if ( (ctx->dirax_rbuffer[i] == '\n') ) { + + if ( (ctx->dirax_rbuffer[i] == '\r') && (ctx->dirax_rbuffer[i+1] == '\n') ) { block_ready = 1; type = DIRAX_INPUT_LINE; break; @@ -270,32 +269,26 @@ static gboolean dirax_readable(GIOChannel *dirax, GIOCondition condition, Contro if ( block_ready ) { + unsigned int new_rbuflen; + unsigned int endbit_length; + switch ( type ) { case DIRAX_INPUT_LINE : { char *block_buffer = NULL; - unsigned int new_rbuflen; - unsigned int endbit_length; block_buffer = malloc(i+1); memcpy(block_buffer, ctx->dirax_rbuffer, i); block_buffer[i] = '\0'; - dirax_parseline(block_buffer, ctx); - free(block_buffer); - /* Now the block's been parsed, it should be forgotten about */ - endbit_length = i+1; - memmove(ctx->dirax_rbuffer, ctx->dirax_rbuffer + endbit_length, - ctx->dirax_rbuflen - endbit_length); - /* Subtract the number of bytes removed */ - ctx->dirax_rbufpos = ctx->dirax_rbufpos - endbit_length; - new_rbuflen = ctx->dirax_rbuflen - endbit_length; - if ( new_rbuflen == 0 ) { - new_rbuflen = 256; + if ( block_buffer[0] == '\r' ) { + memmove(block_buffer, block_buffer+1, i); } - ctx->dirax_rbuffer = realloc(ctx->dirax_rbuffer, new_rbuflen); - ctx->dirax_rbuflen = new_rbuflen; + + dirax_parseline(block_buffer, ctx); + free(block_buffer); + endbit_length = i+2; break; @@ -303,10 +296,8 @@ static gboolean dirax_readable(GIOChannel *dirax, GIOCondition condition, Contro case DIRAX_INPUT_PROMPT : { - memmove(ctx->dirax_rbuffer+i, ctx->dirax_rbuffer+i+7, 7); - ctx->dirax_rbufpos -= 7; dirax_send_next(ctx); - + endbit_length = i+7; break; } @@ -318,6 +309,18 @@ static gboolean dirax_readable(GIOChannel *dirax, GIOCondition condition, Contro } + /* Now the block's been parsed, it should be forgotten about */ + memmove(ctx->dirax_rbuffer, ctx->dirax_rbuffer + endbit_length, ctx->dirax_rbuflen - endbit_length); + + /* Subtract the number of bytes removed */ + ctx->dirax_rbufpos = ctx->dirax_rbufpos - endbit_length; + new_rbuflen = ctx->dirax_rbuflen - endbit_length; + if ( new_rbuflen == 0 ) { + new_rbuflen = 256; + } + ctx->dirax_rbuffer = realloc(ctx->dirax_rbuffer, new_rbuflen); + ctx->dirax_rbuflen = new_rbuflen; + } else { if ( ctx->dirax_rbufpos == ctx->dirax_rbuflen ) { @@ -351,7 +354,7 @@ void dirax_invoke(ControlContext *ctx) { FILE *fh; Reflection *ref; unsigned int opts; - struct termios t; + int saved_stderr; if ( ctx->dirax ) { printf("DX: DirAx is already running.\n"); @@ -373,6 +376,7 @@ void dirax_invoke(ControlContext *ctx) { } fclose(fh); + saved_stderr = dup(STDERR_FILENO); ctx->dirax_pid = forkpty(&ctx->dirax_pty, NULL, NULL, NULL); if ( ctx->dirax_pid == -1 ) { printf("DX: Failed to fork.\n"); @@ -381,12 +385,22 @@ void dirax_invoke(ControlContext *ctx) { if ( ctx->dirax_pid == 0 ) { /* Child process: invoke DirAx */ + struct termios t; + + /* Turn echo off */ + tcgetattr(STDIN_FILENO, &t); + t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); + tcsetattr(STDIN_FILENO, TCSANOW, &t); + + /* Reconnect stderr */ + dup2(saved_stderr, STDERR_FILENO); + execlp("dirax", "", (char *)NULL); printf("(from the Other Side) Failed to invoke DirAx.\n"); _exit(0); } - + ctx->dirax_rbuffer = malloc(256); ctx->dirax_rbuflen = 256; ctx->dirax_rbufpos = 0; @@ -395,11 +409,6 @@ void dirax_invoke(ControlContext *ctx) { opts = fcntl(ctx->dirax_pty, F_GETFL); fcntl(ctx->dirax_pty, F_SETFL, opts | O_NONBLOCK); - /* Turn off terminal echo */ - tcgetattr(ctx->dirax_pty, &t); - t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ECHOCTL | ECHOPRT | ECHOKE | ICANON); - tcsetattr(ctx->dirax_pty, TCSANOW, &t); - ctx->dirax_step = 1; /* This starts the "initialisation" procedure */ ctx->dirax_read_cell = 0; ctx->dirax = g_io_channel_unix_new(ctx->dirax_pty); |