Por que o / proc / self / fd / 0 não tem um bit gravável na sessão serial antes de um shell ser iniciado?

3

Me deparei com um programa que usa uma versão muito antiga da biblioteca linenoise . Todos write() são feitos para STDIN_FILENO , assim:

write(STDIN_FILENO,prompt,plen)

write falha com -1 e errno definido como EBADF . Eu escrevi um programa C que é iniciado no final de /etc/init.d/rcS , que por sua vez é executado por Busybox init quando o sistema é inicializado antes do sh interativo ser iniciado. O programa C lista o diretório /proc/self/fd , sua saída é:

l-wx------    1 root     root          64 Jan  1 00:00 2 -> /dev/console
l-wx------    1 root     root          64 Jan  1 00:00 1 -> /dev/console
lr-x------    1 root     root          64 Jan  1 00:00 0 -> /dev/console

Como você vê, 0 não tem w bit definido e acho que é por isso que write falha. No entanto, depois que o shell normal sh for iniciado:

lrwx------    1 root     root          64 Jan  1 00:00 2 -> /dev/ttyS0
lrwx------    1 root     root          64 Jan  1 00:00 1 -> /dev/ttyS0
lrwx------    1 root     root          64 Jan  1 00:00 0 -> /dev/ttyS0

Agora 0 tem w definido. Por que isso acontece?

    
por user1042840 09.12.2016 / 12:12

1 resposta

3

Porque você pode ter vários dispositivos de terminal.

Portanto, getty é invocado com ttyS0 especificamente, como um parâmetro. Então, ele usa seu próprio código para inicializar todos os FDs. Isso acontece de forma diferente do código do kernel, que abre /dev/console para init . Pode-se supor que getty abre a tty uma vez com O_RDWR , então dup licena o FD.

Eu posso ver uma razão óbvia para o código deste jeito. agetty também pode ser chamado com - significando stdin. Então, sempre usando dup() é a implementação mais simples.

Não sei por que essa opção foi suportada. Não é necessariamente usado ou suportado em um sistema padrão V inittab . Parece combinar com a abordagem mais antiga usada no BSD , onde init passa pelo terminal dispositivo como um FD aberto em vez de um parâmetro A abordagem mais antiga é para init inicializar todos os FDs (link , note apenas 2 FDs como stderr foi adicionado na próxima versão).

Como a questão foi editada para especificar busybox, e cttyhack foi mencionado, a explicação óbvia no caso de busybox é "mantém o código menor". Este também foi um recurso de condução do código unix histórico.

    
por 09.12.2016 / 12:45