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

ЖАНРЫ

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

Троан Эрик В.

Шрифт:

 93: /* Интерфейс Unix98 не использовался, необходима

 94: * специальная обработка полномочий или прав владения.

 95: *

 96: * Выполнить chown/chmod для соответствующего pty, если возможно.

 97: * Это будет работать, только если имеет полномочия root.

 98: * В качестве альтернативы можно написать и запустить небольшую

 99: * setuid-программу, которая сделает все это.

100: *

101: *
В противном случае все проигнорировать и пользоваться

102: * только интерфейсом Unix98.

103: */

104: if ((gptr = getgrnam("tty")) != 0) {

105: gid = gptr->gr_gid;

106: } else {

107: /* если группа tty не существует, не изменять группу

108: * на подчиненном компоненте pty, а только владельца

109: */

110: gid = -1;

111: }

112:

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 <errno.h>

4: #include <signal.h>

5: #include <stdio.h>

6: #include <stdlib.h>

7: #include <sys/ioctl.h>

8: #include <sys/poll.h>

9: #include <termios.h>

 10: #include <unistd.h>

 11: #include <pty.h>

 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: /* родительский процесс */

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