• Viernes 8 de Noviembre de 2024, 14:48

Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.


Mensajes - Zambullo

Páginas: [1]
1
C/C++ / Re: Problema Al Programar Una Minishell
« en: Martes 27 de Mayo de 2008, 19:28 »
Sé que mirar el código de otro es un tostón. Voy a intentar acotar la duda, porque hay una cosa que está mal y seguro que como poco es parte del problema, pero no sé solucionarlo.

En la funcion ejecutar_orden, cojo el pid con fork, y si es hijo ejecuta la orden. El caso es que cuando pongo órdenes con tuberías,el pid nunca vale 0, y por tanto no entra en el if y no se ejecuta nada. Pero si pongo una orden suelta sin tuberías ni redirecciones, sí funciona correctamente. ¿Cómo lo soluciono? Gracias de antemano.

2
C/C++ / Problema Al Programar Una Minishell
« en: Lunes 26 de Mayo de 2008, 21:16 »
¡Buenas!

Estoy un pelín desesperado. El caso es que estoy haciendo una minishell, que puede ejecutar funciones internas (se me pide que programe cd, pwd y algunos más) y las que no, que las ejecute el SO.

Tengo que usar tuberías y redirecciones. El problema que tengo es que cuando pongo cualquier orden con una tubería (hola | hola, por ejemplo), y según veo al ejecutar con strace, el programa hace bien las dos primeras vueltas del bucle (una redireccionando la entrada y otra redireccionando la salida) pero después, en vez de volverme a imprimir el prompt y esperar, lo escribe y sigue dando vueltas al bucle hasta que un SIGSEGV lo termina todo. Yo diría que tanto las tuberías como las señales están bien utilizadas, pero tampoco estoy seguro.

Este es el código de la parte de la que os hablo. Está en C y sobre Linux:

Código: Text
  1.  
  2. //Ejecuta lo que hay entre tuberías
  3. void ejecutar_orden(char *orden, int entrada, int salida , int background){
  4.  
  5.   int indentrada, indsalida, pid, descriptor;
  6.   int *hijos;
  7.   int hijo = 0, estado, i;
  8.   char **array;
  9.   //printf("ejecutar_orden\n");
  10.  
  11.   //parser_orden devuelve un array con la orden diseccionada. Ej. ls en la posicion 0, -l en la 1...
  12.   //También devuelve indentrada, indsalida por si hay < ó > y background 1 ó 0 si hay &
  13.   array = (char **)parser_orden(orden,&indentrada,&indsalida,&background);
  14.   //printf("indentrada %d\n",indentrada);
  15.  
  16.   if (indentrada > -1) {
  17.     printf("entra en indentrada\n");
  18.     if ((descriptor = open(array[indentrada+1], O_RDONLY)) == -1) {
  19.       printf("[Error] al redireccionar la entrada\n");
  20.       exit(-1);
  21.     }
  22.     else
  23.       redirec_entrada(descriptor);
  24.   }
  25.   if (indsalida > -1) {
  26.     if ((descriptor = open(array[indentrada+1], O_WRONLY)) == -1) {
  27.       printf("[Error] al redireccionar la salida\n");
  28.       exit(-1);
  29.     }
  30.     else
  31.       redirec_salida(descriptor);
  32.   }
  33.   if (ord_interna(array) != 0) { //Si no es una orden interna, ejecuta el SO
  34.     printf("No es orden interna\n");
  35.     if ((pid = fork()) == 0) { //Es hijo
  36.       if (execvp(array[0],array) == -1) {
  37.         printf("Error al ejecutar %s\n",array[0]);
  38.         exit(-1);
  39.       }
  40.       //Almaceno los pid de los hijos para que el padre los espere
  41.       hijos[hijo] = (int)malloc(sizeof(int));
  42.       hijos[hijo] = pid;
  43.       hijo++;
  44.     }
  45.     else { //Es padre
  46.       if (background) { //No espera a los hijos
  47.         printf("[Sistema] Ejecutando en segundo plano el proceso %d...\n",pid);
  48.         if(signal(SIGCHLD,manejar_sigchild)==SIG_ERR){
  49.           perror("Error en signal SIGCHLD.\n");
  50.           exit(-1);
  51.         }
  52.       }
  53.       else {  //Espera por los hijos
  54.         for (i = 0; i < hijo; i++) {
  55.           wait(&estado);
  56.         }
  57.       }
  58.     }
  59.   }
  60.        
  61.      
  62. }
  63. //Analiza la entrada a la shell
  64. void ejecutar_linea_ordenes(const char *orden) {
  65.  
  66.   char **lista_ordenes;
  67.   int **pipes;
  68.   int i = 0, total,entrada,salida,background;
  69.   //Disecciona la linea metida por teclado, con un array con las órdenes separadas según las tuberías
  70.   lista_ordenes = (char **)parser_pipes(orden, &total);
  71.   printf("total %d\n",total);
  72.   //crear_pipes crea tantas tuberías como diga total
  73.   pipes = (int **)crear_pipes(total);
  74.   while (i < total) {
  75.     printf("entra en el for\n");
  76.     entrada = 0;
  77.     salida = 0;
  78.     if (total == 1) { //No hay tubería
  79.       printf("entra en el if de total = 1\n");}
  80.     else { //Al menos hay una tubería
  81.       if (i == 0) { //Primera tubería
  82.         printf("entra en el if de i = 0\n");
  83.         salida = pipes[i][1];
  84.         //redirecciona la salida estandar
  85.         redirec_salida(salida);
  86.       }
  87.       else { //Tubería intermedia
  88.         if (i != total - 1) {
  89.           printf("entra en el if intermedio\n");
  90.           entrada = pipes[i-1][0];
  91.           salida = pipes[i][1];
  92.           //Redirecciona la entrada estandar
  93.           redirec_entrada(entrada);
  94.           redirec_salida(salida);
  95.         }
  96.         else { //Última tubería
  97.           printf("entra en el if final\n");
  98.           entrada = pipes[i-1][0];
  99.           redirec_entrada(entrada);
  100.         }
  101.       }
  102.     }
  103.     printf("antes de ejecutar_orden\n");
  104.     ejecutar_orden(lista_ordenes[i],entrada,salida,background);
  105.     i ++;
  106.   }
  107.   printf("Borrar cosas\n");
  108.   for(i=(total-1);i>=0;i--)  free(lista_ordenes[i]);
  109.     free(lista_ordenes); //Liberamos memoria del vector
  110.   destruir_pipes(pipes,total); //Borramos las tuberías
  111. }
  112.  

La función main y el manejador de señal son estos:

Código: Text
  1. void manejar_sigchild(){
  2.   //El hijo ha muerto y eliminamos su PCB
  3.   printf("Ojú\n");
  4.   int estado;  
  5.   wait(&estado);  
  6.   if(signal(SIGCHLD,manejar_sigchild)==SIG_ERR){
  7.     perror("[Sistema] Error, tratamiento de señal SIGCLD");
  8.     exit(0);
  9.   }
  10. }
  11.  
  12. int main(int argc,char* argv[]) {
  13.     char *buf;
  14.     int i = 1;
  15.     signal(SIGCHLD,&manejar_sigchild); //Inicia el manejador de señal
  16.     //signal(SIGINT,manejar_sigkill);
  17.     while (i!=0) {
  18.     buf = (char *)malloc(1024*sizeof(char));
  19.     free(buf);
  20.     imprimir_prompt();
  21.     leer_linea_ordenes(buf);
  22.     if (((strcmp(buf,"exit\0"))==0) || ((strcmp(buf,"quit\0"))== 0))
  23.        i = 0;
  24.     else {
  25.     printf("Entra en el else antes de ejecutarlineaordenes\n");
  26.        ejecutar_linea_ordenes(buf);}
  27.     }
  28.     return 0;
  29. }
  30.  

Si alguno teneis paciencia para mirarlo, os lo agradecería mucho.  :)

3
C/C++ / ¿problema Al Buscar Una Cadena Dentro De Otra?
« en: Viernes 18 de Abril de 2008, 00:04 »
Buenas, soy un novatillo en esto, así que no sé si la duda es un poco ridícula, pero es que ya no sé qué más probar  :( . El título lo pongo como pregunta porque no sé si el problema es con el strstr o quizá es porque no domino bien los punteros, pero no entiendo por qué este código no hace lo que debiera. En principio, el ejercicio hay que hacerlo de dos formas: en la primera se vuelca en memoria el texto de un archivo y se busca una palabra que pueda estar contenida en ese texto. En el otro caso, se lee directamente de un archivo y se busca si una palabra se encuentra en el texto del archivo. Éste último es el que no me funciona, pongo el código:

Código: Text
  1.  
  2.  
  3. /* -------------------------------*/
  4. /*           grep_rw              */
  5. /*                                */
  6. /* Búsqueda de una cadena en      */
  7. /* varios archivos con la técnica */
  8. /* read/write                     */
  9. /*--------------------------------*/
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <fcntl.h>
  15. #include <sys/time.h>
  16.  
  17. int grep_rw (char *cadena, char *archivo) {
  18.  
  19.   int descriptor, valor_lectura, linea=1, linea_vista=0, interruptor=0, i= 0;
  20.   char letra[1], candidata[1024] = "";
  21.   // Nos servimos de la estructura timeval de sys/time.h para guardar los tiempos del principio y fin de ejecución:
  22.   struct timeval ti, tf;
  23.  
  24.   // Tomamos el tiempo antes de empezar las operaciones.
  25.   gettimeofday (&ti, NULL);
  26.  
  27.   // Abrimos fichero.
  28.   descriptor = open(archivo, O_RDONLY);
  29.  
  30.   // Comprobamos si el fichero se ha abierto correctamente.
  31.   if (descriptor == -1) {
  32.      printf("\n-> Error al abrir [%s]", archivo);
  33.      return (0);
  34.      }
  35.   else
  36.      printf("\n-> [%s] abierto correctamente.", archivo);
  37.  
  38.   // Empezamos a leer el fichero:
  39.   valor_lectura = read (descriptor, (char *)letra, 1);
  40.  
  41.   // Comprobamos si ha leído correctamente. Si es así, seguimos leyendo.
  42.   if (valor_lectura == -1)
  43.      printf("\n-> Error al leer [%s]\n", archivo);
  44.   else {
  45.      printf("\n-> Lectura de [%s] correcta.\n", archivo);
  46.          while (valor_lectura > 0) { // Mientras no se acabe el fichero...
  47.      while (letra[0] != '\n') { // Mientras la letra leída no sea un salto de línea...
  48.            // Concatenamos lo que llevamos leído de la línea con la nueva letra leída.
  49.             //i ++;
  50.       sprintf (candidata, "%s%s", candidata, letra);
  51.       valor_lectura = read (descriptor, (char *)letra, 1);
  52.     }
  53.       printf("%s\n", candidata);
  54.            // Comprobamos si la línea candidata que llevamos leída contiene la cadena buscada, y también si ya lo hemos comprobado con esa misma línea.
  55.            //candidata[i+1] = '\0';
  56.       if ((strstr(candidata, cadena) != NULL) && (linea != linea_vista)) {
  57.         interruptor = 1;
  58.         printf("Lalalalalalallal\n");
  59.         printf("\n[%s] está en la línea %d", cadena, linea);
  60.         linea_vista = linea;
  61.       }
  62.            // Seguimos leyendo el fichero.
  63.           // valor_lectura = read (descriptor, (char *)letra, 1);
  64.            //}
  65.     //i = 0;
  66.     linea ++;
  67.     valor_lectura = read (descriptor, (char *)letra, 1);
  68.     // Iniciamos a nada el valor de la línea candidata en la que después buscaremos la cadena.
  69.     candidata[0] = '\0';
  70.     }
  71.   // En caso de que no se haya encontrado ninguna vez la cadena:
  72.   if (interruptor == 0)
  73.   printf("\nNo se ha encontrado la palabra buscada en el archivo %s\n", archivo);
  74.   }
  75.   // Cerramos el fichero y comprobamos si se ha hecho correctamente.
  76.   close(descriptor);
  77.    if (descriptor==-1) {
  78.      printf("\n\n-> ERROR. [%s] no se ha cerrado correctamente\n",archivo);
  79.      return (0);
  80.      }
  81.   else
  82.      printf("\n\n-> [%s] cerrado correctamente\n",archivo);
  83.  
  84.   // Volvemos a tomar el tiempo después de las operaciones y devolvemos un valor de la función igual a la diferencia entre el tiempo inicial y el final (en microsegundos).
  85.   gettimeofday (&tf, NULL);
  86.   return ((tf.tv_sec * 1000000 + tf.tv_usec) - (ti.tv_sec * 1000000 + ti.tv_usec));
  87. }
  88.  

Este grep_rw es llamado por grep, que también dejo aquí, por si hiciese falta:

Código: Text
  1.  
  2. /* -----------------------------*/
  3. /*             grep             */
  4. /*                              */
  5. /* Versión reducida de la orden */
  6. /* grep de UNIX                 */
  7. /*------------------------------*/
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12.  
  13. int main(int argc, char *argv[]) {
  14.  
  15.   int i, tiempo_rw, tiempo_mmap;
  16.  
  17.   // Comprobamos si el número de argumentos es el esperado.
  18.   if (argc < 3)
  19.      printf("-> ERROR: FALTAN ARGUMENTOS (grep <cadena> >nombre_fichero/s>)\n");
  20.   else {
  21.      // A partir del segundo argumento, empezamos a leer tantos ficheros como se hayan pasado.
  22.      for (i = 2; i != argc; i ++) {
  23.     printf("\nVa a comenzar la búsqueda de la cadena [%s] en el archivo [%s] por el método de grep_rw...", argv[1], argv[i]);
  24.     // Llamamos a grep_rw y guardamos su resultado.
  25.     tiempo_rw = grep_rw (argv[1], argv[i]);
  26.  
  27.     printf("\nVa a comenzar la búsqueda de la cadena [%s] en el archivo [%s] por el método de grep_mmap...", argv[1], argv[i]);
  28.     // Llamamos a grep_mmap y guardamos su resultado.
  29.     tiempo_mmap = grep_mmap (argv[1], argv[i]);
  30.     // Escribimos por pantalla el tiempo que ha tardado cada implementación en realizar sus operaciones sobre el mismo archivo.
  31.     printf("\n\nTiempo (microsegundos) necesario para ejecutar %s\n\n",argv[i]);
  32.     printf("grep_rw   : %d\n",tiempo_rw);
  33.     printf("grep_mmap : %d\n\n",tiempo_mmap);
  34.     getchar();
  35.     }
  36.   }
  37.   return(0);
  38. }
  39.  

Gracias de antemano.

Páginas: [1]