Algo é especial sobre / dev / fd / 3

7

Estou tentando aprender sobre descritores de arquivos. Quando eu digito "ls -l / dev / fd /" recebo

lrwx------ 1 me users 64 May  2 16:02 0 -> /dev/pts/5
l-wx------ 1 me users 64 May  2 16:02 1 -> /home/me/file
lrwx------ 1 me users 64 May  2 16:02 2 -> /dev/pts/5
lr-x------ 1 me users 64 May  2 16:02 3 -> /proc/31518/fd

/ dev / fd / 3 parece estar apontando para o processo atual. No entanto, explicações de descritores de arquivo que eu vi, por exemplo link , não diga que há algo especial em / dev / fd / 3 (e implica que é como qualquer / dev / fd / N para N > 3). O que está acontecendo aqui?

Eu observei isso em arch linux e ubuntu, mas não no servidor solaris em que eu tenho uma conta ssh.

    
por qqw 02.05.2013 / 17:14

3 respostas

10

/dev/fd/3 seems to be pointing to the current process.

Ie., ls propriamente dito (note que o pid não existirá depois). Todos os que pertencem ao processo atual, já que os descritores de arquivos não são globais; não existe apenas um único 0, 1 e 2 para todo o sistema - existe um 0, 1 e 2 separados para cada processo.

Como observa Frederik Dweerdt, /dev/fd é um link simbólico. Se você repetir seu ls de terminais diferentes, você notará links para diferentes ptys. Estes corresponderão à saída do comando tty .

No exemplo ls , eu imagino que o descritor 3 é o que está sendo usado para ler o sistema de arquivos. Alguns comandos C (por exemplo, open() ), que sustentam a geração de descritores de arquivos, garantem o retorno de "o descritor de arquivo não usado numerado mais baixo" (POSIX - note que open level () de baixo nível não faz parte do Standard C). Então eles são reciclados depois de serem fechados (se você abrir e fechar arquivos diferentes repetidamente, você receberá 3 como um fd várias vezes).

Se você quer uma pista sobre como eles vêm a existir, aqui está um trecho de código C usando opendir() , que você provavelmente encontrará na fonte para ls:

// open directory for reading
DIR *dh = opendir(".");
// print the fd of the directory handle to standard out:
printf("fd: %d\n", dirfd(dh));
closedir(dh);  

Executar como está, o fd será 3, já que esse é o descritor não usado mais baixo (0, 1 e 2 já existem).

    
por 02.05.2013 / 17:28
10

/dev/fd/3 não é um descritor padrão (edit: assignment). Ele (editar: ter mais de 0, 1 e 2) é específico para o seu caso ( ls ). Você pode executar o comando ls strace para entender o que acontece:

strace -e trace=openat,readlink ls -l /dev/fd/
openat(AT_FDCWD, "/dev/fd/", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
readlink("/dev/fd/0", "/dev/pts/0", 65) = 10
readlink("/dev/fd/1", "/dev/pts/0", 65) = 10
readlink("/dev/fd/2", "/dev/pts/0", 65) = 10
readlink("/dev/fd/3", "/proc/28401/fd", 65) = 14

ls é para exibir o conteúdo de /dev/fd , que é o mesmo que /proc/self/fd . ls tem que abrir o diretório para ler suas entradas. /dev/fd/3 é apenas o descritor de arquivo para este diretório.

Outros programas não têm /dev/fd/3 :

start cmd:> sleep 100 &
[1] 28414

ec:0   17:28:10  hl@inno:~/.wine/drive_c
start cmd:> ls -l /proc/28414/fd
insgesamt 0
crw------- 1 hl tty 136, 0 18. Apr 01:18 0
crw------- 1 hl tty 136, 0 18. Apr 01:18 1
crw------- 1 hl tty 136, 0 18. Apr 01:18 2
    
por 02.05.2013 / 17:29
4

No Archlinux, /dev/fd é um link simbólico para /proc/self/fd . O que você está vendo é o diretório fd do seu comando ls . E esse comando de fato abriu o diretório como descritor de arquivo 3.

EDIT: BTW, uma boa maneira de entender o que está acontecendo é usar strace . Você verá o processo abrindo os descritores de arquivos.

    
por 02.05.2013 / 17:21