lukasz.proszek.info

Powrót do listy plików

nazwane.c

#include "nazwane.h"

/*
Program klinet/serwer dla FIFO.
Program klinet/serwer dla FIFO.
sposób uruchomienia
nazwane.run <klient|serwer> <fifo> <plik>

fifo, plik są dowolnymi stringami

na przykład

nazwane.run server data.tmp in.txt
spowoduje uruchomienie procesu który będzie czytał z in.txt i zapisywał do potoku data.tmp

nazwane.run klient data.tmp out.txt
spowoduje uruchomienie procesu który będzie czytał z potoku data.tmp i zapisywał do pliku out.txt

UWAGA: istnieją dwa sposoby utworzenia potoków nazwanych typu FIFO: z poziomu powłoki oraz z poziomu programu

    serwer szuka zadanego FIFO (już istniejącego)
    jezeli nie znajdzie to utworzy takowy.
*/

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

  /*sprawdzenie poprawności argumentów */

  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);
  }

  if (argc < 4)
  {     /* 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Ż TRZY ARGUMENTY\n");
    exit (0);
  }

  /* wiemy, ze argumentów nie jest za mało, sprawdźmy więc czy nie jest ich za dużo */
  if (argc > 4)
  {     /* 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Ż TRZY ARGUMENTY\n");
    exit (-1);
  }

  /*jeżeli pierwszym z listy argumentóww nie jest klient i nie serwer to wychodzimy */
  if (strcmp (argv[1], "klient"))
    if (strcmp (argv[1], "serwer"))
    {
      printf ("pierwszy argumet to obowiązkowo klient lub serwer\n");
      exit (1);
    }

  /*deklaracja zmiennych */
  int fd;     //deskryptor dla kolejki FIFO
  int fdin;   //deskryptor plik z ktorego pobierane sa dane
  int fdout;    //deskryptor plik do ktorego pisane sa dane
  int len;    //liczba bajtow wczytanych/zapisanych do FIFO
  char buf[N];
  mode_t mode = 0666; //prawa dostepu do pliku



  // /* zapisuje do "dobrze znanej" kolejki FIFO
  //dane pobiera z pliku in.txt (parametr wejsciowy)*/

  /* otwiera do zapisu stworzone zewnętrznie pipe */
  if (!strcmp (argv[1], "serwer"))
  {
    //podaje PID procesu
    printf ("PID procesu = %d\n", getpid ());


    /* !!!!!! creat(plik) = open(plik,  O_WRONLY | O_CREAT | O_TRUNC); */
    /* otworz kolejke FIFO tylko do zapisu */
    if ((fd = creat (argv[2], S_IWUSR | S_IRUSR | S_IWGRP)) < 0)
    {
      perror ("problem przy otwarciu FIFO do zapisu");
      exit (-1);
    }

    //otwarcie pliku wejściowego do pobrania z niego danych
    if ((fdin = open (argv[3], O_RDONLY)) < 0)
    {
      perror ("problem przy otwaciu pliku do odczytu");
      exit (-1);
    }

    //zpisanie z plik do FIFO
    while ((len = read (fdin, buf, N)) > 0)
      write (fd, buf, len);

    close (fdin);
    close (fd);

    return (0);
  }

  if (!strcmp (argv[1], "klient"))
  {
    /*otworz kolejke FIFO tylko do odczytu */
    if ((fd = open (argv[2], O_RDONLY)) < 0)
    {
      perror ("Nastąpił problem przy otwarciu FIFO do odczytu\n");
      printf ("\nNastąpi próba utworzenia FIFO przez klienta\n");
      //tworzy FIFO
      if ((mkfifo (argv[2], mode)) < 0)
      {
        perror ("błąd przy wywołaniu mkfifo()");
        exit (-1);
      }
      if ((fd = open (argv[2], O_RDONLY)) < 0)
      {
        perror ("Nastąpił problem przy otwarciu FIFO do odczytu\n");
        exit (-1);
      }
    }

    /*otworz plik wyjściowy do ktorego zapisane sa dane z potoku */
    if ((fdout =
         creat (argv[3], S_IWUSR | S_IRUSR | S_IWGRP)) < 0)
    {
      perror ("problem z otwrciem pliku do zapisu");
      exit (-1);
    }

    /* czytaj i wyswietlaj wyjscie FIFO, dopoki nie EOF */
    while ((len = read (fd, buf, N)) > 0)
      write (fdout, buf, len);

    close (fd);

  }

  printf ("operacja zakończona pomyślnie: nastąpi usunięcie pliku %s\n",
    argv[2]);
  {
    switch (fork ())
    {
    case -1:
      perror ("fork error");
      exit (1);
    case 0:
      execl ("/bin/rm", "rm", argv[2], NULL);
      perror ("execl error");
      exit (2);
    default:
      ;
    }
    exit (0);
  }
  return 0;
}

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.nazwane", NULL);
    perror ("execl error");
    exit (2);
  default:
    ;
  }
  exit (0);
}

składania pokolorowana przez Code2HTML, v. 0.9.1