Троан Эрик В.
Шрифт:
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);