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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π² срСдС Linux. Π’Ρ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 78

Автор Майкл ДТонсон

fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);

Π§Π΅Ρ‚Ρ‹Ρ€Π΅ Ρ„Π»Π°Π³Π° termios ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΡŽΡ‚ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… части управлСния Π²Π²ΠΎΠ΄ΠΎΠΌ ΠΈ Π²Ρ‹Π²ΠΎΠ΄ΠΎΠΌ. Π€Π»Π°Π³ Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, с_iflag, опрСдСляСт, ΠΊΠ°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ принятыС символы. Π€Π»Π°Π³ Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, c_oflag, опрСдСляСт, ΠΊΠ°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ символы, записываСмыС вашим процСссом Π² tty. Π£ΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ Ρ„Π»Π°Π³, c_cflag, опрСдСляСт характСристики ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° устройства ΠΈ ΠΏΠΎΠ»Π΅Π·Π΅Π½ лишь для физичСских устройств. Π›ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ„Π»Π°Π³, c_lflag, опрСдСляСт, ΠΊΠ°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ символы ΡΠΎΠ±ΠΈΡ€Π°ΡŽΡ‚ΡΡ ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…. На рис. 16.1 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° упрощСнная схСма Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊΠΎΠ΅ мСсто Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ„Π»Π°Π³ Π² ΠΎΠ±Ρ‰Π΅ΠΉ схСмС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ символов.

Рис. 16.1. УпрощСнная схСма ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ tty

Π‘Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ продСмонстрируСм способы примСнСния termios, Π° Π·Π°Ρ‚Π΅ΠΌ прСдставим ΠΊΠΎΡ€ΠΎΡ‚ΠΊΡƒΡŽ справку ΠΎ Π½Π΅ΠΌ.

16.3. ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования termios

16.3.1. ΠŸΠ°Ρ€ΠΎΠ»ΠΈ

Π‘Π°ΠΌΠΎΠΉ распространСнной ΠΏΡ€ΠΈΡ‡ΠΈΠ½ΠΎΠΉ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ установок termios являСтся Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ пароля Π±Π΅Π· эхо-контроля символов. Для этого слСдуСт ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ локальноС эхо Π²ΠΎ врСмя чтСния пароля. Π’Π°Ρˆ ΠΊΠΎΠ΄ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

struct termios ts, ots;

ΠŸΠ΅Ρ€Π²Π°Ρ структура Ρ…Ρ€Π°Π½ΠΈΡ‚ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ установки для восстановлСния, Π° вторая являСтся ΠΊΠΎΠΏΠΈΠ΅ΠΉ для ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ.

tcgetattr(STDIN_FILENO, &ts);

ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΏΠ°Ρ€ΠΎΠ»ΠΈ Ρ‡ΠΈΡ‚Π°ΡŽΡ‚ΡΡ со стандартного устройства Π²Π²ΠΎΠ΄Π°.

ots = ts;

Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΡ‚Π΅ копию ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹Ρ… установок termios, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ·ΠΆΠ΅ Π²ΠΎΡΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΈΡ….

ts.c_lflag &= ~ECHO;

ts.c_lflag |= ECHONL;

tcsetattr(STDIN_FILENO, TCSAFLUSH, fits);

ΠžΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ эхо-ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ символов (ΠΊΡ€ΠΎΠΌΠ΅ символов Π½ΠΎΠ²ΠΎΠΉ строки) послС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ всСх Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…. (ΠŸΠ΅Ρ€Π²Π°Ρ l Π² c_lflag ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Π»ΠΎΠΊΠ°Π»ΡŒΠ½ΡƒΡŽ (local) ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ.)

read_password();

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π²Ρ‹ Ρ‡ΠΈΡ‚Π°Π΅Ρ‚Π΅ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ простой Π²Ρ‹Π·ΠΎΠ² fgets() ΠΈΠ»ΠΈ read(), Π»ΠΈΠ±ΠΎ ΠΆΠ΅ Π±ΠΎΠ»Π΅Π΅ слоТная ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°, Π² зависимости ΠΎΡ‚ Ρ€Π΅ΠΆΠΈΠΌΠ° tty (Π½Π΅Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ ΠΈΠ»ΠΈ Ρ€Π΅ΠΆΠΈΠΌ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ) ΠΈ ΠΎΡ‚ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

tcsetattr(STDIN_FILENO, TCSANOW, &ots);

Π­Ρ‚ΠΎ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ восстанавливаСт исходныС установки termios. (ΠžΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠΏΡ†ΠΈΠΈ ΠΎΠ±ΡŠΡΡΠ½ΡΡŽΡ‚ΡΡ ΠΏΠΎΠ·ΠΆΠ΅, Π² справочном Ρ€Π°Π·Π΄Π΅Π»Π΅ Π΄Π°Π»Π΅Π΅ Π² Π³Π»Π°Π²Π΅.)

ΠŸΠΎΠ»Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹-ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°, readpass, ΠΏΠΎΠΊΠ°Π·Π°Π½ Π½ΠΈΠΆΠ΅.

 1: /* readpass.с */

 2:

 3: #include <stdio.h>

 4: #include <stdlib.h>

 5: #include <termios.h>

 6: #include <unistd.h>

 7:

 8: int main (void) {

 9:  struct termios ts, ots;

10:  char passbuf[1024];

11:

12:  /* ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΈ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠ΅ настройки termios */

13:  tcgetattr(STDIN_FILENO, &ts);

14:  ots = ts;

15:

16:  /* ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΈ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π½ΠΎΠ²Ρ‹Π΅ настройки termios */

17:  ts.c_lflag & = ~ECHO;

18:  ts.c_lflag |= ECHONL;

19:  tcsetattr(STDIN_FILENO, TCSAFLUSH, &ts);

20:

21:  /*Ρ…ΠΎΡ‚ΡŒ это ΠΈ ΠΏΠ°Ρ€Π°Π½ΠΎΠΈΠ΄Π°Π»ΡŒΠ½ΠΎ, Π½ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Π²ΠΎΠ·Ρ‹ΠΌΠ΅Π»ΠΈ Π»ΠΈ эффСкт Π½ΠΎΠ²Ρ‹Π΅ настройки*/

22:  tcgetattr(STDIN_FILENO, &ts);

23:  if (ts.c_lflag & ECHO) {

24:   fprintf(stderr, "Π‘Π±ΠΎΠΉ ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ эхо-контроля\n");

25:   tcsetattr(STDIN_FILENO, TCSANOW, &ots);

26:   exit(1);

27:  }

28:

29:  /* ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΈ вывСсти ΠΏΠ°Ρ€ΠΎΠ»ΡŒ */

30:  printf("Π²Π²Π΅Π΄ΠΈΡ‚Π΅ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ:");

31:  fflush(stdout);

32:  fgets(passbuf, 1024, stdin);

33:  printf("ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ: %s", passbuf);

34:  /* Π² passbuf Π±Ρ‹Π» Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΠΈΠΉ символ \n */

35:

36:  /* Π²ΠΎΡΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ старыС настройки termios */

37:  tcsetattr(STDIN_FILENO, TCSANOW, &ots);

38:

39:  exit(0);

40: }

16.3.2. ΠŸΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΊΠΎΠΌΠΌΡƒΠ½ΠΈΠΊΠ°Ρ†ΠΈΠΈ

Π’ качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° программирования ΠΎΠ±ΠΎΠΈΡ… ΠΊΠΎΠ½Ρ†ΠΎΠ² tty рассмотрим ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰ΡƒΡŽ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π» ΠΊ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΌΡƒ ΠΏΠΎΡ€Ρ‚Ρƒ. На ΠΎΠ΄Π½ΠΎΠΌ tty ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠΎΠ΄ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ robin сообщаСтся с Π²Π°ΠΌΠΈ Π²ΠΎ врСмя Π½Π°Π±ΠΎΡ€Π°. На Π΄Ρ€ΡƒΠ³ΠΎΠΌ tty ΠΎΠ½Π° взаимодСйствуСт с ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ€Ρ‚ΠΎΠΌ. Π‘ Ρ†Π΅Π»ΡŒΡŽ ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΏΠ»Π΅ΠΊΡΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ Π²Π²ΠΎΠ΄Π½Ρ‹Ρ… ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… Π½Π° локальном tty ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΌ ΠΏΠΎΡ€Ρ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ систСмный Π²Ρ‹Π·ΠΎΠ² poll(), описанный Π² Π³Π»Π°Π²Π΅ 13.

НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΏΠΎΠ»Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ robin.с, Π·Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π΄Π°Π½Ρ‹ объяснСния.

  1: /* robin.с */

  2:

  3: #include <sys/poll.h>

  4: #include <errno.h>

  5: #include <fcntl.h>

  6: #include <popt.h>

  7: #include <stdio.h>

  8: #include <stdlib.h>

  9: #include <signal.h>

 10: #include <string.h> /* для strerror() */

 11: #include <termios.h>

 12: #include <unistd.h>

 13:

 14: void die(int exitcode, const char *error, const char *addl) {

 15:  if (error) fprintf(stderr, "%s: %s\n", error, addl);

 16:  exit(exitcode);

 17: }

 18:

 19: speed_t symbolic_speed(int speednum) {

 20:  if (speednum >= 460800) return B460800;

 21:  if (speednum >= 230400) return B230400;

 22:  if (speednum >= 115200) return B115200;

 23:  if (speednum >= 57600) return B57600;

 24:  if (speednum >= 38400) return B38400;

 25:  if (speednum >= 19200) return B19200;

 26:  if (speednum >= 9600) return B9600;

 27:  if (speednum >= 4800) return B4800;

 28:  if (speednum >= 2400) return B2400;

 29:  if (speednum >= 1800) return B1800;

 30:  if (speednum >= 1200) return B1200;

 31:  if (speednum >= 600) return B600;

 32:  if (speednum >= 300) return B300;

 33:  if (speednum >= 200) return B200;

 34:  if (speednum >= 150) return B150;

 35:  if (speednum >= 134) return B134;

 36:  if (speednum >= 110) return B110;

 37:  if (speednum >= 75) return B75;

 38:  return B50;

 39: }

 40:

 41: /* Π­Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ для области видимости Π² ΠΏΡ€Π΅Π΄Π΅Π»Π°Ρ… Ρ„Π°ΠΉΠ»Π°, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ

 42:  * ΠΈΡ… ΠΌΠΎΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°Ρ… сигналов */

 43: /* старыС настройки ΠΏΠΎΡ€Ρ‚Π° termios для восстановлСния */

 44: static struct termios pots;

 45: /* старыС настройки stdout/stdin termios для восстановлСния */

 46: static struct termios sots;

 47: /* Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ дСскриптор ΠΏΠΎΡ€Ρ‚Π° */

 48: int pf;

 49:

 50: /* Π²ΠΎΡΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹Π΅ настройки Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π° ΠΏΡ€ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π΅ */

 51: void cleanup_termios(int signal) {

 52:  tcsetattr(pf, TCSANOW, &pots);

 53:  tcsetattr(STDIN_FILENO, TCSANOW, &sots);

 54:  exit(0);

 55: }

 56:

 57: /* ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹ΠΉ ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ символ */

 58: void send_escape(int fd, char c) {

 59:  switch (c) {

 60:  case 'q':

 61:   /* Π²ΠΎΡΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ настройки termios ΠΈ Π²Ρ‹ΠΉΡ‚ΠΈ */

 62:   cleanup_termios(0);

 63:   break;

 64:  case 'b':

 65:   /* ΠΏΠΎΡΠ»Π°Ρ‚ΡŒ символ Ρ€Π°Π·Ρ€Ρ‹Π²Π°*/

 66:   tcsendbreak(fd, 0);

 67:   break;

 68:  default:

 69:   /* ΠΏΡ€ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ символ */

 70:   /* "C-\ C-\" sends "C-\" */

 71:   write(fd, &c, 1);

 72:   break;

 73:  }

 74:  return;

 75: }

 76:

 77: /* ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠ΅ символы, записывая ΠΈΡ… Π² Π²Ρ‹Π²ΠΎΠ΄ */

 78: void cook_buf(int fd, char * buf, int num) {

 79:  int current = 0;

 80:  static int in_escape = 0;

 81:

 82:  if (in_escape) {

 83:   /* cook_buf послСдний Ρ€Π°Π· вызывался с Π½Π΅Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎΠΉ

 84:      ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰Π΅ΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒΡŽ */

 85:   send_escape(fd, buf[0]);

 86:   num--;

 87:   buf++;

 88:   in_escape = 0;

 89:  }

 90:  while (current < num) {

 91: # define CTRLCHAR(c) ((c)-0x40)

 92:   while ((current < num) && (buf[current] != CTRLCHAR('W')))

 93:    current++;

 94:   if (current) write (fd, buf, current);

 95:   if (current < num) {

 96:    /* Π½Π°ΠΉΠ΄Π΅Π½ ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ символ */

 97:    current++;

 98:    if (current >= num) {

 99:     /*ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ символ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ*/

100:     in_escape = 1;

101:     return;

102:    }

103:    send_escape(fd, buf[current]);

104:   }

105:   num -= current;

106:   buf += current;

107:   current = 0;

108:  }

109:  return;

110: }

111:

112: int main(int argc, const char * argv[]) {

113:  char с; /* ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Ρ€Π°Π·Π±ΠΎΡ€Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² */

114:  struct termios pts; /* настройки termios для ΠΏΠΎΡ€Ρ‚Π° */

115:  struct termios sts; /* настройки termios для stdout/stdin */

116:  const char *portname;

117:  int speed = 0; /* ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΡ€ΠΈ Ρ€Π°Π·Π±ΠΎΡ€Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² для скорости */

118:  struct sigaction sact; /* ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сигналов */