I was trying to mock up a simple GUI for a C program, by forking the C program and exec-ing wish
in the child, then piping a bunch of tcl/tk commands into it from the parent. After the form is created, I would let the C program just keep reading the output of the tcl program and respond to it.
I have it mostly working, but in this example I keep getting a message from tcl:
invalid command name ""
It's not breaking anything but I don't really understand what's causing it.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define DIE do { perror(__FUNCTION__); exit(EXIT_FAILURE); } while (0)
#define LEN(a) (sizeof(a) / sizeof(*a))
int child(int p2c[2], int c2p[2]) {
if (close(p2c[1])) DIE;
if (close(c2p[0])) DIE;
if (dup2(p2c[0], fileno(stdin)) < 0) DIE;
if (dup2(c2p[1], fileno(stdout)) < 0) DIE;
char * cmds[] = { "wish", NULL };
execvp(cmds[0], cmds);
DIE;
}
int parent(int p2c[2], int c2p[2]) {
if (close(p2c[0])) DIE;
if (close(c2p[1])) DIE;
char init[] = "button .b -text {Print} -command {puts hi}\n"
"button .x -text {Exit} -command {exit}\n"
"grid .b -column 0 -row 0\n"
"grid .x -column 0 -row 1\n";
if (write(p2c[1], init, LEN(init)) < LEN(init)) DIE;
if (close(p2c[1])) DIE;
char buf[1<<10];
ssize_t s;
while ((s = read(c2p[0], buf, LEN(buf))) > 0) {
buf[s-1] = '\0';
printf("i read '%s'\n", buf);
}
return 0;
}
int main(int argc, char ** argv) {
int p2c[2]; // parent to child pipe
int c2p[2];
if (pipe(p2c)) DIE;
if (pipe(c2p)) DIE;
switch (fork()) {
case -1: DIE; break;
case 0: child(p2c, c2p); break;
default: parent(p2c, c2p); break;
}
return EXIT_SUCCESS;
}
Any idea why it's claiming that the empty string is an invalid command?