Minishell en C

B

¿Alguien ha hecho una minishell en C? Es que estoy haciendo una practica sobre eso y me gustaria partir con algun ejemplo. No quiero que lo tomeis a mal, no penseis que me la voy a copiar. La tengo casi hecha, lo que pasa es que no se como conectar mas de un proceso con tuberias. Tengo hecho todo lo referente a redirecciones, procesos en background, modificacion de variables de entorno y demas, pero justamente lo que me falta es conectar mas de un comando con tuberias.

Por ejemplo, al hacer el comando "ps -l | sed -e '1,$p' | sort" se me queda bloqueado y no continua.

Gracias de antemano.

Ak3larr3

Es para unix por lo que veo, pues lo que tendras que realizar llamadas a sistema del estandar posix dependiendo de la instruccion que quieras realizar.

Por ejemplo, para cambiar de directorio de trabajo usaras la funcion:
chdir(path); Donde path es el nuevo directorio de trabajo y como esas las que sean.
Para obtener la id del usuario seria con
getlogin(); etz.

Quizas la parte mas dificil sea la de lanzar nuevos procesos cuando se implementan ordenes externas.

Recomendacion, si realizas las practicas en una maquina de la universidad o similar con limitacion de procesos por usuario ten mucho cuidado a la hora de implementar la parte de lanzar ordenes externas o puedes llegar a bloquear la cuenta. Lo mejor es usar una distribucion de linux en ordenador local y luego probarla en la maquina de la universidad.

B

Si la estoy haciendo en casa.
No me has respondido a mis dudas.

ZaeRo

"ps -l | sed -e '1,$p' | sort"
q hace sed -e '1,$p' ?? y que contiene la variable p?? seguramente sea algo de esto lo q falle..
si me lo explicas puede q pueda ayudarte ;P

B

Esto es lo que me da en una shell normal,

ramon@phoenix:$ ps -l | sed -e '1,$p' | sort
0 R 1002 11097 11081 0 77 0 - 1088 - pts/1 00:00:00 ps
0 R 1002 11097 11081 0 77 0 - 1088 - pts/1 00:00:00 ps
0 S 1002 11081 11080 0 75 0 - 1343 wait pts/1 00:00:00 bash
0 S 1002 11081 11080 0 75 0 - 1343 wait pts/1 00:00:00 bash
0 S 1002 11098 11081 0 75 0 - 898 pipe_w pts/1 00:00:00 sed
0 S 1002 11098 11081 0 75 0 - 898 pipe_w pts/1 00:00:00 sed
1 D 1002 11099 11081 0 75 0 - 1343 sync_p pts/1 00:00:00 bash
1 D 1002 11099 11081 0 75 0 - 1343 sync_p pts/1 00:00:00 bash
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD

pero este no es el problema, el problema es que sii hago mas de un proceso conectado con tuberia, se queda bloqueado y el prompt no aparece. Aqui tienes el codigo por si quieres echarle una ojeada. Pero solo he hecho para concatenar dos comandos. Aun asi no funciona.
http://usuarios.lycos.es/dargorg/minishell.c

Creo que se podria solucionar haciendo que el proceso padre almacene en un array los pid de los comandos concatenados por tuberias, asi cada uno tendria que hacer un waitpid del anterior comando menos el primero de todos. Por ejemplo, en la linea:
ls -l | sort
el proceso sort deberia hacer un waitpid del proceso ls.

¿Podria ser correcto este planteamiento?

Gracias

Ak3larr3

Buf, eso me supera, yo hice un minishell en C pero con ordenes mas sencillas, ordenes internas, ordenes externas, procesos en segundo plano y redireccion de salida, poco mas y de esto hace mas de un año. Pense que tu duda era otra. Siento no poder ayudarte mas :(

B

Pues me la podias pasar para echarle un vistazo?

ZaeRo

buff x lo q veo tienes bastante mas nivel q yo.. XDDD
a ver, si tu haces un ls | sort dentro de tu escript, te funciona?

B

no, y eso es lo que me fastidia xD, porque tengo que hacer que funcione!!

Ak3larr3

Mañana mismo lo pillo que lo tengo en la particion de la universidad y lo subo a alguna web.

B

Gracias tio, a ver si soluciono algo.

Ak3larr3

Buscando por cds lo he encontrado, aqui esta:

http://rapidshare.de/files/8259949/shell_unix.zip.html

Si no va bien ahi para bajarlo dimelo y lo subo a otro sitio.

B

Es un poco sencilla. Cuando pongo kwrite & no se ejecuta el comando. Ya he detectado un fallo en un solo comando xD

De todas formas, muchas grracias por pasarlo y por intentar ayudarme. Me quedaré con un 0 en esa practica xD.

Ak3larr3

Quizas no es la version final, es la que encontre en un cd pero hice como tropecientos shells de esos y diferentes versiones (tuve esa asignatura dos años para mi desgracia xD) y si, es sencillita ya te lo decia que no llegaba a lo que tu buscabas ni de lejos. Espero que consigas sacar la practica y ya te digo que siento no poder ayudarte mas. Suerte.

B

Si la termino, la pondre aqui para que todo el mundo se la pueda bajar :)

javithelong

Yo hice algo bastante parecido, en so el año pasado, pero la movida es que la comunicacion entre procesos por pipes era optativa, y yo pasé bastante xD

De todas formas, no es un codigo dificil de debugear, usa ddd, y debugeas primero el padre, con la id del fork ( distinta de 0 era? ) y luego a 0 debugeas el hijo.

Tampoco tengo muy fresco el tema, pero vamos, no recuerdo que fuera una práctica complicada, animo :)

DArgo

El DDD me parece que no sirve cuando trabajas con procesos.

NoSHeL

Yo use el DDD con threads, y tb tengo mis dudas sobre si servira con procesos pesados.De todas formas por probar..

B

Acabo de probarlo y no funciona. Hace cosas extrañas al hacer next y step y no me fio. Además tambien imprime errores raros que antes no daban.

No se que hacer ya...

javithelong

DDD si sirve para debuggear procesos... Lo que no te aseguro que funcione bien es la comunicacion por pipes, eso ya nunca lo probé. De todas formas, si el padre tiene que enviarle algo al hijo por un pipe, se lo pones tu a capón (con el ddd) en la variable que tenga que recibirlo y a correr ^^

Cuando hagas el fork, después, modifica lo que te devuelve (modificas el contenido de la variable) poniendole un 0, y asi debuggeas la ejecucion de la instruccion (el hijo).

Si todo va bien, ejecuta el padre después, y ves si funciona (poniendo esa variable a otro numero).

Uhm, y segun recuerdo, debieras hacer waits no bloqueantes en algun momento por si acaba algun hijo para liberarlo bien y no dejar procesos zombies, y justo antes del exit (no recuerdo si lo hiciste) cuando vas a salir, waits bloqueantes hasta que vuelvan todos los hijos (necesitas una tabla con los pids de los hijos para hacerles los waits específicos y saber cuales faltan por volver y cuales no)

B

Ya me esta saliendo la practica. Prometo que en cuanto la termine os la pongo aqui (no como algunos que he visto por ahi que cobran 30 € por esta practica xD).

LOc0

(no como algunos que he visto por ahi que cobran 30 € por esta practica xD).

LOL -> Teleprácticas, dígame.

Salu2 ;)

B

A ver si alguien me hecha un cable con esto, ya que lo unico que me queda es conectar multiples comandos por tuberias.
En realidad esta todo perfecto para que funcione, lo unico que pasa es que el segundo comando se queda bloqueado, por un wait que no se deberia poner (eso me ha dicho el profe), pero es que si lo quito la shell se vuelve loca con los procesos.

En cuestion el codigo esta aqui: http://usuarios.lycos.es/dargorg/shell.c y el error con el wait es el de la linea 198, en el que creo un proceso para que ejecute el comando actual. A ver si me echais una mano y la pongo como ejemplo para los estudiantes de ingenieria informatica.

Lo malo es que la tengo que entregar mañana :(

Saludos a tod@s!

Usuarios habituales