Since you seem to be C oriented, heres a quick example (Do note it hasn't been tested, and it lacks almost every form of error-checking):
Code:
#define WAIT_TIME 60 /* time to wait in seconds */
#define SEND_KEY 'X' /* Key to send to executed program */
void fork_child(const char* program)
{
int parent2child[2], child2parent[2], input, output, nwrite, status;
size_t last_call = time(NULL);
/* Fork child */
switch (fork())
{
case -1:
perror("fork");
exit(1);
case 0:
/* Child section */
/*
* Duplicate child's stdin into parents stdin,
* and child's writing end of child2parent into stdout
*/
if (dup2(parent2child[0], STDIN_FILENO) ==-1 ||
dup2(child2parent[1], STDOUT_FILENO) ==-1)
{
printf("Error: Child duping parent2child and child2parent.\n");
exit(1);
}
/* Close unused filedescriptors */
if(close(parent2child[0]) != 0)
{
printf("Error: Child closing parent2child[0].\n");
exit(1);
}
if(close(parent2child[1]) != 0)
{
printf("Error: Child closing parent2child[1].\n");
exit(1);
}
if(close(child2parent[0]) != 0)
{
printf("Error: Child closing child2parent[0].\n");
exit(1);
}
if(close(child2parent[1]) != 0)
{
printf("Error: Child closing child2parent[1].\n");
exit(1);
}
/*
* All set: execute program
*/
execvp(program, NULL);
printf("Error: Child executing program {%s}.\n", program);
exit(1);
default:
/* Parent section */
/* Close unused fildescriptor */
if(close(child2parent[1]) != 0)
{
printf("Error: Child closing child2parent[1].\n");
exit(1);
}
if(close(parent2child[0]) != 0)
{
printf("Error: Parent closing parent2child[0].\n");
exit(1);
}
while(1)
{/* get user input and send to child */
/* this is depeding on a system which is in chbreak mode */
if((input = getch()) == ERR)
{/* no userinput, see if it is time to send 'x' */
if(last_call+WAIT_TIME < time(NULL))
{
/* update last_call */
last_call = time(NULL);
/* write 'x' to child */
if((nwrite = write(parent2child[1], (void*)SEND_KEY, 1)) < 0)
{
printf("Error: Parent writing to child\n");
exit(1);
}
}
else
{ /* send out ERR of userinput */
if((nwrite = write(parent2child[1], (void*)SEND_KEY, 1)) < 0)
{
printf("Error: Parent writing to child\n");
exit(1);
}
}
}
else
{ /* send userinput direct to child */
/* update last_call */
last_call = time(NULL);
/* send userinput */
if((nwrite = write(parent2child[1], (void*)input, 1)) < 0)
{
printf("Error: Parent writing to child\n");
exit(1);
}
}
/* read return output from child and send to parents output */
if(read(child2parent[0], output, 1) < 0)
{ /* nothing to read from child */
/* so do whatever you want or do nothing */ ;
}
else
{
/* something to read, so send it */
putc(output);
}
if(waitpid(0,&status,0) <= 1)
{ /* some error during execution */
printf("Error: Child exited with status: %d\n", status);
exit(1);
}
}
}
}