====== Sistema de arquivos ======
Os sistemas de arquivos do UNIX possuem as seguintes características fundamentais:
* Estruturados na forma de uma árvore única, iniciando pelo diretório "/", que é chamado de "raiz".
* Há suporte para arquivos, diretórios e links (atalhos).
* Os arquivos podem ter qualquer nome, usando quaisquer caracteres, com distinção entre maiúsculas e minúsculas. Os nomes são normalmente limitados a 255 caracteres.
* O caractere separador de diretórios é o "/" (barra).
* Arquivos e diretórios cujos nomes começam com "." (ponto) são considerados "ocultos" e normalmente não aparecem nas listagens de diretórios.
* As extensões são normalmente usadas apenas para facilitar a vida do usuário, mas não são importantes para o sistema operacional, que não depende delas para identificar o conteúdo de um arquivo.
* Os arquivos e diretórios possuem permissões de acesso controláveis por seus proprietários.
Os principais sistemas de arquivos usados para a formatação de discos locais em Linux são o ext2, ext3, reiser, xfs e jfs, entre outros. Os sistemas mais recentes implementam o conceito de //journaling//. Os links a seguir fornecem mais detalhes sobre esse conceito e os sistemas de arquivos mais usados:
* [[http://e2fsprogs.sourceforge.net/ext2.html|SourceForge - Ext2/Ext3]]
* [[http://oss.sgi.com/projects/xfs/SiG - XFS on Linux]]
* [[http://www.xenotime.net/linux/linux-fs.html|Informações sobre outros filesystems]]
====== Hierarquia de diretórios ======
Os diretórios de um sistema de arquivos no UNIX têm uma estrutura pré-definida, com poucas variações. Essa estrutura normalmente segue a padronização sugerida pelo documento [[http://www.pathname.com/fhs/|Filesystem Hierarchy Standard]] ([[http://www.redhat.com/docs/manuals/linux/RHL-9-Manual/ref-guide/s1-filesystem-fhs.html|resumo do RedHat 9]]).
A seguir ilustramos os principais diretórios de um sistem Linux típico:
* ''/home'' : raiz dos diretórios home dos usuários.
* ''/boot'' : arquivos de boot (núcleo do sistema, etc)
* ''/var'' : arquivos variáveis, áreas de spool (impressão, e-mail, news), arquivos de log
* ''/etc'' : arquivos de configuração dos serviços
* ''/usr'' : aplicações voltadas aos usuários
* ''/tmp'' : arquivos temporários
* ''/mnt'' : montagem de diretórios compartilhados temporários
* ''/bin'' : aplicações de base para o sistema
* ''/dev'' : arquivos de acesso aos dispositivos físicos e conexões de rede
* ''/lib'' : bibliotecas básicas do sistema
* ''/proc'' : não é um diretório real em disco, mas a porta de acesso para estruturas do núcleo
====== Descritores e Streams ======
Quando um processo abre um arquivo, o núcleo do sistema operacional precisa criar várias estruturas de dados para gerenciar seu uso. Duas estruturas de dados são importantes nesse contexto: a tabela de descritores de arquivos (//file descriptor table//) e a tabela de arquivos do sistema (//system file table//).
* Cada processo possui sua própria **tabela de descritores de arquivos**. Os descritores de arquivos usados pelo processo nas operações sobre os arquivos são índices ou ponteiros para entradas nessa tabela local.
* O sistema operacional possui uma **tabela de arquivos do sistema**, que possui uma entrada para cada open ativo. Essa tabela possui várias entradas, sendo uma dela um apontador (ou índice) para a tabela de //i-nodes// (ou //v-nodes//), que possui uma entrada para cada arquivo aberto no sistema.
{{ filetables.png |Tabelas no sistema de arquivos}}
Um descritor de arquivo constitui uma interface de baixo nível para o acesso ao mesmo. Por ser simplesmente um índice em uma tabela local, geralmente é representado por uma variável do tipo ''int''.
O mecanismo de //streams// provê uma interface mais abstrata para acesso aos arquivos, construída a partir dos descritores. Essa abstração provê uma maior homogeneidade no acesso aos diversos tipos de arquivos e travamento (//locking//) automático, além de um controle mais fino sobre os mecanismos de buferização do arquivo em memória. Streams são definidos por variáveis do tipo ''FILE *''.
Deve-se observar que, enquanto descritores de arquivos são herdados por processos filhos, //streams// não o são.
====== Arquivos padrão ======
Cada processo sempre possui três descritores de arquivos pré-definidos, os chamados //arquivos padrão//, geralmente definidos no arquivo ''unistd.h'':
* ''STDIN_FILENO'' (//stream// ''stdin'', entrada 0) : entrada padrão (default: teclado). Usado por todas as funções de entrada de dados que não especificarem um descritor de arquivo.
* ''STDOUT_FILENO'' (//stream// ''stdout'', entrada 1) : saída padrão (default: terminal). Usado por todas as funções de saída de dados que não especificarem um descritor de arquivo.
* ''STDERR_FILENO'' (//stream// ''stderr'', entrada 2) : saída de erro (default: terminal). Usado pelas funções que produzem mensagens de erro.
Os arquivos padrão são geralmente associados ao terminal onde o processo foi lançado, mas podem ser redirecionados para outros arquivos através do shell (operadores >, <, >>, |, etc) ou dentro do próprio processo, através das funções de abertura de streams (''fopen'', ''freopen'').
====== Operações básicas em arquivos ======
O núcleo do sistema operacional UNIX disponibiliza as seguintes chamadas de sistema (//syscalls//) para as operações básicas de entrada/saída em arquivos, que operam sobre descritores: ''open'', ''close'', ''read'', ''write'' e ''fcntl''. As demais operações são normalmente implementadas como funções de biblioteca que fazem uso dessas chamadas.
* [[Operações usando descritores]]
* [[Operações usando streams]]
* [[Operações em meta-dados]]
* [[Operações em diretórios]]
====== Atividades ======
Execute o programa a seguir e explique o que ocorre com sua saída:
#include
main ()
{
fprintf (stdout, "a ") ;
fprintf (stderr, "imprimi a ") ;
fprintf (stdout, "b ") ;
fprintf (stderr, "imprimi b ") ;
fprintf (stdout, "\n") ;
return 0 ;
}
Escreva um programa ''mycp'' que efetua a cópia de um arquivo em outro:
mycp arq1 arq2
Antes da cópia, ''arq1'' deve existir e ''arq2'' não deve existir. Mensagens de erro devem ser geradas caso essas condições não sejam atendidas ou o nome dado a ''arq2'' seja inválido.
Escreva um programa em C que gere uma listagem do diretório corrente no seguinte formato:
tamanho nome e tipo
115234 arquivo
4096 diretorio/
21 link->
1024 socket@
1024 pipe=
Modifique o programa anterior para incluir na listagem as permissões das entradas do diretório:
perms tamanho nome e tipo
rw-r--r-- 115234 arquivo
rwx------ 4096 diretorio/
rwxrwxrwx 21 link->
rw-rw-rw- 1024 socket@
rw-rw---- 1024 pipe=
Idem, para a data de última modificação de cada entrada.