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