// Användbara systemanrop

// fork() exit() wait() getpid() getppid() execl() execlp() pipe() open() close()

//Hitta en includefil (och mer information) för ett systemanrop

//$ man <systemanropet>

// Skapa en parallell process

pid = fork();
switch(pid)
{
  case -1: fprintf(stderr,"Fork failed.\n"); exit(1);
  case 0: childcode(); exit(0); //K\"ors i en parallell barnprocess.
  default: parentcode1(); wait(0); //K\"ors parallellt med barnprocessen.
}
parentcode2(); //K\"ors efter barnprocessen avslutat.


// Skapa ett barn och ett barnbarn d\"ar barnet skickar sitt processid till 
// barnbarnet som i sin tur skickar det multiplicerat med 2 till föräldern}


// Programnamn: uppg5
main()
{
  int fds1[2], fds2[2], test, a;
  pipe(fds1); pipe(fds2);

  if(!fork())
  {
    char pidstr[20];
    if(!fork())
    {
      test = close(0); assert(test==0);
      test = dup(fds1[0]); assert(test==0);
      test = close(fds1[0]); assert(test==0);
      test = close(fds1[1]); assert(test==0);
      test = close(1); assert(test==0);
      test = dup(fds2[1]); assert(test==1);
      test = close(fds2[1]); assert(test==0);
      test = close(fds2[0]); assert(test==0);
      sleep(1);
      execlp("./double", "./double", NULL);
      fprintf(stderr,"execlp did not work\n");
      exit(1);
    }

    test = close(1); assert(test==0);
    test = dup(fds1[1]); assert(test==1);
    test = close(fds1[1]); assert(test==0);
    test = close(fds1[0]); assert(test==0);
    test = close(fds2[0]); assert(test==0);
    test = close(fds2[1]); assert(test==0);
    sleep(1);
    sprintf(pidstr,"%d",getpid());
    execlp("./out","./out",pidstr,NULL);
    fprintf(stderr,"execlp did not work\n");
    exit(1);
  }
  system("ps -o pid,ppid,pgid,sess,comm");

  read(fds2[0],&a,sizeof(int)); printf("pid * 2: %d.\n", a);

  wait(0);
}

// out:

int main(int argc, char* argv[])
{
  int a=atoi(argv[1]);
  write(1, &a, sizeof(int));
  sleep(1);
  return 0;
}


// double:

int main()
{
  int a;
  read(0,&a,sizeof(int));
  a=2*a;
  write(1,&a,sizeof(int));
  sleep(1);
  return 0;
}
