Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Fabio_loh

Algo novo, segmentation fault xD

Mensagens Recomendadas

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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ã.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.