Resolução — File Descriptors em C ================================== **Exercício 1** A variável fd representa o *file descriptor* devolvido pela system call open() . É um número inteiro que identifica o ficheiro aberto dentro do processo. Esse valor será usado depois em funções como: * read() * write() * close() -------------------------------------------------- **Exercício 2** Os três *file descriptors* padrão em UNIX/Linux são: * 0 → stdin → entrada (teclado) * 1 → stdout → saída (ecrã) * 2 → stderr → saída de erro Estes descritores já existem quando o programa começa. -------------------------------------------------- **Exercício 3** O valor devolvido por open() deve ser sempre verificado porque pode ocorrer erro ao abrir o ficheiro. Se houver erro, open() devolve: .. code-block:: c -1 Exemplos de erro: * ficheiro não existe * falta de permissões * erro no disco Se não verificarmos, o programa pode falhar. -------------------------------------------------- **Exercício 4** Se esquecermos de usar close(fd) , o sistema operativo mantém recursos ocupados desnecessariamente enquanto o processo estiver a executar. O sistema operativo fecha automaticamente todos os ficheiros abertos quando o processo terminar. Se tivermos demasiados ficheiros abertos desnecessariamente isso pode causar: * desperdício de memória * limite de ficheiros abertos atingido * perda de dados pendentes de escrita Por isso, todo ficheiro aberto deve ser fechado. -------------------------------------------------- **Exercício 5** Resposta correta: .. code-block:: c int fd = open("notas.txt", O_RDONLY); O_RDONLY significa abertura apenas para leitura. -------------------------------------------------- **Exercício 6** Resposta correta: .. code-block:: c close(fd); A função close() fecha o ficheiro e liberta recursos. -------------------------------------------------- **Exercício 7** 1. stdin corresponde ao file descriptor 0 → Verdadeiro 2. stdout corresponde ao file descriptor 2 → Falso 3. stderr corresponde ao file descriptor 2 → Verdadeiro 4. open() devolve um file descriptor → Verdadeiro 5. read() pode funcionar sem file descriptor → Falso -------------------------------------------------- **Exercício 8** Este programa: 1. abre o ficheiro teste.txt apenas para escrita 2. escreve os caracteres ABC no ficheiro A função: .. code-block:: c write(fd, "ABC", 3); escreve 3 bytes no ficheiro. -------------------------------------------------- **Exercício 9** O nome serve para localizar o ficheiro. O file descriptor serve para manipular o ficheiro depois de aberto. * nome do ficheiro → identificação textual do ficheiro, por exemplo dados.txt * file descriptor → número inteiro usado internamente pelo sistema operativo -------------------------------------------------- **Exercício 10**= Porque os valores: * 0 → stdin * 1 → stdout * 2 → stderr já estão reservados pelo sistema. Assim, o primeiro ficheiro aberto normalmente recebe: .. code-block:: c 3 como file descriptor. -------------------------------------------------- **Exercício 11** .. code-block:: c #include #include #include int main() { int fd = open("exemplo.txt", O_RDONLY); if (fd == -1) { printf("Erro ao abrir o ficheiro\n"); return 1; } printf("Ficheiro aberto com sucesso\n"); close(fd); return 0; } Este programa abre o ficheiro, verifica erro e fecha corretamente. -------------------------------------------------- **Exercício Extra — Interpretação** 1. e 2. fd1 e fd2 terão obrigatoriamente o mesmo valor? Não. Porque cada chamada a open() cria uma nova entrada na tabela de ficheiros abertos e recebe um novo file descriptor. Cada ficheiro aberto possui normalmente um descriptor diferente. -------------------------------------------------- 3. Qual será normalmente o valor de fd1 ? .. code-block:: c 3 porque: * 0 → stdin * 1 → stdout * 2 → stderr já estão ocupados.