Pagina 1 di 2

Segmentation Fault su fclose()

Inviato: lun 22 ott 2007, 13:04
da Blizzard
Ciao ragà vi posto l'ultima funzione della shell ovvero quella che si occupa di verificare in base ad un file se esiste un programma associato nel file di configurazione

Codice: Seleziona tutto

//This function take the filename as parameter
//get his extension and find in the config file 
//the relative program (if exist).
//This function returns the string of the program if exists
//otherwise returns NULL
char* FindFileAssociation(char *line)
{
	FILE *stream=NULL;
	char conffile[2048];
	char ext[2048];
	char *home=NULL;
	char *result=NULL;
	char *p=NULL;
	char *l=NULL,*j=NULL, *k=NULL;;
	char *temp=NULL;
	int n=2047;
	int i=0;
	
	if(!line)
	{
		fprintf(stderr,"ERROR!!! line parameter is NULL\n");
		fprintf(stderr,"This error could not happen!!! what's wrong!!! HEEEEEEELP!!!\n");
		fprintf(stderr,"Error in FindFileAssociation in [association.c]\n");
		return NULL;
	}
	
	//allocating the string that contains the result
	result=malloc(2048);
	if(!result)
	{
		fprintf(stderr,"Could not allocate the memory for the result string\n");
		fprintf(stderr,"Error in FindFileAssociation in [association.c]\n");
		return NULL;
	}
	//Zeroing out the structure
	memset(result,0,2048);
	
	//searching the extension .something
	//we simply search the first dot in the string line
	p=line;
	while(*p!='.')
	{
		if(p=='\0')
		{
			fprintf(stderr,"There is no extension in the filename!!!\n");
			fprintf(stderr,"Could not continue! Error in FindFileAssociation in [association.c]\n");
			free(result);
			result=NULL;
			return NULL;
		}
		p++;
	}
	p++; //step to the extensions after the dot
	
	//Opening the config file
	home=getenv("HOME");
	if(!home)
	{
		fprintf(stderr,"Could not take the home directory!\n");
		fprintf(stderr,"Error in FindFileAssociation [association.c]\n");
		return NULL;
	}
	memset(conffile,0,2048);
	strcpy(conffile,home);
	strcat(conffile,"/.bohshell_conf");
		
	stream=fopen(conffile,"rt");
	
	if(!stream)
	{
		fprintf(stderr,"There is no config file [~/.bohshell_conf]\n");
		fprintf(stderr,"Could not continue! Error in FindFileAssociation in [association.c]\n");
		free(result);
		result=NULL;
		return NULL;
	}
	
	
	//finding the first tag @start bohsh config
	while(1)
	{
		//free(temp);
		//temp=NULL;
		if(getline(&temp,&n,stream)==-1)
		{
			fprintf(stderr,"Warning!reached the end of configuration file\n");
			fprintf(stderr,"whithout finding tags\n");
			fprintf(stderr,"No association file found\n");
			fclose(stream);
			free(result);
			result=NULL;
			return NULL;
		}
		l=temp;
		
		//space removal
		while(*l==' ')l++;
		
		if(*l=='@')
		{
		
		
			//verifying
			j=l;
			while(*j!='\0')
			{
				if(*j=='\n')
				{
					*j='\0';
					break;
				}
				j++;
			}
			
			if(strcmp(l,"@start association\0")!=0)
			{
				printf("%s\n",l);
				fprintf(stderr,"Warning!error in the parsing of configuration file\n");
				fprintf(stderr,"could not find @start association config\n");
				fprintf(stderr,"No association file found\n");
			}	
			else
			{
				printf("HERE\n");
				break;
			}	
		}
		memset(temp,0,2048);
	}
	
	
	
	
	//finding the program association
	memset(temp,0,2048);
	while(1)
	{
	printf("HERE1\n");
		if(getline(&temp,&n,stream)==-1)
		{
			fprintf(stderr,"Warning!reached the end of configuration file\n");
			fprintf(stderr,"whithout finding tags\n");
			fprintf(stderr,"No association file found\n");
			fclose(stream);
			free(result);
			result=NULL;
			return NULL;
		}
		
		
		l=temp;
		
		if(strcmp(p,"@end association\0")==0)
		{
			fprintf(stderr,"Warning!reached the end of configuration tag\n");
			fprintf(stderr,"whithout finding associations\n");
			fprintf(stderr,"No association file found\n");
			fclose(stream);
			free(result);
			result=NULL;
			return NULL;
		}
		
		
		while(*l==' ') l++;
		
		//copyng the extension
		memset(ext,0,2048);
		for(i=0; i<2047; i++)
		{
			//we exit if we reach the end of the config string
			//because we have no program associated with the extension
			if(*l=='\0' || *l=='\n')
			{
				fprintf(stderr,"Error! Bad config option\n");
				fprintf(stderr,"in the association settings\n");
				fprintf(stderr,"No program associated to an extension\n");
				fclose(stream);
				free(result);
				result=NULL;
				return NULL;
			}
			
			//we find the estension!
			//we can exit by this for to control if
			//the extension is the one we are searching for
			if(*l==' ' || *l=='|')
			{
				//space and '|' removal
				while(*l==' ' || *l=='|') 
				{
					l++;
				}
				break;
			}
			
			ext[i]=*l;
			l++;
		}
		ext[i+1]='\0';
		
		
		i=0;
		i=strcmp(p,ext);
		if(i==0)
		{
		
			//return the program name with parameters
			//associated to the extension
			strcpy(result,l);
			printf("FOFO\n");
			//fclose(stream);
			return result;
		}
		
	}//end while find the program association
	
}
In pratica nell'ultimo if vedete prima del return result la chiamata di funzione fclose commentata.
Se la decommento e di conseguenza da bravo chiudo il file il programma mi esplode!
Secondo voi perchè?????

ciao
Gio

Inviato: lun 22 ott 2007, 13:24
da lamarozzo
La mia è solo una risposta al volo.

fclose() può esplodere se chiudi uno stream già chiuso. Non è magari questo il tuo caso? Ho visto che ci sono un po' di fclose() disseminati in giro.

Inviato: lun 22 ott 2007, 14:23
da Blizzard
ciao!
mi hai messo la pulce nell'orecchio e ho controllato!
ogni fclose è seguita da un opportuno return poichè questi casi sono quelli che per un modo o per un altro hanno fallito l'esecuzione....

mah! spero di risolvere... o quanto meno di capire!

grazie
Giovanni

Inviato: lun 22 ott 2007, 14:43
da Mario Vanoni
if (fclose(stream) == 0)
return(result);
else
return(fprintf(stderr, "... quello che serve a capire ..."));

Mario Vanoni

Inviato: lun 22 ott 2007, 14:51
da Mario Vanoni
Domanda:

il programma e` solo per C99 od anche per C89?

Se si`, attento ai commenti // invece di /* ... */
non compilabili in molti ambienti.

Mario Vanoni

Inviato: lun 22 ott 2007, 17:51
da lamarozzo
il segmentation fault lo becchi anche se provi a chiudere uno stream che non hai aperto.

Ad esempio il seguente codice esplode

Codice: Seleziona tutto

FILE *stream=NULL;
fclose(stream);
Magari controlla che il tuo codice non ricada anche in questa casistica.

Inviato: lun 22 ott 2007, 19:38
da Blizzard
ciao!
if (fclose(stream) == 0)
return(result);
else
return(fprintf(stderr, "... quello che serve a capire ..."));
Non servirebbe a nulla in quanto la fclose non ritorna nulla! e proprio lei che genera l'errore in quanto se metto qualche printf dopo non arriva a stamparla.
il programma e` solo per C99 od anche per C89?

Se si`, attento ai commenti // invece di /* ... */
non compilabili in molti ambienti.
Ciao! ho progettato la shell per il C89 in tutto fuor che nei commenti!
magari realizzerò un programma per convertire i commenti in futuro e renderlo aderente anche perchè non mi piace proprio il vecchio sistema dei commenti.
Non me ne sono curato perchè fondamentalmente sono quasi 10 anni che esiste il "nuovo standard" e spero che sia più utilizzato di 3/4 anni fa
il segmentation fault lo becchi anche se provi a chiudere uno stream che non hai aperto.

Ad esempio il seguente codice esplode

Codice:

FILE *stream=NULL;
fclose(stream);
Anche questo è improbabile, poichè se non è possibile aprire il file la funzione ritorna... anche se non è possibile lavorarci esce prima di svolgere qualsiasi operazione.
Se arriva là con successo significa che il file c'è, lo apre e lo legge.

ciao
Gio

Inviato: lun 22 ott 2007, 19:47
da bloodlust
Blizzard ha scritto:
if (fclose(stream) == 0)
return(result);
else
return(fprintf(stderr, "... quello che serve a capire ..."));
Non servirebbe a nulla in quanto la fclose non ritorna nulla! e proprio lei che genera l'errore in quanto se metto qualche printf dopo non arriva a stamparla.
infatti devi testare la validità del file pointer prima di ogni chiamata a fclose().

Inviato: mar 23 ott 2007, 0:02
da Blizzard
ciao!
infatti devi testare la validità del file pointer prima di ogni chiamata a fclose().
io non la testavo perchè se il codice arrivava la il puntatore doveva essere per forza valido.... altrimenti esplodeva prima.
Comunque... solita pulce nell'orecchio e cambio il codice così

Codice: Seleziona tutto

if(i==0)
		{
		
			//return the program name with parameters
			//associated to the extension
			strcpy(result,l);
			printf("FOFO\n");
			if(stream) fclose(stream);
			return result;
		}
Purtroppo il risultato non cambia, perchè il puntatore risulta valido ma esplode lo stesso alla fclose.

ciao
Gio

Inviato: mar 23 ott 2007, 0:42
da targzeta
Ma un debugger lo usi? Altrimenti è difficile venirne a capo, specialmente quando il codice si farà più esteso.

comunque, prova a far sì che il tuo programma si fermi prima, prova, cioé, a modificare il file di configurazione in modo da testare le altre fclose().

Spina

P.S. ma quel "rt" che vuol dire nella fopen?

Inviato: mar 23 ott 2007, 10:24
da absinthe
spina ha scritto:Ma un debugger lo usi? Altrimenti è difficile venirne a capo, specialmente quando il codice si farà più esteso.

comunque, prova a far sì che il tuo programma si fermi prima, prova, cioé, a modificare il file di configurazione in modo da testare le altre fclose().

Spina

P.S. ma quel "rt" che vuol dire nella fopen?
r=read, t=text mode

in effetti se si da un occhio a http://www.opengroup.org/onlinepubs/000 ... fopen.html
si nota che tale modalità non esiste... io la uso da una vita sotto dos/windows. blizzard: non è che hai fatto casino?!

M

Inviato: mar 23 ott 2007, 11:11
da Blizzard
ciao Abshinte,

dici che il prog mi esplode per quella modalità di apertura???
Cavolo... bill mi perseguita ancora :D

Comunque provo e vi faccio sapere.

Ciao
Gio

Inviato: mar 23 ott 2007, 14:54
da lamarozzo
Mi sembra strano che fopen non restituisca NULL se si apre un file con una modalità sconosciuta. Per sicurezza prova a controllare cosa dice la variabile errno
(http://science.unitn.it/~fiorella/guidac/guidac092.html) dopo la chiamata a fopen.

Comunque la modalità "rt" è la prima volta che la sento, stasera provo a vedere se sul K&R è prevista.

Inviato: mer 24 ott 2007, 0:14
da Blizzard
ciao

ho corretto anche il modo di apertura del file ma non cambia le cose...

comunque vedrò di fare il debugging...
in ogni caso domani metto online sul CVS la beta del sistema di associazione file/programma... perchè comunque devo fare un paio di modifiche.

ciao
Gio

Inviato: gio 25 ott 2007, 20:16
da Blizzard
Ciao,
comunque, prova a far sì che il tuo programma si fermi prima, prova, cioé, a modificare il file di configurazione in modo da testare le altre fclose().
Ho provato e ad ogni fclose il programma esplode... o meglio non esplode praticamente sempre ma solo se la fclose è all'interno del blocco:

Codice: Seleziona tutto

if(getline(&temp,&n,stream)==-1)
{
....
....
..
}
in altre parti invece mi chiude tranquillamente il file! :? :? :? :? :? :? :?

vi salta in mente niente????
ciao
Gio