errno

01/04/2008

1

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

#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;
}



Responder

Posts

01/04/2008

Massuda

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


Responder

01/04/2008

Brunomk8

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).


Responder

01/04/2008

Massuda

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.


Responder

01/04/2008

Brunomk8

Eu fiz assim, mas não funcionou:

#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:

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?


Responder

02/04/2008

Massuda

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 ´´.


Responder

02/04/2008

Brunomk8

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:


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


Responder

03/04/2008

Brunomk8

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

Abaixo, segue o 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?


Responder

03/04/2008

Brunomk8

hhmmm já sei pq:

Acho q não posso fazer isso:

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


Mas tentei fazer isto e tb não funcionou:

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



Porque?


Responder
×
+1 DevUP
Acesso diário, +1 DevUP
Parabéns, você está investindo na sua carreira