Então, como @muru aponta nos comentários, não parece haver uma maneira simples de fazer interface com o arquivo criado para você apenas com o shell. Eu gerenciei tudo, mas a parte unlockpt()
. De acordo com algo que eu li aqui pode ser que existam algumas opções de tempo de compilação no kernel para desabilitando o bloqueio de pty recém-criado, mas eu não queria fazer isso. Então eu fiz outra coisa.
Eu não precisei de grantpt()
na verdade. De acordo com a descrição encontrada aqui tudo o que isso faz é alterar o UID / GID para /dev/pts/[num]
arquivo do dispositivo. Mas, de acordo com man mount
, há maneiras mais fáceis de lidar com isso. Aqui estão algumas opções de devpts
mount:
-
uid=value
egid=value
- Isso define o proprietário ou o grupo de PTYs recém-criados para os valores especificados. Quando nada é especificado, eles serão definidos para o UID e GID do processo de criação. Por exemplo, se houver um grupo tty com GID 5, então
gid=5
fará com que os PTYs recém-criados pertençam ao grupo tty .
- Isso define o proprietário ou o grupo de PTYs recém-criados para os valores especificados. Quando nada é especificado, eles serão definidos para o UID e GID do processo de criação. Por exemplo, se houver um grupo tty com GID 5, então
Esse já era o caso no meu sistema por padrão. Mas depois de ler isso, percebi que poderia querer fazer uma mudança, afinal. A próxima seção diz:
-
%código%
- Defina o modo para o novo nó do dispositivo ptmx no sistema de arquivos
ptmxmode=value
. - Com o suporte para várias instâncias de
devpts
(consulte a opçãodevpts
acima), cada instância tem um nó ptmx particular na raiz do sistema de arquivosnewinstance
(geralmentedevpts
) - Para compatibilidade com versões mais antigas do kernel, o modo padrão do novo nó ptmx é
/dev/pts/ptmx
.0000
especifica um modo mais útil para o nó ptmx e é altamente recomendado quando a opçãoptmxmode=value
é especificada.
- Defina o modo para o novo nó do dispositivo ptmx no sistema de arquivos
Apesar de ter funcionado sem fazê-lo, gostei da ideia e defini-a como newinstance
conforme recomendado no documentação do kernel . O link doc do kernel, a propósito, elabora sobre a opção 0640
mount - que é bem legal e basicamente permite que você obtenha um grupo separado de espas por nome por newinstance
mount.
De qualquer forma, o algo mais foi principalmente para:
mount -o remount,newinstance,gid=5,ptmxmode=0640 /dev/pts
mount --bind /dev/pts/ptmx /dev/ptmx
... como os documentos do kernel recomendam - veja o link sobre o porquê. Também tornei permanente o efeito dos comandos acima, adicionando algumas linhas ao meu /dev/ptmx
.
E ...
<<\C cc -xc - -o pts
#include <stdio.h>
int main(int argc, char *argv[]) {
if(unlockpt(0)) return 2;
char *ptsname(int fd);
printf("%s\n",ptsname(0));
return argc - 1;
}
C
Que apenas compila um pequeno programa em C que tenta chamar /etc/fstab
em seu arquivo stdin e, se for bem sucedido, imprime o nome do recém-criado e desbloqueado pty em unlockpt()
ou então silenciosamente retorna 2.
Uma vez que isso foi feito, eu poderia criar meus próprios processos selecionados como:
exec 3<>/dev/ptmx
... para obter o fd master-side no shell atual ...
(setsid -c "$0" -i 2>&1|tee log) <>"$(./pts <&3)" 3>&- >&0 &
Isso obtém um shell interativo em execução na outra extremidade do pseudo-terminal em segundo plano. Ele irá interpretar qualquer coisa impressa em stdout
como entrada do usuário.
mikeserv@localhost$ echo echo hey >&3
mikeserv@localhost$ cat log
$ hey
$
mikeserv@localhost$ echo echo hey >&3
mikeserv@localhost$ cat log
$ hey
$ hey
$
Que basicamente me faz um intérprete interativa, com registro em log (ou qualquer outra coisa que eu possa me preocupar em executar nelas) ala >&3
sem muita sobrecarga e em qualquer descritor de arquivo que eu escolher.
O fd do lado mestre de propriedade do meu shell atual é o único meio de servir a entrada do lado do escravo e é apenas gravável pelo meu processo de shell atual (e seus filhos) . Eu posso me comunicar com o outro lado escrevendo para screen
e eu posso ler do mesmo ou de um arquivo de log como eu desejo.
E >&3
funciona no terminal depois de tudo:
mikeserv@localhost$ echo stty -a ">$(tty)" >&3
speed 38400 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>;
swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc
-ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl
echoke