182 lines
5.9 KiB
C
182 lines
5.9 KiB
C
|
/*
|
||
|
Serwer wspolbiezny oparty na kolejekach komunikatow.
|
||
|
*/
|
||
|
|
||
|
#include <unistd.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <sys/uio.h>
|
||
|
#include <signal.h>
|
||
|
#include <sys/ipc.h>
|
||
|
#include <sys/msg.h>
|
||
|
#include <string.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <errno.h>
|
||
|
|
||
|
typedef struct mymesg1
|
||
|
{
|
||
|
long mtype;
|
||
|
pid_t pid;
|
||
|
} paczka1;
|
||
|
typedef struct mymesg2
|
||
|
{
|
||
|
long mtype;
|
||
|
double melement;
|
||
|
} paczka2;
|
||
|
int f;
|
||
|
paczka1 *wiad;
|
||
|
char *sciezka;
|
||
|
int czy_skasowac = 1;
|
||
|
|
||
|
void ala(int i)
|
||
|
{
|
||
|
if (i == SIGTERM || i == SIGINT)
|
||
|
{
|
||
|
printf("Serwer: Koniec pracy serwera.\n");
|
||
|
free(wiad);
|
||
|
msgctl(f, IPC_RMID, NULL);
|
||
|
if (czy_skasowac)
|
||
|
{
|
||
|
unlink(sciezka);
|
||
|
}
|
||
|
free(sciezka);
|
||
|
exit(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int main(int argc, char *argv[])
|
||
|
{
|
||
|
pid_t pid;
|
||
|
key_t klucz_kolejka;
|
||
|
const size_t wielkosc1 = sizeof(paczka1) - sizeof(long);
|
||
|
ssize_t liczba_bajtow;
|
||
|
int plik = 0;
|
||
|
|
||
|
signal(SIGTERM, ala);
|
||
|
signal(SIGINT, ala);
|
||
|
sigignore(SIGCHLD);
|
||
|
if (argc > 1)
|
||
|
{
|
||
|
sciezka = strndup(argv[1], strlen(argv[1]));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sciezka = strndup("/tmp/roboczy.kolejka_serwer", strlen("/tmp/roboczy.kolejka_serwer"));
|
||
|
}
|
||
|
if (access(sciezka, F_OK) == 0)
|
||
|
{
|
||
|
czy_skasowac = 0;
|
||
|
}
|
||
|
if (czy_skasowac && ((plik = open(sciezka, O_CREAT | O_EXCL, 0600)) == -1))
|
||
|
{
|
||
|
fprintf(stderr, "Serwer: Blad utworzenia pliku %s: %s.\n", sciezka, strerror(errno));
|
||
|
free(sciezka);
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
close(plik);
|
||
|
if ((klucz_kolejka = ftok(sciezka, 1)) == -1)
|
||
|
{
|
||
|
perror("Serwer: Blad funkcji ftok.\n");
|
||
|
if (czy_skasowac)
|
||
|
{
|
||
|
unlink(sciezka);
|
||
|
}
|
||
|
free(sciezka);
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((f = msgget(klucz_kolejka, 0600 | IPC_CREAT | IPC_EXCL)) == -1)
|
||
|
{
|
||
|
perror("Serwer: Blad funkcji msgget.\n");
|
||
|
if (czy_skasowac)
|
||
|
{
|
||
|
unlink(sciezka);
|
||
|
}
|
||
|
free(sciezka);
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (;;)
|
||
|
{
|
||
|
wiad = (paczka1 *)malloc(sizeof(paczka1));
|
||
|
if ((liczba_bajtow = msgrcv(f, wiad, wielkosc1, 1, 0)) == -1)
|
||
|
{
|
||
|
perror("Serwer: Blad funkcji msgrcv.\n");
|
||
|
if (czy_skasowac)
|
||
|
{
|
||
|
unlink(sciezka);
|
||
|
}
|
||
|
free(sciezka);
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("Serwer: Przeczytalem %ld bajtow od klienta na glownej kolejce.\n", liczba_bajtow);
|
||
|
if ((pid = fork()) == -1)
|
||
|
{
|
||
|
perror("Serwer: Wywolanie funkcji fork nie powiodlo sie.\n");
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pid == 0)
|
||
|
{
|
||
|
int f1;
|
||
|
|
||
|
if ((klucz_kolejka = ftok(sciezka, wiad->pid)) == -1)
|
||
|
{
|
||
|
free(sciezka);
|
||
|
perror("Serwer, proces potomny: Blad funkcji ftok.\n");
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((f1 = msgget(klucz_kolejka, 0600)) == -1)
|
||
|
{
|
||
|
perror("Serwer, proces potomny : Nie moge utworzyc kolejki komunikatow dla klienta.\n");
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
paczka2 *praca = (paczka2 *)malloc(sizeof(paczka2));
|
||
|
const size_t wielkosc2 = sizeof(paczka2) - sizeof(long);
|
||
|
|
||
|
if ((liczba_bajtow = msgrcv(f1, praca, wielkosc2, 2, 0)) == -1)
|
||
|
{
|
||
|
perror("Serwer, proces potomny: Blad funkcji msgrcv.\n");
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("Serwer, proces potomny: Przeczytalem %ld bajtow od klienta.\n", liczba_bajtow);
|
||
|
praca->melement *= praca->melement;
|
||
|
praca->mtype = 3;
|
||
|
if ((liczba_bajtow = msgsnd(f1, praca, wielkosc2, 0)) == -1)
|
||
|
{
|
||
|
perror("Serwer, proces potomny: Blad funkcji msgsnd.\n");
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
free(praca);
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sigignore(SIGCHLD);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|