Inverti as declarações em if/else
, corrigidas agora.
Estou lendo um trecho de código de Programação Avançada no Ambiente UNIX® :
O programa testa sua entrada padrão para ver se é capaz de buscar.
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void){
if(lseek(STDIN_FILENO,0, SEEK_CUR) == -1)
printf("cannot seek\n");
else{
printf("seek ok\n");
}
}
Eu compilo e executo (em Ubuntu 18.04.2 LTS
), mas não entendo os seguintes comportamentos.
//1
$ ./a.out
cannot seek
//2
$ ./a.out < /etc/passwd
seek OK
//3
$ cat < /etc/passwd | ./a.out
cannot seek
//4
$ ./a.out < /var/spool/cron/FIFO
cannot seek
Por que //1
é cannot seek
? Vazio stdin
deve ser capaz de procurar eu acho. É porque stdin
ainda não foi aberto? Porque eu ouvi isso normalmente stdin
, stdout
e stderr
são abertos quando um programa começa a rodar.
Por que //2
está bem e //3
não está? Acho que são iguais.
//1 ./a.out
:Se você não fizer o redirecionamento de stdin (sem pipe e sem
<
), stdin será herdado do processo pai. À medida que você executaa.out
interativamente em um shell, ele herda o dispositivo terminal que recebe a entrada do teclado como stdin.Os dispositivos de terminal geralmente não são pesquisáveis porque representam a interação do usuário, mas de acordo com o padrão POSIX
lseek
podem retornar sucesso e simplesmente não fazer nada. No Linuxlseek
falha com um arquivoESPIPE
.//2 ./a.out < /etc/passwd
:Aqui stdin é redirecionado para um arquivo aberto. Como
/etc/passwd
deve ser um arquivo regular, é pesquisável.//3 cat < /etc/passwd | ./a.out
:Aqui você inicia dois processos (
cat
e./a.out
) e os conecta com um pipe.cat
(sem outros argumentos) lê-o stdin (/etc/passwd
) e copia-o para seu stdout (o pipe conectando a./a.out
). Este não é o mesmo caso que//2
. Do ponto de vista do./a.out
stdin não pode buscar pois é apenas um pipe conectando a outro processo.//4 ./a.out < /var/spool/cron/FIFO
:Aqui você tem um pipe nomeado ou arquivo especial similar. Este caso é semelhante ao
//3
. Você tem uma conexão unidirecional com outro processo. E estes não são pesquisáveis.