lukasz.proszek.info

Powrót do listy plików

nienazwane.c

/*
program komunikacji miedzy procesami za pomoca potokow nienazwanych
problem producenta-konsumenta
pr.macierzysty - producent - dostarcza surowiec do potoku (z pliku podanego jako argument 1)
pr.potomny - konsument - pobiera surowiec z potoku (zapisuje do pliku podanego jako argument 2)
*/

#include "nienazwane.h"

int
main (int argc, char *argv[]) /*argumenty wejsciowe */
{

  if (argc == 1)
  {     /* jeżeli mamy dokładnie jeden argument (nazwę programu) to poinformujemy
         * użyszkodnika o jego niekompetencji */
    printf ("Złe wywołanie programu: wywołaj program z parametrem --help aby uzyskać pomoc\n");
    printf ("Powód wyjścia: BRAK ARGUMENTÓW\n");
    exit (1);
  }

  /* przeszliśmy dalej co znaczy że użyszkodnik podał jakieś argumenty */
  if (!strcmp (argv[1], "--help"))
  {     /* sprawdźmy zatem czy nie zażyczył sobie pomocy ;) */
    pokaz_pomoc ();
    exit (1);
  }

  /* zobaczmy czy nie podał ich za mało */
  if (argc < 3)
  {     /* jeżeli mamy mniej argumentów niż potrzeba to poinformujemy
         * użyszkodnika o jego niekompetencji */
    printf ("Złe wywołanie programu: wywołaj program z parametrem --help aby uzyskać pomoc\n");
    printf ("Powód wyjścia: MNIEJ NIŻ DWA ARGUMENTY\n");
    exit (1);
  }

  /* wiemy, ze argumentów nie jest za mało, sprawdźmy więc czy nie jest ich za dużo */
  if (argc > 3)
  {     /* jeżeli mamy więcej argumentów niż potrzeba to poinformujemy
         * użyszkodnika o jego niekompetencji */
    printf ("Złe wywołanie programu: wywołaj program z parametrem --help aby uzyskać pomoc\n");
    printf ("Powód wyjścia: WIĘCEJ NIŻ DWA ARGUMENTY\n");
    exit (1);
  }

  /************************************************************************
  **   jak już przeprowadziliśmy testy poprawności wywołania prograu     **
  **   to możemy go zacząć :)                                            **
  ************************************************************************/

/*==================DEKLARACJA ZMIENNYCH===================================*/

  int fd[2];
  /* tablica deskryptorow pliku dla potoku
   * fd[0] deskryptor czytania 
   * fd[1] deskryptor zapisywania */

  int fdin, fdout;
  /* deskryptory dla plikow: wejściowego  i wyjściowego
   * nazwy od FileDataInput i FileDataOutput */

  char buf[N_BUF];
  /* bufor na przekazywany ,,surowiec''
   * jego rozmiar jest zdefiniowany w pliku nagłówkowym */

  int len;
  /* len - ilość bajtów w buforze */
  int pid;

  char decyzja;

int czas;
/*=========================================================================*/

  /* czy napewno użyszkodnik wie co robi? */


  printf ("Uwaga plik \"%s\" (jeżeli istnieje) zostanie nadpisany!\nAby kontynuować musicz napisać \"tak\"", argv[2]);
  scanf ("%s", &decyzja);
  if (strcmp ("tak", &decyzja))
    exit (0);


  /*tworzymy potok \ */
  if ((pipe (fd)) < 0)
    /* w wypadku porażki wychodzimy z programu drukując powód porażki */
    err_quit ("problem z utworzeniem potoku");

  /*tworzymy proces potomny */
  switch (pid = fork ())
  {
  case -1:    /* w wypadku porażki wychodzimy z programu drukując powód porażki */
    err_quit ("problem z utworzeniem procesu potomnego za pomocą fork()");

  case 0:   /*akcja dla potomnego */
    /* drukujemy PID procesu i info że jest potomny */
    printpid ("potomny");

    /* zamykamy potok do zapisywania (w wypadku potoków dwukierunkowych w systemie) */
    close (fd[1]);

    /* otwieramy plik do zapisu (wyjściowy) */
    if ((fdout =
         /*otwórz plik wyjściowy ( tylko do zapisu; utwórz; jeżeli istnieje to wyzeruj) *
          * zwracany plik bedzie miał prawa u=w,g=w,o= */
         creat (argv[2], S_IWUSR | S_IRUSR | S_IWGRP)) < 0)
      /* !!!!!! creat(plik) = open(plik,  O_WRONLY | O_CREAT | O_TRUNC); */
      /* jezeli nie można otworzyć pliku to kończymy */
      err_quit ("problem z otwarciem pliku wyjściowego");



    /* dopuki nie EOF
     * czytamy z potoku N_BUF danych
     * dane zapisujemy do zmiennej buf
     * ilość odczytanych danych przekazujemy do zmiennej len */
    while ((len = read (fd[0], buf, N_BUF)) > 0)
      /* zapisujemy do fdout (pliku wyjściowego) len danych zaczynając na pozycji buf */
    {
      sleep (czas=opoznienie ()); /* czas - opóźnienie */
      write (fdout, buf, len);
      printf ("out <- %s",buf);
      
    }
    close (fd[0]);  /* zamykamy potok do czytania */
    close (fdout);  /* zamykamy plik wyjściowy */



  default:
    /* drukujemy PID procesu i info że jest macierzysty */
    if (pid ==0) exit(0);
    printpid ("macierzysty");

    /* zamykamy potok do czytania (w wypadku potoków dwukierunkowych w systemie) */
    close (fd[0]);

    /* otwieramy plik wejściowy tylko do odczytu */
    if ((fdin = open (argv[1], O_RDONLY)) < 0)
    {
      err_quit ("problem z otworzeniem pliku wejściowego");
    }

    /* dopuki nie EOF
     * czytamy z pliku wejściowego N_BUF danych
     * dane zapisujemy do zmiennej buf
     * ilość odczytanych danych przekazujemy do zmiennej len */
    while ((len = read (fdin, buf, N_BUF)) > 0)
      /* zapisujemy do potoku
       * dane len danych z buf */
    {
        sleep (czas=opoznienie ()); /* opóźnienie */
      write (fd[1], buf, len);
      printf (" in -> %s", buf);
    
    }
    /*zamykamy plik wejściowy */
    close (fdin);

    /* zamykamy potok do zapisu */
    close (fd[1]);


  }

  //zbieranie stanu koncowego, czekanie na zakonczenie procesu potomnego
  waitpid (pid, NULL, 0);
  
  
/**************************************************************************
***************************************************************************
** !!!!!!!!!!! sprawdzimy sobie różnice między plikami !!!!!!!!!!!!!!!!! **
***************************************************************************
**************************************************************************/
  printf("\n\nPorównamy teraz pliki\n");
      switch (fork ())
    {
    case -1:
      perror ("fork error");
      exit (1);
    case 0:
      execl ("/usr/bin/diff", "diff", argv[1],argv[2], NULL);
      perror ("execl error");
      exit (2);
    default:
      //wait();
      ;
    }
  
  
  
  //printf ("pid= %d\n", pid);
  exit (0);
}

void
err_quit (char *msg)
{
  perror (msg);
  exit (1);
}

void
printpid (char *proces)
{
  printf ("PID=%d, proces %s\n", getpid (), proces);
  return;
}

void
pokaz_pomoc ()
{       /*pomoc wyswietlamy za pomocą funkcji fork() oraz execl()
         * wiele praktyczniej jest ją umieścić w pliku tekstowym */
  switch (fork ())
  {
  case -1:
    perror ("fork error");
    exit (1);
  case 0:
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  !! FIXME: dodać sprawdzanie czy plik readme istnieje !!
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
    execl ("/bin/cat", "cat", "./README.nienazwane", NULL);
    perror ("execl error");
    exit (2);
  default:
    ;
  }
  exit (0);
}

int
opoznienie ()
{
  int czas = (5.0 * rand () / (RAND_MAX + 1.0));
  printf("%i\n",czas);
  return czas;
}

składania pokolorowana przez Code2HTML, v. 0.9.1