Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: RADIACTIVO en 3 Abril 2014, 20:34 pm



Título: Duda minishell
Publicado por: RADIACTIVO en 3 Abril 2014, 20:34 pm
         Hola buenas, estoy programando una minishell para ir probando con esto de c. Estoy programando en debian con gcc 4.4 .
El comando que estoy intentando emular es grep "model name" < <input_file> .
         El caso es que no consigo hacerlo bien. No tiene mucho misterio, pero creo que me hago un lío con la función dup2(). Creo que no redirecciono bien las salidas, pero por mas que leo en internet no entiendo porque esta mal.

         Les dejo solo un main() con la función. Antes de meterlo en la minishell, programo los comandos en "módulos" diferentes hasta que funcionan debidamente.

         Gracias de antemano, cualquier ayuda es bien recibida. Saludos


Código:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int pid=0;
int sys_call_response=0;
int my_pipe[2];
int fd=0;


int main()
{
        char input_file[20];
        scanf("%s", input_file);
        fd =open(input_file, O_CREAT | O_RDWR, 0666);
        char *arguments[3] = {"grep","model name",NULL};
        pid = fork();

        if(pid==0)
        {
                dup2(fd,1);
                sys_call_response = execvp(arguments[0], arguments);
                exit(0);
        }

        else wait(NULL);
        return 0;
}


Título: Re: Duda minishell
Publicado por: SARGE553413 en 4 Abril 2014, 00:53 am
Hola.

Por lo que leo intentas hacer algo como grep "[regexp]" < [fichero_de_texto], pero con grep no hace falta poner el '<', simplemente:
grep grep "[regexp]"  [fichero_de_texto]
Por ejemplo:
grep "asdasd" fich1 ==> ok
grep "asdasd" < fich1 ==> no ok

Además, cuando haces dup2(), esta función devuelve un nuevo descriptor de fichero, y deberías cerrar el antiguo, me explico:

Código:
    int fd=creat(fichName,0644);
    //Creamos un descriptor para el fichero (el mas bajo disponible
    //como no he cerrado ninguno, sería el 3 en principio).
    int nuevoFd=dup2(fd,1);
    //Duplico el descriptor 'fd' para asignárselo al descriptor 1 (stdout)
    //de tal manera que la salida estándar ha pasado a ser el fichero en
    //cuestión.
    close(fd);
    //Ya no necesito el antiguo descriptor, cierro.

Si no cierras el otro, creo que tendras el mismo descriptor apuntando a dos sitios a la vez.

Por otro lado, al crear el proceso hijo luego haces solo un if() para ver si es el hijo, pero el proceso padre debe esperar a que acabe el hijo. Así:
Código:
int n=fork();
switch(n){
case -1:
cerr<<"ERROR"<<endl;
break;
case 0:
//soy el proceso hijo, ahora voy a hacer mis cosas...
break;
default:
                       //soy el proceso padre, voy a esperar a mi hijo:
wait(NULL);
break;
}

Saludos.

PD. yo he tenido que hacer una práctica de crear un minishell, la tengo y está bastante documentada (el código con explicaciones y tal), si la quieres pídela.


Título: Re: Duda minishell
Publicado por: RADIACTIVO en 4 Abril 2014, 15:27 pm
Muchas gracias  SARGE553413, me han venido muy bien tus consejos. ;D
Finalmente he resuetlo mi problema. A pesar de los errores que me has comentado, me he dado cuenta que era lo que no entendia.
Solo habia que redirigir la entrada estandar.

Código:
dup2(fd,0);

Siento las molestias y agradezco la ayuda.
Saludos


Título: Re: Duda minishell
Publicado por: xaps en 4 Abril 2014, 18:54 pm
No sería mejor recibir los parámetros desde el argv? Es decir, tu puedes crear una declaración de este tipo:
Código
  1. int main(int argc, char* argv[])
  2. {
  3.  ...
  4. }
  5.  
Entonces, si tu aplicación es app.exe, cuando hagas desde consola (Linux en este caso) "./a.exe parametro1 parametro2", argc será 3 (argument counter) y argv será {"a.exe", "parametro1", "parametro2"}, de manera que no tendrás que preocuparte por leer los datos.


Título: Re: Duda minishell
Publicado por: RADIACTIVO en 6 Abril 2014, 10:16 am
   Si eso ya lo habia probado y efectivamente funciona. Pero es mas divertido hacer esas cosas manualmente, por lo menos para aprender.  ;D
  Estoy pensando en subir el codigo de la shell cuando acabe a ver que les parece, y asi me podrian dar ideas, consejos y cosas para sguir mejorando.
  Gracias otra vez! Saludos