Determinando se um objeto do sistema de arquivos é um procfs / sysfs / etc. “Arquivo virtual” que não informa seu tamanho corretamente

4

Alguns tipos de pseudo-arquivos, como muitos nos sistemas de arquivos virtuais procfs e sysfs, não têm tamanho de arquivo ( stat retorna st_size == 0) e não suportam SEEK_END em fseek . Esses objetos do sistema de arquivos, como /proc/cpuinfo , se comportam mais como FIFOs do que arquivos regulares de acesso aleatório. Infelizmente, eles também mentem sobre o tipo de arquivo: o campo st_mode inclui o S_IFREG bit, o que implica um arquivo regular, não o S_IFIFO bit.

Isso causa problemas com o código de entrada que tenta ser "mais inteligente" sobre o gerenciamento de dados e há muitos relatórios de ferramentas que são interrompidas quando olham para /proc/* arquivos.

Estou trabalhando em uma dessas ferramentas, que possui um sistema de entrada de fluxo de propósito geral que pode obter um fluxo de várias fontes, indicado pelo usuário. Também posso manipular fluxos de acesso não aleatório como pipes e soquetes que são puramente "sequenciais", e as mesmas técnicas usadas para eles funcionariam em procfs / sysfs / outros objetos do sistema de arquivos virtuais - mas devo ser capaz de dizer sem ambiguidade quando estou olhando para um.

Dado um ponteiro FILE, descritor de arquivo ou nome de caminho de arquivo, como posso determinar em C se estou olhando para um desses objetos de pseudo-arquivo problemáticos? (Nota: apenas a verificação de um caminho que começa com / proc não é suficiente, pois um sistema de arquivos pode ser montado arbitrariamente. Preciso do sistema operacional para saber se posso confiar nos arquivos st_size e SEEK_END .) solução razoavelmente portátil para os modernos * nixes?

(Esta é uma questão de programação; sinta-se à vontade para migrá-lo para o SO, se necessário.)

    
por librik 22.06.2013 / 00:56

2 respostas

3

Se você stat um descritor de arquivo e o tamanho for reportado como 0, o arquivo estará vazio ou o tamanho será desconhecido. Se o arquivo estiver vazio, não há muito sentido em jogar para lê-lo com mais eficiência.

Assim, se o tamanho for desconhecido, você terá que usar seu caminho de código alternativo e, se o arquivo estiver vazio, não será um problema usar o caminho de código alternativo.

Eu alertaria contra a tentativa de diagnosticar o tipo de arquivo apenas com base no nome do arquivo, já que isso o abrirá a um ataque (ou bug) de isca e comutador. Você não deve tentar descobrir nada até abrir o arquivo com êxito e, em seguida, certifique-se de usar o descritor de arquivo, direta ou indiretamente, em vez do nome, porque o nome pode não estar mais associado ao arquivo. mesmo arquivo.

Espero que ajude.

    
por 22.06.2013 / 05:54
3

Verificar o caminho é apenas a segunda melhor ideia. Você pode verificar o sistema de arquivos (dispositivo): st_dev=makedev(0, 14) . Se o número principal for 0, então será proc , sys ou algo parecido.

Mesmo o kernel não pode ter certeza sobre a natureza de um arquivo. Imagine uma montagem FUSE que contenha partes de /proc . O kernel assumiria um sistema de arquivos normal, ao passo que é um pseudo sistema de arquivos com os problemas que você deseja evitar.

Mas se você sabe que SEEK_END não funciona, por que você não usa isso para o teste?

    
por 22.06.2013 / 01:35