Чтение онлайн

ЖАНРЫ

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

 21: * дескриптора на ведущую сторону pty.

 22: */

 23: void sigwinch_handler(int signal) {

 24: propagate_sigwinch = 1;

 25: }

 26:

 27:

 28: /* ptytest пытается открыть пару pty с запуском оболочки

 29: * на подчиненной стороне pty.

 30: */

 31: int main(void) {

 32: int master;

 33: int pid;

 34: char * name;

 35: struct pollfd ufds[2];

 36: int i;

 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:

133: /* Этот код взят без изменений из robin.с

134: * Если дочерний процесс завершается, читающая ведущая сторона

Поделиться с друзьями: