A Biblioteca C GNU/Verificando erros

Origem: Wikilivros, livros abertos por um mundo aberto.

A maior parte das funções de biblioteca retorna um valor para indicar que elas falharam. O valor especial normalmente é -1, um ponteiro nulo, ou uma constante como EOF que é definida para este propósito. Mas este valor de retorno apenas indica que um erro ocorreu. Para descobrir que tipo de erro aconteceu você precisa procurar pelo código de erro armazenada na variável errno. Esta variável é declarada no arquivo de cabeçalho errno.h. De fato, tudo o que esta biblioteca faz é criar esta variável e associá-la com o estado do sistema.

A variável "volatile int errno"[editar | editar código-fonte]

A variável errno contém o número de erro do sistema. Você pode mudar o valor de errno.

Como errno é declarado como volatile, ele pode ser alterado por um sinal controlador. Entretanto, um sinal manipulador escrito corretamente salva e restaura o valor de errno, então você geralmente não precisa se preocupar com esta possibilidade, exceto se estiver escrevendo sinais controladores.

O valor inicial de errno no início de um programa é sempre zero. Muitas funções de biblioteca irão seguramente mudar o valor de errno quando encontrarem certos tipos de erros. Estas condições de errno são listadas em cada função. Como elas não mudam o valor de errno se forem bem-sucedidas e como o valor da variável não será necessariamente zero no início de cada função, você não deve contar com o valor da variável para indicar onde o erro aconteceu. A maneira correta de fazer isso é indicada para cada função. Se a chamada falhar, você pode verificar o valor de errno.

Muitas funções de biblioteca podem alterar o valor de errno como o resultado de chamar outras funções de biblioteca que podem falhar. Você deve assumir que qualquer função da biblioteca pode alterar errno quando a função retorna um erro.

Nota de Portabilidade: O padrão ISO C especifica errno' como um "valor de endereço modificável" ao invés de como uma variável, permitindo que ele seja implementado como uma macro. Por exemplo sua expansão pode envolver uma chamada de função, como _errno(). De fato, é assim que ele é implementado no sistema GNU. A biblioteca GNU, em sistemas não-GNU, fazem o que quer que seja o certo para o sistema.

Existem algumas poucas funções de biblioteca, como sqrt e atan, que retornam um valor perfeitamente legítimo que descreve o erro, além de ajustar o valor de errno. Para estas funções, se você quiser ver quando um erro ocorreu, o método recomendável é ajustar errno para zero antes de chamar a função, e então, verificar o seu valor após a função.

Todos os códigos de erro possuem nomes simbólicos; eles são macros definidas em errno.h. Os seus nomes começam com 'E' e uma letra maiúscula ou dígito; você deve considerar tais nomes como palavras reservadas. Veja A Biblioteca C GNU/Usando a biblioteca.

Os valores do código dos erros assumido por errno são todos inteiros positivos distintos, com uma exceção: EWOULDBLOCK e EAGAIN são a mesma coisa. Como os valores são distintos, você pode usá-los como valores de teste para um comando switch; apenas não use EWOULDBLOCK e EAGAIN ao mesmo tempo. Seu programa não deve assumir nada mais sobre os valores destas constantes simbólicas.

O valor de errno não tem que corresponder necessariamente à qualquer uma destas macros, já que algumas funções da biblioteca podem retornar outros códigos de erro para outras situações particulares. Os únicos valores que são significativos para uma função de biblioteca em particular são aquelas que este livro lista para cada função.

Em sistemas não-GNU, quase qualquer chamada de sistema pode retornar EFAULT se um ponteiro inválido for passado como argumento. Como isto só pode acontecer devido a um bug em seu programa, e como isso não acontece em sistemas GNU, será economizado o espaço não mencionando EFAULT nas descrições de funções individuais.

Em alguns sistemas Unix, muitas chamadas de sistema podem também retornar EFAULT se um ponteiro for passado como um argumento na pilha, e o kernel, por alguma razão obscura falhar em sua tentativa de estender a pilha. Se isso acontecer, você provavelmente deve tentar usar memória alocada dinâmica ou estaticamente ao invés da pilha de memória do sistema.

Exemplos de uso[editar | editar código-fonte]

Testar o valor da variável errno é comum para verificar a existência de erros ao realizar qualquer atividade. A variável também pode ser passada como argumento para uma função que imprime o erro que aconteceu ou impedir que o programa faça algo indesejável logo após o erro. O código abaixo foi retirado do código-fonte do editor de textos EMACS:

if (errno == EMFILE || errno == ENFILE)
		fprintf (stderr, "Error: too many clients.\n");

A macro EMFILE passa a ser o valor de errno sempre que o programa atual abre um número muito grande de arquivos e a ENFILE sempre que já existe um número excessivamente grande de arquivos abertos no sistema inteiro. Perceba que se uma destas coisas ocorrer quando o EMACS abrir um novo arquivo, ele imprimirá na tela a mensagem "Error: too many clients.\n" e não abrirá nenhum arquivo pedido. Essa mensagem só aparece quando o Emacs é usado como servidor. No próximo capítulo, você verá uma lista de todas as macros definidas pela biblioteca errno.h.