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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Linux ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ…Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 126

Автор Роббинс ΠΡ€Π½ΠΎΠ»ΡŒΠ΄

Когда Π»Π΅Π²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΌΠΎΠΊ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ, ΠΎΠ½ заканчиваСтся. БистСма послС этого Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ всС Π΅Π³ΠΎ дСскрипторы Ρ„Π°ΠΉΠ»ΠΎΠ². Когда это случаСтся, ΠΏΡ€Π°Π²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΌΠΎΠΊ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π² ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΌ счСтС ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π° ΠΈ Ρ‚ΠΎΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΈ Π²Ρ‹ΠΉΡ‚ΠΈ.

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°,

ch09-pipeline.c
, создаСт эквивалСнт ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ:

$ <b>echo hi there | sed s/hi/hello/g</b>

hello there

Π’ΠΎΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°:

1 Β /* ch09-pipeline.c --- отвСтвляСт Π΄Π²Π° процСсса Π² ΠΈΡ… собствСнный ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€.

2Β Β Β Β  Для краткости ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ошибок свСдСна ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌΡƒ. */

3

4Β  #include &lt;stdio.h&gt;

5Β  #include &lt;errno.h&gt;

6Β  #include &lt;sys/types.h&gt;

7Β  #include &lt;sys/wait.h&gt;

8 Β #include &lt;unistd.h&gt;

9

10 int pipefd[2];

11

12 extern void left_child(void), right_child(void);

13

14 /* main --- ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ процСссов ΠΈ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ ΠΈΡ… Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ */

15

16 int main(int argc, char **argv)

17 {

18Β  pid_t left_pid, right_pid;

19Β  pid_t ret;

20Β  int status;

21

22Β  if (pipe(pipefd) &lt; 0) { /* ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠ°Π½Π°Π» Π² самом Π½Π°Ρ‡Π°Π»Π΅ */

23Β Β  perror(&quot;pipe&quot;);

24Β Β  exit(1);

25Β  }

26

27Β  if ((left_pid = fork()) &lt; 0) { /* ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π»Π΅Π²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ° */

28Β  Β perror(&quot;fork&quot;);

29Β  Β exit(1);

30Β  } else if (left_pid == 0)

31 Β left_child();

32

33Β  if ((right_pid = fork()) &lt; 0) { /* ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ° */

34Β Β  perror(&quot;fork&quot;);

35Β Β  exit(1);

36Β  } else if (right_pid == 0)

37Β  right_child();

38

39Β  close(pipefd[0])); /* Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ ΠΊΠΎΠΏΠΈΠΈ ΠΊΠ°Π½Π°Π»Π° */

40Β  close(pipefd[1]);

41

42Β  while ((ret = wait(&amp;status)) &gt; 0) { /* wait for children */

43Β Β  if (ret == left_pid)

44Β Β Β  printf(&quot;left child terminated, status: %x\n&quot;, status);

45Β Β  else if (ret == right_pid)

46Β Β Β  printf(&quot;right child terminated, status: %x\n&quot;, status);

47Β Β  else

48Β Β Β  printf(&quot;yow! unknown child %d terminated, status %x\n&quot;,

49Β Β Β Β  ret, status);

50Β Β }

51

52Β  return 0;

53 }

Π‘Ρ‚Ρ€ΠΎΠΊΠΈ 22–25 ΡΠΎΠ·Π΄Π°ΡŽΡ‚ ΠΊΠ°Π½Π°Π». Π­Ρ‚ΠΎ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ сдСлано Π² самом Π½Π°Ρ‡Π°Π»Π΅.

Π‘Ρ‚Ρ€ΠΎΠΊΠΈ 27–31 ΡΠΎΠ·Π΄Π°ΡŽΡ‚ Π»Π΅Π²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ°, Π° строки 33–37 ΡΠΎΠ·Π΄Π°ΡŽΡ‚ ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ°. Π’ ΠΎΠ±ΠΎΠΈΡ… случаях Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠ΅ исполнСниС Π²Π΅Ρ‚Π²ΠΈ

main()
Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½Π½Ρ‹ΠΉ процСсс Π½Π΅ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для манипулирования дСскрипторами Ρ„Π°ΠΉΠ»Π° ΠΈ осущСствлСния
exec
.

Π‘Ρ‚Ρ€ΠΎΠΊΠΈ 39–40 Π·Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΡƒΡŽ копию ΠΊΠ°Π½Π°Π»Π°.

Π‘Ρ‚Ρ€ΠΎΠΊΠΈ 42–50 Π² Ρ†ΠΈΠΊΠ»Π΅ ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‚ ΠΏΠΎΡ‚ΠΎΠΌΠΊΠΎΠ², ΠΏΠΎΠΊΠ°

wait()
Π½Π΅ Π²Π΅Ρ€Π½Π΅Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ.

55 /* left_child --- осущСствляСт Ρ€Π°Π±ΠΎΡ‚Ρƒ Π»Π΅Π²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ° */

56

57 void left_child(void)

58 {

59Β  static char *left_argv[] = { &quot;echo&quot;, &quot;hi&quot;, &quot;there&quot;, NULL };

60

61Β  close(pipefd[0]);

62Β  close(1);

63 Β dup(pipefd[1]);

64Β  close(pipefd[1]);

65

66Β  execvp(&quot;echo&quot;, left_argv);

67Β  _exit(errno == ENOENT ? 127 : 126);

68 }

69

70 /* right_child --- осущСствляСт Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ° */

71

72 void right_child(void)

73 {

74 Β static char *right_argv[] = { &quot;sed&quot;, &quot;s/hi/hello/g&quot;, NULL };

75

76Β  close(pipefd[1]);

77Β  close(0);

78Β  dup(pipefd[0]);

79Β  close(pipefd[0]));

80

81Β  execvp(&quot;sed&quot;, right_argv);

82Β  _exit(errno == ENOENT ? 127 : 126);

83 }

Π‘Ρ‚Ρ€ΠΎΠΊΠΈ 57–68 ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΊΠΎΠ΄ΠΎΠΌ для Π»Π΅Π²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ°. ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° слСдуСт ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΌ Π²Ρ‹ΡˆΠ΅ шагам, закрывая Π½Π΅Π½ΡƒΠΆΠ½Ρ‹ΠΉ ΠΊΠΎΠ½Π΅Ρ† ΠΊΠ°Π½Π°Π»Π°, закрывая ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΉ стандартный Π²Ρ‹Π²ΠΎΠ΄, помСщая с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ

dup()
записываСмый ΠΊΠΎΠ½Π΅Ρ† ΠΊΠ°Π½Π°Π»Π° Π½Π° Π½ΠΎΠΌΠ΅Ρ€ 1 ΠΈ закрывая Π·Π°Ρ‚Π΅ΠΌ ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΉ записываСмый ΠΊΠΎΠ½Π΅Ρ†. Π’ этот ΠΌΠΎΠΌΠ΅Π½Ρ‚ строка 66 Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚
execvp()
, ΠΈ Ссли ΠΎΠ½Π° Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ Π½Π΅ΡƒΠ΄Π°Ρ‡Π΅ΠΉ, строка 67 Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚
_exit()
. (ΠŸΠΎΠΌΠ½ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ строка 67 Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ выполняСтся, Ссли
execvp()
Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ ΡƒΠ΄Π°Ρ‡Π½ΠΎ.)