#include #include #include #define path "/usr/bin/bc" // Es necesario actualizar esta linea void alarm_cb (int signum) { printf("Tiempo maximo excedido!\nPresione Enter para continuar\n"); return; } int main (int argc, char *argv[]) { int timeout=5; int correctas=0,total=0,tiempo=0,lapso; int i,status; int bc_in[2],bc_out[2]; char inbuf[1024]; char lectmp[200]; char respuesta[1024]; FILE *expr; FILE *bc; FILE *tmp; pid_t pid; printf("Rapidez Aritmetica\nAutor: Gonzalo Vasquez Saez\n"); if (argc<2 || argc>3 || (argc==3 && atoi(argv[2])<1)) { printf("La sintaxis es: ra filename [timeout]\n\n"); printf("donde:\n-filename es un archivo de texto que contiene "); printf("en cada linea una de las\n expresiones a evaluar\n"); printf("-timeout es un parametro opcional que indica el tiempo "); printf("maximo de espera\n por una respuesta (minimo 1 segundo)\n\n"); exit(1); } if ((expr=fopen(path,"r"))==NULL) { printf("\nLa aplicacion bc no se encuentra en el directorio "); printf(path); printf("\n\nNecesita recompilar modificando la cuarta linea del\n"); printf("archivo ra.c para que se ajuste a su maquina\n\n"); exit(1); } fclose(expr); if (argc==3) timeout=atoi(argv[2]); printf("Timeout: %d segundos\n",timeout); if ((expr=fopen(argv[1],"r"))==NULL) { fprintf(stderr,"No se puede abrir el archivo de expresiones! (%s)\n\n",argv[1]); exit(1); } if (pipe(bc_in)<0) // Pipe de entrada a bc (Expresiones) { perror("Pipe de Expresiones"); exit(1); } if (pipe(bc_out)<0) // Pipe de salida desde bc (Resultados) { perror("Pipe de Resultados"); exit(1); } if ((pid=fork())<0) { perror("Fork!"); exit(1); } if (pid==0) { dup2(bc_out[1],1); // Asociar stdout a esta pipe dup2(bc_in[0],0); // Asociar stdin a esta pipe close(bc_out[0]); // No leeremos de esta pipe close(bc_in[1]); // No escribiremos en esta pipe execl(path,"bc","-q",0); exit(0); } close(bc_out[1]); // No escribiremos en esta pipe close(bc_in[0]); // No leeremos de esta pipe while(fgets(lectmp,200,expr)!=NULL) { total++; signal (SIGALRM, alarm_cb); write(bc_in[1],lectmp,strlen(lectmp)); // entrega expresion a bc alarm(timeout); // activa la alarma de timeout printf("\nEvalue: %sRespuesta: ",lectmp); fgets(inbuf, sizeof(inbuf), stdin); // lee respuesta desde teclado lapso=alarm(0); // registra el tiempo que tomo en responder tiempo+=timeout-lapso; // acumula el tiempo if (lapso!=0) { if (read(bc_out[0],respuesta,1024)<0) // lee respuesta desde bc { perror("Respuesta"); } if (strncmp(respuesta,inbuf,strlen(inbuf))==0) { correctas++; printf("Respuesta Correcta!\n"); } else printf("Respuesta Incorrecta!\n"); } } write(bc_in[1],"quit\n",5); // cierra el bc printf("Respuestas correctas: %d de %d\n",correctas,total); printf("Porcentaje de exactitud: %2.2f%\n\n",(float) (100*(float)(correctas)/(float)(total))); printf("Tiempo promedio de respuesta: %2.2f segundos\n\n",(float) ((float)tiempo/(float)total)); close(bc_in[0]); close(bc_in[1]); close(bc_out[0]); close(bc_out[1]); waitpid(pid,&status,0); // espera a que se cierre el bc return 0; }