/* Copyright (c) 2001-2009 by SoftIntegration, Inc. All Rights Reserved */
/* a sample program that attempts to handle background processes by
   changing their process groups. This program is compiled as follows:
   setpgid.c < setpgid.in.  The contents of setpgid.in are: asdf, quit.*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#define MAX_CANON 1024
#define PROMPT_STRING "Enter string: " 
#define NEWLINE_SYMBOL '\n'
#define QUIT_STRING "quit"
#define NULL_SYMBOL '\0'
#define BACK_SYMBOL '!'
#define FALSE 0;
#define TRUE 1;

int main() {
    char inbuf[MAX_CANON];
    pid_t child_pid;
    int inbackground,x;
    char *backp;
    
    for(;;) {
      fputs(PROMPT_STRING,stdout);
      if(fgets(inbuf,MAX_CANON,stdin) == NULL)
        break;
      if(*(inbuf + strlen(inbuf) -1) == NEWLINE_SYMBOL)
        *(inbuf+strlen(inbuf) -1) =0;
      if(strcmp(inbuf,QUIT_STRING) == 0) {
        break;
      }
      else {
        if((backp = strchr(inbuf,BACK_SYMBOL)) == NULL) {
          inbackground = FALSE;
        }
        else {
          inbackground = TRUE;
          *(backp) = NULL_SYMBOL;
        }
        if((child_pid = fork())==0) {
          if(inbackground) {
            if(setpgid(getpid(), getpid()) == -1)
              exit(1);
          }
          execv(inbuf,NULL);
          exit(1);
        }
        else if (child_pid >0 && !inbackground)
          waitpid(child_pid,NULL,0);
     }
   printf("Success\n");
   }
}
