Informe minishell

16
ESCUELA POLITÉCNICA NACIONAL CARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN SISTEMAS OPERATIVOS NOMBRE: Alexander Pinchao INFORME Programa para una mini Shell #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <sys/mman.h> #include <pthread.h> #include <semaphore.h> #include <sys/file.h> #include <time.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/times.h> #include <sys/time.h> #include <unistd.h> extern int fork(); extern int pipe(); /* Define constante nominada*/ #define PROMPT "veroshell@vero-linux:$ " #define ESPACIO ' ' #define TUBERIA '|' #define ENTRADA '<' #define SALIDA '>' #define ERROR "&>" #define VARIABLE '=' #define EXIT 'e' #define INGRESO 'i' #define DOLAR '$' #define BACKGROUND '&' #define MAX_BUF 1024 #define MAX_COMMS 32 #define MAX_ARGS 32 #define TAMANYO_ALM 1024

description

Minishell desarrollada en c,

Transcript of Informe minishell

Page 1: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao

INFORME

Programa para una mini Shell

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <sys/wait.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <sys/mman.h>#include <pthread.h>#include <semaphore.h>#include <sys/file.h>#include <time.h>#include <sys/ipc.h>#include <sys/sem.h>#include <sys/times.h>#include <sys/time.h>#include <unistd.h>

extern int fork();extern int pipe();

/* Define constante nominada*/#define PROMPT "veroshell@vero-linux:$ "#define ESPACIO ' '#define TUBERIA '|'#define ENTRADA '<'#define SALIDA '>'#define ERROR "&>"#define VARIABLE '='#define EXIT 'e'#define INGRESO 'i'#define DOLAR '$'#define BACKGROUND '&'

#define MAX_BUF 1024#define MAX_COMMS 32#define MAX_ARGS 32#define TAMANYO_ALM 1024#define TB 1024#define ESPERA 1000

char buf[TB];char *bp;int lver=0, larchivo=1, i, lineas=0, desplazamiento=0;int archivo,bytesleidos;int arrange (char *buffer) { int i = 0, j = 0; while (buffer[i]) {

Page 2: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao

while (buffer[i] == ESPACIO) i++; while ((buffer[i] != ESPACIO) && buffer[i]) buffer[j++] = buffer[i++]; if (! buffer[i]) { if (buffer[i-2] == ESPACIO)

buffer[j-2] = '\0'; else buffer[j-1] = '\0'; } else buffer[j++] = ESPACIO; } return j;}int makeargs (char * buffer, char * args[]) { int i = 0; char * puntero = buffer; args[i++] = puntero; while (puntero = strchr(puntero, ESPACIO)) { *puntero++ = '\0'; args[i++] = puntero; } args[i] = NULL; return i;}int environment (char * buffer, char * env[]) { char *puntero = buffer;

if (puntero = strchr(puntero, INGRESO)) { *puntero++ = '\0'; env[0] = buffer; env[1] = puntero; return 1; } return 0;}int background (char * buffer) { char *puntero = buffer; if (puntero = strchr(puntero, BACKGROUND)) { *puntero--; *puntero = '\0'; return 1; } return 0;}int main( int argc, char *argv[] ) {

int continuar;int ingreso;

#ifdef DEBUG int i; #endif char buffer[MAX_BUF], *puntero, value[MAX_BUF], *args[MAX_ARGS], *comms[MAX_COMMS]; int j = 0, k = 0, pid = 0, numargs = 0, actual = 0, anterior = 0, t1[2], t2[2]; printf("\nMinishell de sistemas Operativos");

Page 3: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao

printf("\n\n");do{ printf(PROMPT);printf("\n MENU");printf("\n 1. Procesos en abanico");printf("\n 2. Semaforos");printf("\n 3. Creacion de archivos");printf("\n 4. Copia de un archivo a otro");printf("\n 5. Vector usando lseek");printf("\n 6. Comando tail");printf("\n 7. Pipes");printf("\n 8. Tuberias");printf("\n 9. Hora del sistema");printf("\n 10. Tiempo en modo usuario");printf("\n 11. Comandos");printf("\n Ingrese la opcion a realizar: ");scanf("%i",&ingreso);

if(ingreso==11){ while(1) { printf(PROMPT); if (fgets(buffer, MAX_BUF, stdin) == NULL) continue; arrange(buffer); #ifdef DEBUG printf("Entrada: #%s#\n", buffer); i = 0; #endif if (environment(buffer, args)) { //setenv(args[0], args[1], 1); =

exit(0); } else if (background(buffer)) { if (fork() == 0) {

pid = fork();if (pid) { wait(NULL); printf("Proceso terminado con PID=%d\n", pid); printf(PROMPT); exit(0);}else { execlp(buffer, buffer, NULL); perror("Error de ejecucion de execvp\n"); exit(0);}

} } else if (fork()) wait(NULL); else { numargs = makeargs(buffer, args);

while (args[j] != NULL) {

#ifdef DEBUG

Page 4: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao

printf(" #%s#\n", args[j]);#endifif (args[j][0] == DOLAR) { strcpy(value, getenv(++args[j])); args[j] = value;}if (*args[j] == '|') { args[j] = NULL; anterior = actual; actual = j+1; pipe(t1); #ifdef DEBUG printf("t1[0] = %d, t1[1] = %d\n", t1[0], t1[1]); printf("t2[0] = %d, t2[1] = %d\n", t2[0], t2[1]); printf("Anterior %d\n", anterior); printf("Actual %d\n", actual); #endif if (fork() == 0) { if (anterior != 0) { close(t1[0]); close(t2[1]); close(0); dup(t2[0]); close(1); dup(t1[1]); close(t1[1]); close(t2[0]); } else { close(t1[0]); close(1); dup(t1[1]); close(t1[1]); } execvp(args[anterior], &args[anterior]); perror("Error de execvp\n"); exit(0); } else wait(NULL); t2[0] = t1[0]; t2[1] = t1[1];}j++;

} #ifdef DEBUG printf("t1[0] = %d, t1[1] = %d\n", t1[0], t1[1]); printf("t2[0] = %d, t2[1] = %d\n", t2[0], t2[1]); #endif close(t2[1]); close(0); dup(t2[0]); close(t2[0]); #ifdef DEBUG printf("actual %d\n", actual); #endif execvp(args[actual], &args[actual]); perror("Error de execvp\n"); exit(0); }}}

Page 5: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao

else if(ingreso==1){pid_t pid;

int i; int n = 4; printf ("\nA partir de un proceso padre se crea un abanico de procesos\n"); for (i = 0; i < n; i++) { pid = fork(); if (pid == 0) break; } printf("El padre del proceso %d es %d\n", getpid(), getppid()); exit(0);}else if(ingreso==2){

int pid_p; /* identifica el proceso hijo */int mutex; /* semaforo binario */mutex=inicia(1);if (0==(pid_p=fork()))

proceso_hijo(mutex);else

proceso_padre(mutex);borra_s(mutex);

}else if(ingreso==3){

int fd_archivo;int escrito=0;int aux=0; int longitud=5;char datos[]="Prueba";fd_archivo=creat("Ejemplo",0644);

if(fd_archivo==-1)

{

perror("Archivo no creado"); }

elseprintf("Archivo creado");

while(escrito<longitud){

aux=write(fd_archivo, datos+escrito, longitud-escrito);if(aux>0)

escrito=escrito+aux;}close(fd_archivo);}else if(ingreso==4){

int fd_ent, fd_sal; /* identificadores de archivos */char almacen[TAMANYO_ALM]; /* almacen de E/S */int n_read; /* contador de E/S */

Page 6: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao

/* Abrir el archivo de entrada */fd_ent = open ("Ejemplo", O_RDONLY);if (fd_ent < 0){

perror ("open");exit (-1);

}/* Crear el archivo de salida. Modo de protección: rw-r--r--*/fd_sal = creat ("archivo_salida", 0644);if (fd_sal < 0){

perror ("creat");exit (-1);

}/* Bucle de lectura y escritura */while ((n_read = read (fd_ent, almacen, TAMANYO_ALM)) >0 ){

if (write (fd_sal, almacen, n_read) < n_read){

perror ("write");close (fd_ent);close (fd_sal);exit (-1);

}} if (n_read < 0){

perror ("read");close (fd_ent);close (fd_sal);exit (-1);

}printf("El archivo copiado correctamente en archivo_salida");close (fd_ent);close (fd_sal);

}else if(ingreso==5){

int fd_archivo;int numero; int longitud=10;char datos1[]="ABCDEFGHIJ";char datos2[]="abcdefghij";fd_archivo=creat("Vectores",0644);

if(fd_archivo==-1)

{

perror("No se Puede Crear el Archivo"); }

write(fd_archivo, datos1, longitud);numero= lseek(fd_archivo, 1024,SEEK_SET);write(fd_archivo, datos2, longitud);numero=lseek(fd_archivo, numero+1024,SEEK_SET);

Page 7: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao

write(fd_archivo, datos1, longitud);printf("Archivo escrito con los vectores correctamente");

close(fd_archivo);

}else if(ingreso==6){

archivo=open("Leer", O_RDONLY);while(bytesleidos = read(archivo, buf, TB))//Cuento cuantas lineas

tiene mi archivo{

for(i=0; i<= 1024; i++){

if(buf[i] == '\n')larchivo++;

}if(bytesleidos == -1)

break;}close(archivo);

printf ("\nComando tail\n \n\n");printf("lineas para ver:");scanf("%d",&lver);

if(lver >= larchivo) lver = 0;else{ while(bytesleidos = read(archivo,buf, 1024)) {

for(i=0; i <= 1024; i++){

if(buf[i] != '\n')desplazamiento++;

else{desplazamiento++;lineas++;

}if(lineas == larchivo - lver - 1)

break;}if(bytesleidos == -1)break;

}close(archivo);}

archivo = open("Leer", O_RDONLY);lseek(archivo, desplazamiento, SEEK_SET);while(bytesleidos = read(archivo, buf, TB)){ if(bytesleidos == -1)

break; write(0, buf, bytesleidos);}

Page 8: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao

close(archivo);printf("\n");

}else if(ingreso==7){

int fd[2];char mensaje[] = "\nMensaje enviado a hijo por Vero\n";char buffer[40];pipe(fd);pid_t hijo;if((hijo = fork())<0){

perror("No se puede crear el proceso\n");exit(1);

}if(hijo!= 0){

close(fd[0]);write(fd[1],mensaje,strlen(mensaje));

}else{

close(fd[1]);read(fd[0],buffer,sizeof(buffer));printf("\nLo que se envio por el pipe es: %s",buffer);

}return(0);

}else if(ingreso==8){

int fd1[2]; pid_t pid;

/* se crea la tuberia */ if (pipe(fd1) < 0) { perror("Error al crear la tuberia"); exit(0); } pid = fork(); switch (pid) { case -1: /* error */ perror("Error en el fork"); exit(0); case 0: /* proceso hijo ejecuta ls */ close(fd1[0]); close(STDOUT_FILENO); dup(fd1[1]); close(fd1[1]); execlp("ls", "ls", NULL); perror("Error en el exec"); break; default: /* proceso padre ejecuta wc */ close(fd1[1]); close(STDIN_FILENO); dup(fd1[0]); close(fd1[0]); execlp("wc", "wc", NULL);

Page 9: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao

perror("Error en el exec"); }}else if(ingreso==9){

time_t tiempo;struct tm *fecha;

tiempo= time(NULL);fecha= localtime(&tiempo);/* hay que ajustar el año ya que lo devuelve respecto a 1900 */printf ("%02d/%02d/%04d %02d:%02d:%02d\n",

fecha->tm_mday, fecha->tm_mon,fecha->tm_year+1900, fecha->tm_hour,fecha->tm_min, fecha->tm_sec);

}else if (ingreso==10){

struct tms InfoInicio, InfoFin;clock_t t_inicio, t_fin;long tickporseg;

if (argc<2) {fprintf(stderr, "Uso: %s programa [args]\n", argv[0]);exit(1);

}

tickporseg= sysconf(_SC_CLK_TCK);

t_inicio= times(&InfoInicio);

if (fork()==0) {execvp(argv[1], &argv[1]);perror("error ejecutando el programa");exit(1);

}wait(NULL);t_fin= times(&InfoFin);printf ("Tiempo real: %7.2f\n",

(float)(t_fin - t_inicio)/tickporseg);

printf ("Tiempo de usuario: %7.2f\n",(float)(InfoFin.tms_cutime -

InfoInicio.tms_cutime)/tickporseg);printf ("Tiempo de sistema: %7.2f\n",

(float)(InfoFin.tms_cstime - InfoInicio.tms_cstime)/tickporseg);}printf("\n Desea continuar: 1 0\n");scanf("%d", &continuar);}//do

while(continuar==1);}

Page 10: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao

proceso_hijo(critica)int critica;{

int i,j;for (i=0;i< 5; i++) {

P(critica);printf("Soy el proceso Hijo en el turno %d", i);fflush(stdout); //Limpia el buffer de tecladoretardo ();printf("\n");V(critica);

}exit(1);

}

proceso_padre(critica)int critica;{

int i,j;for (i=0;i< 5; i++){

P(critica); printf("Soy el proceso Padre en el turno %d", i);fflush (stdout); //Limpia el buffer de tecladoretardo ();printf("\n");V(critica);

}

wait(0); /* espera a que finalice el hijo */}

retardo(){

struct timeval tiempo;struct timezone tz;unsigned long inicio, ahora;gettimeofday(&tiempo, &tz);ahora = inicio = tiempo.tv_sec * 1000000 + tiempo.tv_usec;// ESPERA microsegswhile (ahora < inicio + ESPERA){

gettimeofday(&tiempo, &tz);ahora = tiempo.tv_sec * 1000000 + tiempo.tv_usec;

}}

inicia(valor)int valor;{

int semval;int id;union semun

Page 11: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao

{int val;struct semid_ds *buf;ushort *array;

} arg;

//Permisos del semaforo creadoif ((id=semget(IPC_PRIVATE, 1, (IPC_CREAT|0666))) == -1){

perror("Error al crear semaforo.");

return(-1);}arg.val = valor;if (semctl(id, 0, SETVAL, arg) == -1){

perror("Error al inicializar semaforo.");return (-1); /*error en inicializacion*/

}return(id);

}/*Rutina P */P(semaforo)int semaforo;{

if ( semcall(semaforo, -1) == -1 ) perror("Error");

}

/*Rutina V */V(semaforo)int semaforo;{

if ( semcall(semaforo, 1) == -1 ) perror("Error");

}semcall(semaforo, operacion)int semaforo, operacion;{

struct sembuf sb;sb.sem_num = 0;sb.sem_op = operacion;sb.sem_flg = 0;return ( semop(semaforo, &sb, 1) ); /*devuelve -1 si error */

}borra_s(semaforo)int semaforo;{

if ( semctl(semaforo, 0, IPC_RMID, 0) == -1){

perror("Error");return(-1);

}}

Page 12: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao

CAPTURAS:

Page 13: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao

Page 14: Informe minishell

ESCUELA POLITÉCNICA NACIONALCARRERA DE INGENIERÍA EN SISTEMAS INFORMÁTICAS Y DE COMPUTACIÓN

SISTEMAS OPERATIVOSNOMBRE: Alexander Pinchao