View Single Post
Old 01-08-2007, 11:49 AM   #11 (permalink)
redhead
Newbie
 
redhead's Avatar
 
Join Date: Jun 2002
Location: Denmark
Posts: 1,697
redhead is on a distinguished road
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);
	    }
	}
    }
}
__________________
Don't worry Ma'am, We're university students, We know what We're doing.
-----
If you pull the pin, Mr.Grenade would no longer be your friend.
-----
01000111 01101111 00100000 01000011 00100000 00100001
redhead is offline   Reply With Quote