aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dirax.c73
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);