37: #define BUFSIZE 1024

 38:  char buf[1024];

 39:  struct termios ot, t;

 40:  struct winsize ws;

 41:  int done = 0;

 42:  struct sigaction act;

 43:

 44: if ((master = get_master_pty(&name)) < 0) {

 45:  perror('ptypair: не удается открыть ведущее устройство pty');

 46:  exit(1);

 47: }

 48:

 49: /* установить обработчик SIGWINCH */

 50:  act.sa_handler = sigwinch_handler;

 51:  sigemptyset(&(act.sa_mask));

 52:  act.sa_flags = 0;

 53:  if (sigaction (SIGWINCH, &act, NULL) < 0) {

 54:   perror('ptypair: невозможно обработать SIGWINCH');

 55:   exit(1);

 56:  }

 57:

 58:  if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0) {

 59:   perror('ptypair: не удается получить размеры окна');

 60:   exit(1);

 61:  }

 62:

 63:  if ((pid = fork()) < 0) {

 64:   perror('ptypair');

 65:   exit(1);

 66:  }

 67:

 68:  if (pid == 0) {

 69:   int slave; /* файловый дескриптор для подчиненного компонента pty*/

 70:

 71:   /* Мы находимся в дочернем процессе */

 72:   close(master);

 73:

 74:   if ((slave = get_slave_pty(name)) < 0) {

 75:    perror('ptypair: не удается открыть подчиненный компонент pty');

 76:    exit(1);

 77:   }

 78:   free(name);

 79:

 80:   /* Мы должны сделать этот процесс лидером группы сеансов,

 81:    * поскольку он выполняется на новом PTY, а функции вроде

 82:    * управления заданиями просто не будут корректно работать,

 83:    * если нет лидера группы сеансов и лидера группы процессов

 84:    * (который автоматически является лидером группы сеансов).

 85:    * Это также разъединяет со старым управляющим tty.

 86:    */

 87:   if (setsid() < 0) {

 88:    perror('невозможно установить лидер сеанса');

 89:   }

 90:

 91:   /* Соединиться с новым управляющим tty. */

 92:   if (ioctl(slave, TIOCSCTTY, NULL)) {

 93:    perror('невозможно установить новый управляющий tty');

 94:   }

 95:

 96:   /* сделать подчиненный pty стандартным устройством ввода, вывода и ошибок */

 97:   dup2(slave, STDIN_FILENO);

 98:   dup2(slave, STDOUT_FILENO);

 99:   dup2(slave, STDERR_FILENO);

100:

101:   /* в этой точке подчиненный pty должен быть стандартным устройством ввода */

102:   if (slave > 2) {

103:    close(slave);

104:   }

105:

106:   /* Попытаться восстановить размеры окна; сбой не является критичным */

107:   if (ioctl(STDOUT_FILENO, TIOCSWINSZ, &ws) < 0) {

108:    perror('не удается восстановить размеры окна');

109:   }

110:

111:   /* запустить оболочку */

112:   execl('/bin/sh', '/bin/sh', 0);

113:

114:   /* сюда управление никогда не попадет */

115:   exit(1);

116:  }

117:

118:  /* родительский процесс */

119:  free(name);

120:

121:  /* Обратите внимание, что настройки termios устанавливаются только

122:   * для стандартного ввода; ведущая сторона pty НЕ является tty.

123:   */

124:  tcgetattr(STDIN_FILENO, &ot);

125:  t = ot;

126:  t.c_lflag &= ~(ICANON | ISIG | ECHO | ECHOCTL | ECHOE |

127:   ECHOK | ECHOKE | ECHONL | ECHOPRT);

128:  t.c_iflag |= IGNBRK;

129:  t.c_cc[VMIN] = 1;

130:  t.c_cc[VTIME] = 0;

131:  tcsetattr(STDIN_FILENO, TCSANOW, &t);

132:

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату