30: * но теоретически менее переносимо, следующему:
31: * master = posix_openpt(O_RDWR);
32: */
33:
34: if (master >= 0 && grantpt(master) >= 0 &&
3
5: unlockpt(master) >= 0) {
36: slavename = ptsname(master);
37: if (!slavename) {
38: close(master);
39: master = -1;
40: /* сквозной проход для нейтрализации ошибки */
41: } else {
42: *name = strdup(slavename);
43: return master;
44: }
45: }
46:
47: /* Остаток этой функции — нейтрализация ошибки для старых систем */
48:
49: /* создать фиктивное имя для заполнения */
50: *name = strdup("/dev/ptyXX");
51:
52: /* искать неиспользуемый pty */
53: for (i=0; i<16 && master <= 0; i++) {
54: for (j = 0; j<16 && master <= 0; j++) {
55: (*name)[8] = "pqrstuvwxyzPQRST"[i];
56: (*name)[9] = "0123456789abcdef"[j];
57: /* открыть ведущее устройство pty */
58: if ((master = open(*name, O_RDWR)) < 0) {
59: if (errno == ENOENT) {
60: /* устройства pty исчерпаны */
61: free(*name);
62: return(master);
63: }
64: }
65: }
66: }
67:
68: if ((master < 0) && (i == 16) && (j == 16)) {
69: /* необходимо для каждого неудачного pty */
70: free(*name);
71: return(master);
72: }
73:
74: /* Подставляя букву, изменить имя ведущего устройства pty
75: * в имени подчиненного компонента pty.
76: */
77: (*name)[5] = 't';
78:
79: return(master);
80: }
81:
82: /* get_slave_pty() возвращает целочисленный файловый дескриптор.
83: * Если возвращается значение < 0, значит, возникла ошибка.
84: * В противном случае возвращается файловый дескриптор подчиненного
85: * компонента. */
86:
87: int get_slave_pty(char * name) {
88: struct group *gptr;
89: gid_t gid;
90: int slave = -1;
91:
92: if (strcmp(name, "/dev/pts/")) {
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: