Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX: взаимодСйствиС процСссов». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 18

Автор Уильям БтивСнс

Рис. 4.12. Один сСрвСр, нСсколько ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ²


Π‘Π΅Ρ€Π²Π΅Ρ€ создаСт ΠΊΠ°Π½Π°Π» с извСстным ΠΏΠΎΠ»Π½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ, Π² Π΄Π°Π½Π½ΠΎΠΌ случаС /tmp/fifΠΎ.serv. Из этого ΠΊΠ°Π½Π°Π»Π° ΠΎΠ½ считываСт запросы ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ². ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΡ€ΠΈ запускС создаСт свой собствСнный ΠΊΠ°Π½Π°Π», ΠΏΠΎΠ»Π½ΠΎΠ΅ имя ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ опрСдСляСтся Π΅Π³ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠΌ процСсса. ΠšΠ»ΠΈΠ΅Π½Ρ‚ отправляСт свой запрос Π² ΠΊΠ°Π½Π°Π» сСрвСра с извСстным ΠΈΠΌΠ΅Π½Π΅ΠΌ, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ запрос этот содСрТит ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ процСсса ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈ имя Ρ„Π°ΠΉΠ»Π°, ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΡƒ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ Ρƒ сСрвСра. Π’ листингС 4.10 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ сСрвСра.

Листинг 4.10. Π‘Π΅Ρ€Π²Π΅Ρ€, ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ нСсколько ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠ°Π½Π°Π»Π° FIFO

//fifocliserv/mainserver.с

1  #include "fifo.h"

2  void server(int, int);

3  int

4  main(int argc, char **argv)

5  {

6   int readfifo, writefifo, dummyfd, fd;

7   char *ptr, buff[MAXLINE], fifoname[MAXLINE];

8   pid_t pid;

9   ssize_t n;

10  /* созданиС FIFO сСрвСра с извСстным ΠΈΠΌΠ΅Π½Π΅ΠΌ. ОК, Ссли ΡƒΠΆΠ΅ сущСствуСт */

11  if ((mkfifo(SERV_FIFO, FILE_MODE) < 0) && (errno != EEXIST))

12   err_sys("can't create %s", SERV_FIFO);

13  /* ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ FIFO-cepΠ²epa Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ */

14  readfifo = Open(SERV_FIFO, O_RDONLY, 0);

15  dummyfd = Open(SERV_FIFO, O_WRONLY, 0); /* Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ */

16  while ((n = Readline(readfifo, buff, MAXLINE)) > 0) {

17   if (buff[n-1] == '\n')

18    n--; /* delete newline from readline() */

19   buff[n] = '\0'; /* ΠΏΠΎΠ»Π½ΠΎΠ΅ имя, Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅ΠΌΠΎΠ΅ 0 */

20   if ((ptr = strchr(buff, ' ')) == NULL) {

21    err_msg("bogus request: ls", buff);

22    continue;

23   }

24   *ptr++ = 0; /* ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ процСсса, ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° имя Ρ„Π°ΠΉΠ»Π° */

25   pid = atol(buff);

26   snprintf(fifoname, sizeof(fifoname), "/tmp/fifo.%ld", (long) pid);

27   if ( (writefifo = open(fifoname, O_WRONLY, 0)) < 0) {

28    err_msg("cannot open: ls", fifoname);

29    continue;

30   }

31   if ((fd = open(ptr, O_RDONLY)) < 0) {

32    /* ошибка, Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ */

33    snprintf(buff + n, sizeof(buff) – n, ": can't open, %s\n",

34     strerror(errno));

35    n = strlen(ptr);

36    Write(writefifo, ptr, n);

37    Close(writefifo);

38

39   } else {

40    /* ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ΅ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅, ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Ρ„Π°ΠΉΠ» */

41    while ((n = Read(fd, buff, MAXLINE)) > 0)

42     Write(writefifo, buff, n);

43    Close(fd);

44    Close(writefifo);

45   }

46  }

47 }

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΊΠ°Π½Π°Π»Π° ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Π΅Π³ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для записи ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния

10-15 Π‘Π΅Ρ€Π²Π΅Ρ€ создаСт ΠΊΠ°Π½Π°Π» FIFO с извСстным ΠΈΠΌΠ΅Π½Π΅ΠΌ, обрабатывая ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ, ΠΊΠΎΠ³Π΄Π° Ρ‚Π°ΠΊΠΎΠΉ ΠΊΠ°Π½Π°Π» ΡƒΠΆΠ΅ сущСствуСт. Π—Π°Ρ‚Π΅ΠΌ этот ΠΊΠ°Π½Π°Π» открываСтся Π΄Π²Π°ΠΆΠ΄Ρ‹: ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния, Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ β€” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для записи. ДСскриптор readfifo ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΏΡ€ΠΈΠ΅ΠΌΠ° запросов ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ², Π° дСскриптор dummyfd Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ вовсС. ΠŸΡ€ΠΈΡ‡ΠΈΠ½Π°, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ ΠΊΠ°Π½Π°Π» для записи, Π²ΠΈΠ΄Π½Π° ΠΈΠ· Ρ‚Π°Π±Π». 4.1. Если ΠΊΠ°Π½Π°Π» Π½Π΅ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ Π½Π° запись, Ρ‚ΠΎ ΠΏΡ€ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° этот ΠΊΠ°Π½Π°Π» Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡƒΡΡ‚ΠΎΡˆΠ°Ρ‚ΡŒΡΡ ΠΈ сСрвСр Π±ΡƒΠ΄Π΅Ρ‚ ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ 0, ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ½Π΅Ρ† Ρ„Π°ΠΉΠ»Π°. ΠŸΡ€ΠΈΡˆΠ»ΠΎΡΡŒ Π±Ρ‹ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· Π·Π°ΠΊΡ€Ρ‹Π²Π°Ρ‚ΡŒ ΠΊΠ°Π½Π°Π» Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ close, Π° Π·Π°Ρ‚Π΅ΠΌ Π·Π°Π½ΠΎΠ²ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Ρ‚ΡŒ Π΅Π³ΠΎ с Ρ„Π»Π°Π³ΠΎΠΌ O_RDONLY, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΠ»ΠΎ Π±Ρ‹ ΠΊ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ Π΄Π΅ΠΌΠΎΠ½Π° Π΄ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. ΠœΡ‹ ΠΆΠ΅ всСгда Π±ΡƒΠ΄Π΅ΠΌ ΠΈΠΌΠ΅Ρ‚ΡŒ дСскриптор, ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ Π½Π° запись, поэтому функция read Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ 0, ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ½Π΅Ρ† Ρ„Π°ΠΉΠ»Π°, ΠΏΡ€ΠΈ отсутствии ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ². ВмСсто этого сСрвСр просто Π±ΡƒΠ΄Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ read, оТидая ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Π­Ρ‚ΠΎΡ‚ Ρ‚Ρ€ΡŽΠΊ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ ΠΊΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹-сСрвСра ΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ количСство Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² open для ΠΊΠ°Π½Π°Π»Π° сСрвСра.

ΠŸΡ€ΠΈ запускС сСрвСра ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² open (с Ρ„Π»Π°Π³ΠΎΠΌ O_RDONLY) ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ процСсса Π΄ΠΎ появлСния ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΊΠ°Π½Π°Π» сСрвСра Π½Π° запись (см. Ρ‚Π°Π±Π». 4.1). Π’Ρ‚ΠΎΡ€ΠΎΠΉ Π²Ρ‹Π·ΠΎΠ² open (с Ρ„Π»Π°Π³ΠΎΠΌ O_WRONLY) Π½Π΅ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΊΠ°Π½Π°Π» ΡƒΠΆΠ΅ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ Π½Π° запись. 

Π‘Ρ‡ΠΈΡ‚Ρ‹Π²Π°Π½ΠΈΠ΅ запроса ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

16 ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ запрос, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌΡ‹ΠΉ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, прСдставляСт собой ΠΎΠ΄Π½Ρƒ строку, ΡΠΎΡΡ‚ΠΎΡΡ‰ΡƒΡŽ ΠΈΠ· ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° процСсса, ΠΏΡ€ΠΎΠ±Π΅Π»Π° ΠΈ ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°. Π­Ρ‚Π° строка считываСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ readline (ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΉ Π² [24, с.79]).

Анализ запроса ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

17-26 Π‘ΠΈΠΌΠ²ΠΎΠ» ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° строки, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ readline, удаляСтся. Π­Ρ‚ΠΎΡ‚ символ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ‚ΠΎΠΌ случаС, Ссли Π±ΡƒΡ„Π΅Ρ€ Π±Ρ‹Π» Π·Π°ΠΏΠΎΠ»Π½Π΅Π½, ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Π±Ρ‹Π» ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ символ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° строки, Π»ΠΈΠ±ΠΎ Ссли послСдняя ввСдСнная строка Π½Π΅ Π±Ρ‹Π»Π° Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° этим символом. Ѐункция strchr Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΡ€ΠΎΠ±Π΅Π» Π² этой строкС, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°Ρ‚Π΅ΠΌ увСличиваСтся Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π» Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ символ ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ Ρ„Π°ΠΉΠ»Π°, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ Π·Π° ΠΏΡ€ΠΎΠ±Π΅Π»ΠΎΠΌ. ПолноС имя ΠΊΠ°Π½Π°Π»Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° формируСтся ΠΈΠ· Π΅Π³ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° процСсса, ΠΈ этот ΠΊΠ°Π½Π°Π» открываСтся сСрвСром Π½Π° запись.

ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Π΅Π³ΠΎ Π² FIFO ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

27-44 ΠžΡΡ‚Π°Π²ΡˆΠ°ΡΡΡ Ρ‡Π°ΡΡ‚ΡŒ ΠΊΠΎΠ΄Π° ΠΏpoΠ³Ρ€aΠΌΠΌΡ‹-cepΠ²epa Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ server ΠΈΠ· листинга 4.3. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Ρ„Π°ΠΉΠ»; Ссли ΠΏΡ€ΠΈ этом Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ ошибка β€” ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ отсылаСтся сообщСниС ΠΎ Π½Π΅ΠΉ. Если ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, Π΅Π³ΠΎ содСрТимоС копируСтся Π² ΠΊΠ°Π½Π°Π» ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. ПослС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ копирования ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ сСрвСром Β«ΠΊΠΎΠ½Π΅Ρ†Β» (дСскриптор) ΠΊΠ°Π½Π°Π»Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΊΡ€Ρ‹Ρ‚ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ close, Ρ‡Ρ‚ΠΎΠ±Ρ‹ функция read Π²Π΅Ρ€Π½ΡƒΠ»Π° ΠΏpoΠ³Ρ€aΠΌΠΌe-ΠΊΠ»ΠΈeΠ½Ρ‚y Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 0 (ΠΊΠΎΠ½Π΅Ρ† Ρ„Π°ΠΉΠ»Π°). Π‘Π΅Ρ€Π²Π΅Ρ€ Π½Π΅ удаляСт ΠΊΠ°Π½Π°Π» ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°; ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠΎΠ·Π°Π±ΠΎΡ‚ΠΈΡ‚ΡŒΡΡ ΠΎΠ± этом послС ΠΏΡ€ΠΈΠ΅ΠΌΠ° ΠΎΡ‚ сСрвСра символа ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π°. ВСкст ΠΏpoΠ³Ρ€aΠΌΠΌΡ‹-ΠΊΠ»ΠΈeΠ½Ρ‚a ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π² листингС 4.11.

Листинг 4.11. ΠšΠ»ΠΈΠ΅Π½Ρ‚, ΡΠ²ΡΠ·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉΡΡ с сСрвСром (листинг 4.10) с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠ°Π½Π°Π»Π° FIFO

//fifocliserv/mainclient.с

1  #include "fifo.h"

2  int

3  main(int argc, char **argv)

4  {

5   int readfifo, writefifo;

6   size_t len;

7   ssize_t n;

8   char *ptr, fifoname[MAXLINE], buff[MAXLINE];

9   pid_t pid;

10  /* созданиС FIFO с Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Π² Π΅Π³ΠΎ имя PID */

11  pid = getpid();

12  snprintf(fifoname, sizeof(fifoname), "/tmp/fifo,%ld", (long) pid):

13  if ((mkfifo(fifoname, FILE_MODE) < 0) && (errno != EEXIST))

14   err_sys("can't create %s", fifoname);

15  /* инициализация Π±ΡƒΡ„Π΅Ρ€Π° PID ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»ΠΎΠΌ */

16  snprintf(buff, sizeof(buff), "%ld ", (long) pid);

17  len = strlen(buff);

18  ptr = buff + len;

19  /* считываниС ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ */

20  Fgets(ptr, MAXLINE – len, stdin);

21  len = strlen(buff); /* fgets() Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΠΈΠΉ 0 */

22  /* ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ FIFO сСрвСра ΠΈ запись Π² Π½Π΅Π³ΠΎ ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ ΠΈ PID */

23  writefifo = Open(SERV_FIFO, O_WRONLY, 0);

24  Write(writefifo, buff, len);

25  /* ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ созданного FIFO; Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π΄ΠΎ открытия Π΅Π³ΠΎ сСрвСром */

26  readfifo = Open(fifoname, O_RDONLY; 0);

27  /* считываниС ΠΈΠ· ΠΊΠ°Π½Π°Π»Π° IPC, запись Π² stdout */

28  while ((n = Read(readfifo, buff, MAXLINE)) > 0)

29   Write(STDOUT_FILENO, buff, n);

30  Close(readfifo);

31  Unlink(fifoname);

32  exit(0);

33 }

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΊΠ°Π½Π°Π»Π°

10-14 Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ процСсса ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° содСрТится Π² ΠΈΠΌΠ΅Π½ΠΈ создаваСмого ΠΈΠΌ ΠΊΠ°Π½Π°Π»Π°.

Π€ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ строки запроса

15-21 Запрос ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° состоит ΠΈΠ· Π΅Π³ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° процСсса, ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ±Π΅Π»Π°, ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ ΠΈΠΌ Ρ„Π°ΠΉΠ»Π° ΠΈ символа ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° строки. Π‘Ρ‚Ρ€ΠΎΠΊΠ° запроса формируСтся Π² массивС buff, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ имя Ρ„Π°ΠΉΠ»Π° считываСтся ΠΈΠ· стандартного ΠΏΠΎΡ‚ΠΎΠΊΠ° Π²Π²ΠΎΠ΄Π°.

ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΊΠ°Π½Π°Π»Π° сСрвСра ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° запроса

22-24 ΠšΠ»ΠΈΠ΅Π½Ρ‚ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ ΠΊΠ°Π½Π°Π» сСрвСра ΠΈ записываСт Π² Π½Π΅Π³ΠΎ строку запроса. Если ΠΊΠ»ΠΈΠ΅Π½Ρ‚ окаТСтся ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ с ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° запуска сСрвСра, Π²Ρ‹Π·ΠΎΠ² open Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ сСрвСр, Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ послС сдСланного ΠΈΠΌ Π²Ρ‹Π·ΠΎΠ²Π° open (с Ρ„Π»Π°Π³ΠΎΠΌ O_RDONLY).

ΠŸΡ€ΠΈΠ΅ΠΌ содСрТимого Ρ„Π°ΠΉΠ»Π° ΠΈΠ»ΠΈ сообщСния ΠΎΠ± ошибкС ΠΎΡ‚ сСрвСра

25-31 ΠžΡ‚Π²Π΅Ρ‚ сСрвСра считываСтся ΠΈΠ· ΠΊΠ°Π½Π°Π»Π° ΠΈ записываСтся Π² стандартный ΠΏΠΎΡ‚ΠΎΠΊ Π²Ρ‹Π²ΠΎΠ΄Π°, послС Ρ‡Π΅Π³ΠΎ ΠΊΠ°Π½Π°Π» ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° закрываСтся ΠΈ* удаляСтся.

Π‘Π΅Ρ€Π²Π΅Ρ€ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΏΡƒΡ‰Π΅Π½ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ· ΠΎΠΊΠΎΠ½, Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ β€” Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ, ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ ΠΌΡ‹ ΠΈ рассчитывали. НиТС ΠΌΡ‹ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ тСкст, Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌΡ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ:

solaris % mainclient /etc/shadow          Ρ„Π°ΠΉΠ», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π°ΠΌ нСльзя Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ

/etc/shadow: can't open. Permission denied

solaris % mainclient /etc/inet/ntp.conf  Ρ„Π°ΠΉΠ» ΠΈΠ· Π΄Π²ΡƒΡ… строк

multicastclient 224.0.1.1

driftfile /etc/inet/ntp.drift 

ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Ρ‚Π°ΠΊΠΆΠ΅ ΡΠ²ΡΠ·Π°Ρ‚ΡŒΡΡ с сСрвСром ΠΈΠ· ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Π° ΠΊΠΎΠΌΠ°Π½Π΄, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΊΠ°Π½Π°Π»Ρ‹ FIFO ΠΎΠ±Π»Π°Π΄Π°ΡŽΡ‚ ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ Π² Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС.

solaris % Pid=$$

solaris % mkfifo /tmp/fifo.$Pid

solaris % echo "$Pid /etc/inet/ntp.conf" > /tmp/fifo.serv

solaris % cat < /tmp/fifo.$Pid

multicastclient 224.0.1.1

driftfile /etc/inet/ntp.drift

solaris % rm /tmp/fifo.$Pid

ΠœΡ‹ отсылаСм сСрвСру ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ процСсса Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΊΠΎΠΏΠΈΠΈ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Π° ΠΈ ΠΏΠΎΠ»Π½ΠΎΠ΅ имя Ρ„Π°ΠΉΠ»Π° ΠΎΠ΄Π½ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Π° (echo) ΠΈ считываСм ΠΈΠ· ΠΊΠ°Π½Π°Π»Π° сСрвСра Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ (cat). ΠœΠ΅ΠΆΠ΄Ρƒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ этих Π΄Π²ΡƒΡ… ΠΊΠΎΠΌΠ°Π½Π΄ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΠΉΡ‚ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΠΊ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, сСрвСр ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ содСрТимоС Ρ„Π°ΠΉΠ»Π° Π² ΠΊΠ°Π½Π°Π», Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°Ρ‚Π΅ΠΌ запускаСт ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ cat, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΡ‚Ρ‚ΡƒΠ΄Π° Π΄Π°Π½Π½Ρ‹Π΅. ΠœΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΠ°ΠΊΠΈΠΌ-Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ хранятся Π² ΠΊΠ°Π½Π°Π»Π΅, хотя ΠΎΠ½ Π½Π΅ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ Π½ΠΈ ΠΎΠ΄Π½ΠΈΠΌ процСссом. На самом Π΄Π΅Π»Π΅ всС Π½Π΅ Ρ‚Π°ΠΊ. ПослС закрытия ΠΏpoΠ³Ρ€aΠΌΠΌΠ½oΠ³o ΠΊΠ°Π½Π°Π»Π° ΠΈΠ»ΠΈ FIFO послСдним процСссом с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ close всС Π΄Π°Π½Π½Ρ‹Π΅, Π² Π½Π΅ΠΌ находящиСся, Ρ‚Π΅Ρ€ΡΡŽΡ‚ΡΡ. Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ сСрвСр, считав строку запроса ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, блокируСтся ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ ΠΊΠ°Π½Π°Π» ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ (наша копия ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Π°) Π΅Ρ‰Π΅ Π½Π΅ ΠΎΡ‚ΠΊΡ€Ρ‹Π» Π΅Π³ΠΎ Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ (вспомним Ρ‚Π°Π±Π». 4.1). Волько послС Π²Ρ‹Π·ΠΎΠ²Π° cat Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ врСмя спустя ΠΊΠ°Π½Π°Π» Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅, ΠΈ Ρ‚ΠΎΠ³Π΄Π° сСрвСр разблокируСтся. ΠšΡΡ‚Π°Ρ‚ΠΈ, Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ осущСствляСтся Π°Ρ‚Π°ΠΊΠ° Ρ‚ΠΈΠΏΠ° Β«ΠΎΡ‚ΠΊΠ°Π· Π² обслуТивании» (denial-of-service attack), ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΡ‹ обсудим Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅.