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
Materiały z Systemów Operacyjnych udostępnione zostały na zasadach licencji GPL w wersji 2.