Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Sign in to follow this  
Fabio_loh

Algo novo, segmentation fault xD

Recommended Posts

Fabio_loh

Boas. Tenho um problema com o seguinte pedaço de código.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

#define ALLOC 256


typedef struct {

char **arg; //argumentos 
char *infile; // ficheiro para onde stdin, se nenhum ficheiro for redireccionado é NULL
char *outfile; // ficheiro para onde stout, se nenhum ficheiro for redireccionado é NULL
int background;
} Command_Info;







pid_t exec_simple(Command_Info *cmd_info)

{
int a;	
pid_t pid;  //duas variaveis do tipo pid_t (poderia ter sido só uma)
pid_t pid2;

        pid2 = fork(); //cria processo filho

     if(pid2 = -1) /* erro */

     {
fprintf(stderr,"erro ao fazer fork\n"); //se pid2 for -1 é sinal que dá erro
	exit(-1);

     }
     else if(pid == 0) /* filho */      //tambem poderia ter sido adicionada condicao para o caso de o pid retornado ser o pai (pid > 0);
 {
             a = execvp(cmd_info->arg[0],cmd_info->arg);
	if( a == -1) {
fprintf(stderr,"erro no exec\n"); //se a tiver o valor -1 o exec dá erro
exit(1); }

	else exit(0);

 }
return getpid();
}



int parse_cmd(char *cmd_line, Command_Info *cmd_info)

{
//char* linha = readline("$> ");
char * sap = (char*)malloc (ALLOC); //sap - string a processar
unsigned int acumulador = 0; //incremento a usar para avançar **arg

if(cmd_line == '\0') //devolve -1 se a string for vazia
return -1;

//inicializacao de Command_Info
	cmd_info->arg = (char**)malloc(ALLOC);
    	       *cmd_info->outfile = '\0'; // outfile vazio
              *cmd_info->infile = '\0'; // infile vazio
         	cmd_info->background = 0; //processo corre em foreground

	while (*sap != '\n') //corre o ciclo enquanto a string introduzida não estiver vazia

{
sap = strtok(cmd_line," "); //divide a string por partes usando strtok() tendo o espaço em branco como separador

	 if ( *sap == '<') //se encontrar um < e a seguir vier um infile, o infile é colocado na estrutura , se não devolve -1

		{
		      sap = strtok(NULL," ");
	 if (*sap == '>' | *sap == '\0') return -1; /*se nao for colocado um ficheiro de entrada ou se o simbolo > for 

									colocado exactamente a seguir devolve -1*/
			 else (*cmd_info).infile = sap;

					 	// senao coloca a infile no sitio apropriado da estrutura; cmd_info->infile = sap
		}
	  if (*sap == '>')

		 {
                       		sap = strtok(NULL," ");	    
			  if(*sap =='\0') return -1; // se não for introduzido um finehiro de saida a seguir ao >, devolve -1	

			  else (*cmd_info).outfile = sap;
		}

	   // se ambas as condiçoes de cima falharem , coloca sap na lista de argumentos da estrutura


	(*cmd_info).arg[acumulador] = sap; //coloca sap na lsita de argumentos

	acumulador++; //incrementa o apontador dos argumentos para nao guardar na msma posicao		 

				sap = strtok(NULL," ");

	}
		return 0; //termina com sucesso

}


int main(int argc, char *argv[])

{	

char c[ALLOC];

int a, status;
       	char now[ALLOC];

while(1)

{
      	getcwd(now,sizeof(now)) ;
printf("\n");
        printf("%s>",now);

            fgets(c, ALLOC, stdin);	//le os caracteres introduzidos e devolve uma string

	if (c[strlen(c)-1]=='\n') //se o ultimo caracter for o newline, a string esta vazia

		c[strlen(c)-1]='\0';

	Command_Info estrutura1;

	a = parse_cmd(c, &estrutura1); // utiliza a para simplificar o codigo, parse_cmd é chamado

	if(a != -1)

	{
		printf("\n");

		printf("Infile: %s \n", estrutura1.infile); //mostra infile, outfile e se o processo esta ou nao em background (se estiver é 1);

		printf("Outfile: %s \n", estrutura1.outfile);

		printf("Background; %i \n", estrutura1.background);

		for(a = 0; estrutura1.arg[a] != NULL; a++) //ciclo para imprimir a lista de argumentos no ecra

		{

			printf("Arguments[%i]: %s \n",a, estrutura1.arg[a]);

		}

		printf("\n");

		if(!strcmp(estrutura1.arg[0], "exit"))

			exit(0);

		exec_simple(&estrutura1); //chama a funcao a testar

		wait(&status); //espera que o processo filho termine

	}

}



}

Eu sei que é grandinho, mas agradecia a ajuda, quase de certeza que é do malloc. Preciso mesmo deste código. Desculpem lá o estruturamento, Só estou a começar a estudar C agora ;)

PS: Este código implementa uma shell linux que recebe e executa comandos básicos.

Share this post


Link to post
Share on other sites
Fabio_loh

Tal como o título do post diz, o problema é que obtenho segmentation fault ao correr o executável :/

Share this post


Link to post
Share on other sites
Fabio_loh

Bem, acho que não me fiz entender muito bem xD. Eu compilo esse código usando o gcc. Até aí tudo bem, depois uso o comando  ./(nome do executável) para correr, ele corre. Só que quando introduzo uma frase que supostamente vai ser interpretada e o comando nela contido executado (por exemplo ls –la) aparece "Segmentation fault" escrito no ecrã.

Share this post


Link to post
Share on other sites
Localhost

Começa a pôr printf's com algo e diz em que sitio do código é que isso acontece.


here since 2009

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.