Array
(
)

errno

Brunomk8
   - 01 abr 2008

Porque que o seguinte código retorna este erro: Segmentation fault (core dumped)

#Código


#include <stdio.h>
include <stdlib.h>
include <unistd.h>
include <string.h>
include <errno.h>

const char *descricao[] = {"Operação não permitida", "Arquivo ou diretório inexistente"};

const char *abrir_arquivo(char *arquivo)
{
FILE *fp;
if ((fp = fopen(arquivo, "r")) == NULL)
return descricao[errno];
}

int main (void)
{
printf("¬s\n", abrir_arquivo("asdasdasd"));
return 1;
}



Massuda
   - 01 abr 2008

Provavelmente o valor de errno está fora da faixa 0-1, que é a faixa implícita para o array ´descricao´.


Brunomk8
   - 01 abr 2008

E como que eu faço pra verificar este range?

Na verdade eu preciso mesmo é traduzir as mensagens de erro padrão do FreeBSD (errno.h).


Massuda
   - 01 abr 2008

No mínimo, você precisa definir um array com tantas strings quanto o maior valor possível de errno. Por exemplo, no errno.h do BC 5.5 o menor valor é 0 e o maior é 49; logo, o array nesse caso precisaria ter 50 strings, de 0 a 49.


Brunomk8
   - 01 abr 2008

Eu fiz assim, mas não funcionou:

#Código

#include <stdio.h>
include <stdlib.h>
include <unistd.h>
include <string.h>
include <errno.h>

const char *descricao[] = { "Operação não permitida",
"Arquivo ou diretório inexistente",
"Processo inexistente",
"Chamada de sistema interrompida",
"Erro de Entrada/Saída",
"Dispositivo não configurado",
"Lista de argumentos muito longa",
"Formato Exec errado",
"Descritor de arquivo ruim",
"Sem processo filho",
"Evitado congelamento de recusos",
"Memória não pode ser alocada",
"Permissão negada",
"Endereço ruim",
"Dispositivo de bloqueio requerido",
"Dispositivo ocupado",
"Arquivo existe",
"Ligação inválida",
"Operação não suportada pelo dispositivo",
"Não é um diretório",
"É um diretório",
"Argumento inválido",
"Muitos arquivos abertos no sistema",
"Muitos arquivos abertos",
"ioctl inapropriado para o dispositivo",
"Arquivo de texto ocupado",
"Arquivo muito grande",
"Não há espaço livre no dispositivo",
"Procura ilegal",
"Sistema de arquivos somente leitura",
"Muitas ligações",
"Pipe quebrado",
"Argumento numérico fora do domínio",
"Resultado muito grande",
"Recurso temporariamente indisponível",
"Operação em progresso",
"Operação já se encontra em progresso",
"Operação de Socket em non-socket",
"Endereço de destino requerido",
"Mensagem muito longa",
"Tipo de protocolo errado para o socket",
"Protocolo indisponível",
"Protocolo não suportado",
"Tipo de socket não suportado",
"Operação não suportada",
"Família de protocolos não suportada",
"Família de endereços não suportada pela família de protocolos",
"Endereço já se encontra em uso",
"Não é possível atribuir o endereço solicitado",
"Rede desconectada",
"Rede inacessível / inalcançavel",
"A conexão de rede foi perdida ao resetar",
"Programa causou o cancelamento da conexão",
"Conexão resetada por outro ponto",
"Sem espaço disponível no buffer",
"Socket já está conectado",
"Socket não está conectado",
"Não é possível enviar após encerramento do socket",
"Too many references: can´t splice",
"Operação expirou",
"Conexão recusada",
"Demasiados níveis de links simbólicos",
"Nome do arquivo muito longo",
"Host desligado",
"Sem rota para o Host",
"Diretório não vazio",
"Muitos processos",
"Muitos usuários",
"Quota de disco excedida",
"Engano na manipulação de arquivo NFS",
"Demasiados níveis de remoto no path",
"Estrutura RPC ruim",
"Versão RPC errada",
"RPC prog. sem proveito",
"Versão do programa errrada",
"Procedimento ruim para o programa",
"Sem locks disponíveis",
"Função não implementada",
"Tipo ou formato de arquivo inapropriado",
"Erro de autenticação",
"Precisa-se de autenticador",
"Identificador removido",
"Sem mensagem para o tipo desejado",
"Valor muito grande para ser guardado no tipo de dados",
"Operação cancelada",
"Seqüência de bytes ilegal",
"Atributo não encontrado",
"Erro de programação",
"Mensagem ruim",
"Multihop esperado",
"Ligação foi cortada",
"Erro de protocolo",
"Deve ser igual ou maior que errno",
};

const char *abrir_arquivo(char *arquivo)
{
FILE *fp;
if ((fp = fopen(arquivo, "r")) == NULL)
return descricao[errno];
}

int main (void)
{
printf("¬s\n", abrir_arquivo("asdasdasd"));
return 1;
}


O mesmo erro aparece. Mas o engraçado é que assim funciona:

#Código

char *erro(int erro)
{

switch(erro)
{
case 1:
return "Operação não permitida";
break;
case 2:
return "Arquivo ou diretório inexistente";
break;
}

}

const char *abrir_arquivo(char *arquivo)
{
FILE *fp;
if ((fp = fopen(arquivo, "r")) == NULL)
return erro(errno);
else
return "Ok";
}

int main (void)
{
printf("¬s\n", abrir_arquivo("asdasdasd"));
return 1;
}


Mas pq do segundo jeito funciona e do primeiro jeito não?


Massuda
   - 02 abr 2008

Não sei como é o seu errno.h, mas o que tenho do compilador BC 5.5 indica que o menor valor de errno é zero e que os valores não são consecutivos.

Seu código indica que o seu errno tem menor valor igual a um; como todo array em C/C++ começa em zero, seu array está errado pois a mensagem descricao[0] devia ser ´´, já que, pelo código que você postou, descricao[1] deveria ser ´Operação não permitida´.

As strings em descricao[] devem estar no mesmo indice do errno correspondente, não apenas na mesma ordem (que parece ser o que você fez). Por exemplo, se não existe errno == 12, então descricao[12] dever ser ´´.


Brunomk8
   - 02 abr 2008

Claro cara... vc está coberto de razão. Eu percebi isto hj demanhã e vim aqui no fórum responder... heheheh

Realmente, o índice estava fora da faixa, portanto uma exceção era gerada.

O código certo e funcional ficou assim:


#Código


const char *descricao[] = {"", "Operação não permitida", "Arquivo ou diretório inexistente"};

const char *abrir_arquivo(char *arquivo)
{
FILE *fp;
int *a;

if ((fp = fopen(arquivo, "r")) == NULL)
{
if ((errno >= 0) && (errno <= 2))
return descricao[errno];
else
return "Erro desconhecido";
}
else
return "Aberto";
}

int main (void)
{
printf("¬s\n", abrir_arquivo("asdasdasd"));
return 1;
}


Muito obrigado pela ajuda!

:D


Brunomk8
   - 03 abr 2008

Agora eu estou tendo o mesmo erro quando tentei concatenar strings:
Segmentation fault (core dumped)

Abaixo, segue o código


#Código


#include <stdio.h>
include <stdlib.h>
include <unistd.h>
include <string.h>
include <errno.h>

define INTSIZE 2

char *itoa(int value)
{
int count, i, sign;
char *ptr, *string, *temp;

count = 0;
if ((sign = value) < 0)
{
value = -value;
count++;
}


temp = (char *) malloc(INTSIZE + 2);
if (temp == NULL)
{
return(NULL);
}
memset(temp,´\0´, INTSIZE + 2);

string = (char *) malloc(INTSIZE + 2);
if (string == NULL)
{
return(NULL);
}
memset(string,´\0´, INTSIZE + 2);
ptr = string;


do
{
*temp++ = value ¬ 10 + ´0´;
count++;
} while (( value /= 10) >0);

if (sign < 0)
*temp++ = ´-´;

*temp-- = ´\0´;

for (i = 0; i < count; i++, temp--, ptr++)
{
memcpy(ptr,temp,sizeof(char));
}

return(string);
}

char *descricao[] = {"", "Operação não permitida", "Arquivo ou diretório inexistente"};

char *abrir_arquivo(char *arquivo)
{
FILE *fp;
char *erro;


if ((fp = fopen(arquivo, "r")) == NULL)
{
if ((errno >= 0) && (errno <= 2))
{
strcat(descricao[errno]," - Cód.: ");
strcat(descricao[errno],itoa(errno));
return descricao[errno];
}
else
return "Erro desconhecido";
}
else
return "Aberto";
}

int main (void)
{
printf("¬s\n", abrir_arquivo("asdasdasd"));
return 1;
}


Alguém sabe o que pode estar acontecendo?


Brunomk8
   - 03 abr 2008

hhmmm já sei pq:

Acho q não posso fazer isso:

#Código

strcat(descricao[errno]," - Cód.: ");
strcat(descricao[errno],itoa(errno));
return descricao[errno];


Mas tentei fazer isto e tb não funcionou:

#Código
char *erro;
erro = descricao[errno];
strcat(erro," - Cód.: ");
strcat(erro,itoa(errno));
return erro;



Porque?