Программа - Файловый сервер
В структуре struct message содержится имя личного именованного канала вместе с именем требуемого файла.
Программа файлового сервера открывает на чтение общедоступный именованный канал. Он «спит» до тех пор, пока какой-нибудь процесс-клиент не откроет другой конец этого канала. Тогда сервер читает из общедоступного канала имена личного канала и требуемого файла в соответствующие поля структуры. Затем сервер открывает личный канал и требуемый файл. Содержимое файла копируется в канал, и файл закрывается.
Затем, закрыв общедоступный канал, программа снова открывает общедоступный канал и ждет обращение следующего клиента.
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include “server.h”
main (int argc, char **argv)
{
int fdpub, fdpriv, fd;
struct message msg; /*структура сообщения, которое читается из общедоступного именованного канала*/
int n;
char line[LINESIZE];
loop: /* бесконечный цикл */
/* Общедоступный канал открывается для чтения. Системный вызов open() блокируется, если никакой процесс-клиент не открывает другой конец канала*/
if ((fdpriv=open(msg.privfifo, O_RDONLY)) == -1)
{ perror (PUBLIC);
exit(1);
}
/* Из общедоступного канала читается сообщение, содержащее имена личного канала и */
/* требуемого файла. Требуемый файл открывается для чтения. */
while(read(fdpub, (char*)&msg, sizeof(msg)) > 0)
{
if ((fd=open(msg.filename, O_RDONLY)) == -1)
{ perror(msg.filename);
break;
}
/* Личный канал открывается для записи. Файловый сервер спит, пока клиент не откроет свой конец личного канала. Если возникли проблемы, и клиент не может открыть канал, сервер повиснет внутри этого open(). !см. соответствующие ключи, предотвращающие блокировки. */
if ((fdpriv=open(msg.privfifo, O_WRONLY)) == -1)
{ perror(msg.privfifo);
break;
}
/* данные из файла копируются в личный именованный канал */
while((n = read(fd, line, LINESIZE)) > 0)
write(fdpriv, line, n);
/* Когда копирование закончено, требуемый файл и личный именованный канал закрывается */
close (fd);
close (fdpriv);
}
/* end of first while() */
/* Закрыть общедоступный канал. Сервер переходит к следующему витку цикла. Причина для закрытия и повторного открытия состоит в том, что хочется, чтобы файловый сервер спал на open(), ожидая запросов. */
close (fdpub);
goto loop;
}
/* !Программа никогда не завершается */
Запуск клиента и сервера
% mkfifo public
(иначе сервер не находит обычный файл public, а в случае созданного именованного программного канала, он блокируется на open (файл public))
% server &
% client data
[распечатанный файл]