forkpty – гнездо

Я пытаюсь разработать простой демон «telnet / server», который должен запускать программу в новом подключении сокета. Эта часть работает нормально.

Но мне нужно связать мой новый процесс с pty, потому что этот процесс имеет некоторые возможности терминала (например, readline).

Код, который я разработал, (где socketfd – новый дескриптор файла сокета для нового входного соединения):

int masterfd, pid; const char *prgName = "..."; char *arguments[10] = ....; if ((pid = forkpty(&masterfd, NULL, NULL, NULL)) < 0) perror("FORK"); else if (pid) return pid; else { close(STDOUT_FILENO); dup2(socketfd, STDOUT_FILENO); close(STDIN_FILENO); dup2(socketfd, STDIN_FILENO); close(STDERR_FILENO); dup2(socketfd, STDERR_FILENO); if (execvp(prgName, arguments) < 0) { perror("execvp"); exit(2); } } 

С этим кодом дескриптор файла stdin / stdout / stderr моего «prgName» связан с сокетом (при просмотре с помощью ls -la / proc / PID / fd), и поэтому возможности терминала этого процесса не работают ,

Тест с подключением через ssh / sshd на удаленном устройстве и выполнение «localy» (под ssh-соединением) prgName, показывают, что stdin / stdout / stderr fd этого процесса «prgName» связаны с pty (и так возможности терминала этого процесса работают нормально).

Что я делаю неправильно? Как связать мой socketfd с pty (созданным forkpty)?

Поблагодарить

Alex

Вы должны написать код для передачи данных из сокета в master pty и наоборот. Обычно это задача родительского процесса. Обратите внимание, что передача данных должна быть двунаправленной. Существует много вариантов: цикл select (), который отслеживает как masterfd, так и socketfd

(точно так же, как подсказка, очень плохой код, а не для производства !!! Отсутствует ошибка и проверка eof !!!)

 for (;;) { FD_ZERO(&set); FD_SET(masterfd,&set); FD_SET(socketfd,&set); select(...,&set,...); if (FD_ISSET(masterfd,&set)) { read(masterfd,&c,1); write(socketfd,&c,1); } if (FD_ISSET(sockerfd,&set)) { read(sochetfd,&c,1); write(masterfd,&c,1); } 

или пару streamов, один для socketfd-> masterfd и один для передач masterfd-> sockefd.

(точно так же, как подсказка, очень плохой код, а не для производства !!!)

 /*thread 1 */ while (read(masterfd,&c,1) > 0) write(socketfd,&c,1); /*thread 2 */ while (read(socketfd,&c,1) > 0) write(masterfdfd,&c,1); 

В любом случае вы должны добавить код в родительской части ветви.

С уважением

— EDIT — Конечно, вы не должны перенаправлять fd 0,1 и 2 на socketfd в дочернем процессе.