113: /* Обратите внимание, что здесь не осуществляется проверка на ошибки.
114: * Однако если выполняемые действия являются критически важными,
115: * проверка ошибок должна быть. */
116: chown(name, getuid(), gid);
117:
118: /* Этот код делает подчиненный компонент доступным для чтения/записи
119: * только конкретному пользователю. Если код предназначен для
120: * интерактивной оболочки, которая должна получать сообщения
121: * "write" и "wall", добавьте ниже "ИЛИ" с S_IWGRP во второй аргумент.
122: * В таком случае потребуется перенести эту строку за пределы
123: * оператора if(), чтобы код мог выполняться для интерфейсов как
124: * BSD-стиля, так и Unix98-стиля.
125: */
126: chmod(name, S_IRUSR|S_IWUSR);
127: }
128:
129: /* открыть соответствующий подчиненный компонент pty */
130: slave = open(name, O_RDWR);
131:
132: return(slave);
133: }
Функция get_slave_pty()
не делает ничего нового. Все функции описываются в других местах этой книги, поэтому здесь они не объясняются.
16.6.4. Примеры псевдотерминалов
Возможно, одной из самых простых программ, которая может быть написана для использования pty, является программа, открывающая пару pty и запускающая оболочку на подчиненном компоненте pty, соединяя его с управляющим устройством pty. Написав эту программу, вы можете расширять ее любым подходящим способом, forkptytest.с
является примером использования функции forkpty()
, a ptytest.с
— это пример, который использует функции, определенные в ptypair.с
, и является несколько более сложным.
1: /* forkptytest.с */
2:
3: #include
4: #include
5: #include
6: #include
7: #include
8: #include
9: #include
10: #include
11: #include
12:
13:
14: volatile int propagate_sigwinch = 0;
15:
16: /* sigwinch_handler
17: * распространяет изменения размеров окна из входного файлового
18: * дескриптора на ведущую сторону pty.
19: */
20: void sigwinch_handler(int signal) {
21: propagate_sigwinch = 1;
22: }
23:
24:
25: /* forkptytest пытается открыть пару pty с запуском оболочки
26: * на подчиненной стороне pty.
27: */
28: int main(void) {
29: int master;
30: int pid;
31: struct pollfd ufds[2];
32: int i;
33: #define BUFSIZE 1024
34: char buf[1024];
35: struct termios ot, t;
36: struct winsize ws;
37: int done = 0;
38: struct sigaction act;
39:
40: if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0) {
41: perror("ptypair: не удается получить размеры окна");
42: exit(1);
43: }
44:
45: if ((pid = forkpty(&master, NULL, NULL, &ws)) < 0) {
46: perror("ptypair");
47: exit(1);
48: }
49:
50: if (pid == 0) {
51: /* запустить оболочку */
52: execl("/bin/sh", "/bin/sh", 0);
53:
54: /* сюда управление никогда не попадет */
55: exit(1);
56: }
57:
58: /* родительский процесс */
59: /* установить обработчик SIGWINCH */
60: act.sa_handler = sigwinch_handler;