В строке 105 после завершения poll()
мы проверяем, является ли причиной завершения poll()
сигнал SIGWINCH
, доставляемый функции sigwinch_handler
в строке 20. Если это так, необходимо получить новый размер текущего окна из стандартного ввода и распространить его в pty подчиненного компонента. Установкой размера окна SIGWINCH
передается SIGWINCH
этому процессу.
Теперь для сравнения посмотрите, насколько усложняется этот код в случае использования функций, определенных в ptypair.с
.
1: /* ptytest.с */
2:
3: #include
4: #include
5: #include
6: #include
7: #include
8: #include
9: #include
10: #include
11: #include
12: #include
13: #include
14: #include "ptypair.h"
15:
16:
17: volatile int propagate_sigwinch = 0;
18:
19: /* sigwinch_handler
20: * распространяет изменения размеров окна из входного файлового
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: