Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Victor Nunes

[Resolvido] Pipe Multiplo em C

Recommended Posts

pessoal, to precisando fazer um shell em C que execute a seguinte linha de comando ( estilo bash )

 

# ls -l | sort | grep rwx

 

eu consegui ate fazer executar o pipe com 2 comandos, mas e com um numero indefinido? teria que fazer uma recursividade? como faço??? ajudem por favor

 

codigo da função que fiz

void execute( char **cmd, int cmdIndex )
{
  int fd[2];
  int estado;
  pid_t pid;
  
  if( getArrayLength( cmd ) > 1 )
  {
	pipe( fd );
	pid = fork();
	
	if( pid > 0 )
	{
	  char **cmd1 = stringToArray( cmd[cmdIndex], " " );
	  
	  close( fd[0] );
	  dup2( fd[1],1 );
	  close( fd[1] );
	  
	  if( execv( cmd1[0], cmd1 ) )
		puts( "erro pipe 1" );
	}
	else if( pid == 0 )
	{
	  char **cmd2 = stringToArray( cmd[cmdIndex+1], "" );
	  
	  close( fd[1] );
	  dup2( fd[0],0 );
	  close( fd[0] );
	  
	  if( execv( cmd2[0], cmd2 ) )
		puts( "erro pipe 2" );
		
	  wait( &estado );
	}
  }
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você podia postar o código inteiro p/ ninguém ter que ficar correndo atrás de nome de biblioteca e adivinhar o que tem no main.

Compartilhar este post


Link para o post
Compartilhar em outros sites

crie uma stack de execução e vá redirecionando os inputs/outputs.

 

ps.: Se for postar o código inteiro, favor usar um serviço de postagem. Ler um código grande monocromático é muito mais difícil do que ler ele com realce de sintaxe.

por exemplo: codepad.org

Compartilhar este post


Link para o post
Compartilhar em outros sites

Teu raciocínio ta certo.

O problema é que na função execute você cria um processo filho, espera ele acabar e só. No caso de um único pipe, isso funciona. Mas para mais pipes...

 

você vai precisar de uma pilha, quando você executar um pipe, cheque a pilha. Se ela estiver vazia, a execução do comando terminou.

Se ainda houver algum item (comando) na pilha, refaça a função execute.

 

por exemplo:

ls -l | sort | grep qualquer_coisa

você tem que ter uma pilha assim:
[0] grep qualquer_coisa
[1] sort
[2] ls -l

execute: ls -l | sort

você vai ter uma pilha assim:
[0] grep qualquer_coisa
[1] output do "ls -l | sort"

e assim você continua, até sobrar apenas o output desejado na pilha.

Não sei c essa é a melhor forma de fazer isso, mas é como eu faria!

=D

 

http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif

 

ps.: você deve conhecer a função popen(), certo? Acredito que seja um trabalho pra facul.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Teu raciocínio ta certo.

O problema é que na função execute você cria um processo filho, espera ele acabar e só. No caso de um único pipe, isso funciona. Mas para mais pipes...

 

você vai precisar de uma pilha, quando você executar um pipe, cheque a pilha. Se ela estiver vazia, a execução do comando terminou.

Se ainda houver algum item (comando) na pilha, refaça a função execute.

 

por exemplo:

ls -l | sort | grep qualquer_coisa

você tem que ter uma pilha assim:
[0] grep qualquer_coisa
[1] sort
[2] ls -l

execute: ls -l | sort

você vai ter uma pilha assim:
[0] grep qualquer_coisa
[1] output do "ls -l | sort"

e assim você continua, até sobrar apenas o output desejado na pilha.

Não sei c essa é a melhor forma de fazer isso, mas é como eu faria!

=D

 

http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif

 

ps.: você deve conhecer a função popen(), certo? Acredito que seja um trabalho pra facul.

tá, você já é a segunda pessoa que me fala pra eu colocar o resultado na pilha, me professor ( você acertou, é trabalho de facul ) falou pra mim que fez usando recursão... só que o cara é fera né, ele sabe como fazer isso...

 

você poderia me dar um exemplo simples, só pra passar a idéia mesmo, de como faz isso usando a pilha. grato!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, posso sim fazer um exemplo pra você, vou ver se amanhã a noite escrevo qualquer coisa, pode ser?

 

http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif

 

Abraços

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fala Victor,

 

Eu nunca tinha tentado fazer um pipe para mais de dois comandos. A minha idéia da stack é uma furada... =/

Mais vale fazer com recursão, ou então iteratividade (um array de pid_t e vários forks na mesma função)

Eu arrisco dizer que com recursão será mais tranquilo.

 

http://www.cse.ohio-state.edu/~mamrak/CIS7..._lab_notes.html

Eu encontrei o código de um shell, escrito por Keshan Harris. Tem suporte a multiplos pipes e tudo mais. Muito bacana!!

http://codepad.org/KPFuoQIj

 

O teu professor não te deu nenhuma dica de como fazer? Ou como ele fez usando recursão?

 

você fez algum avanço?

 

http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fala Victor,

 

Eu nunca tinha tentado fazer um pipe para mais de dois comandos. A minha idéia da stack é uma furada... =/

Mais vale fazer com recursão, ou então iteratividade (um array de pid_t e vários forks na mesma função)

Eu arrisco dizer que com recursão será mais tranquilo.

 

http://www.cse.ohio-state.edu/~mamrak/CIS7..._lab_notes.html

Eu encontrei o código de um shell, escrito por Keshan Harris. Tem suporte a multiplos pipes e tudo mais. Muito bacana!!

http://codepad.org/KPFuoQIj

 

O teu professor não te deu nenhuma dica de como fazer? Ou como ele fez usando recursão?

 

você fez algum avanço?

 

http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif

pior que não, é pq esse é o extra do shell, o resto todo eu ja fiz...

a intenção era fazer uma implementação que usasse a $PATH do sistema para encontrar o executavel do comando...

=/

pior que é pra terça que vem

Compartilhar este post


Link para o post
Compartilhar em outros sites

pior que o outro código que você me mandou ta meio em C++ e meio em C né?!

haha, eu sou mais familiarizado em Java... mas vou ler com atenção... acho que vai me ajudar

Compartilhar este post


Link para o post
Compartilhar em outros sites

Esse código que eu te mandei é inteiro em C++.

As funções como: pipe, dup2, fork, exec...

não são da linguagem, mas sim do sistema operacional.

 

O mais próximo que eu cheguei foi:

http://codepad.org/b6Pk4g08

 

Se você conseguir resolver, posta aqui. Agora fiquei curioso... hahahaha

Eu postei um tópcio na comunidade do orkut (C/C++ Brasil), tem um pessoal fera lá também!

 

Abraços

Compartilhar este post


Link para o post
Compartilhar em outros sites

Consegui!

 

=D

 

http://codepad.org/I5fdwney

 

Fiz usando uma função iterativa.

A idéia é primeiro cirar todos os pipes, redirecionar todos os inputs/outputs e por último executar os comandos.

 

dado um comando: "a | b | c | d"

teremos 3 pipes e 4 processos
pipes: fd[3][2]

n		proc	   stdin	  stdout
0		 a			 -		 fd[0][1]
1		 b		 fd[0][0]	fd[1][1]
2		 c		 fd[1][0]	fd[2][1]
3		 d		 fd[2][0]		-

Compartilhar este post


Link para o post
Compartilhar em outros sites

Consegui!

 

=D

 

http://codepad.org/I5fdwney

 

Fiz usando uma função iterativa.

A idéia é primeiro cirar todos os pipes, redirecionar todos os inputs/outputs e por último executar os comandos.

 

dado um comando: "a | b | c | d"

teremos 3 pipes e 4 processos
pipes: fd[3][2]

n		proc	   stdin	  stdout
0		 a			 -		 fd[0][1]
1		 b		 fd[0][0]	fd[1][1]
2		 c		 fd[1][0]	fd[2][1]
3		 d		 fd[2][0]		-

 

pow valeu mesmo...

te devo essa... flw

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.