/* Ficheros cabecera del sistema */ #include #include #include #include /* Ficheros cabecera de la aplicacion */ #include "tipo_shmem.h" #include "error_shmem.h" /* Constantes */ #define KEY_SEMAFORO #define KEY_SHMEM #define NUM_SEMAFOROS 1 #define NUM_OPERACIONES 1 #define SEMAFORO 0 #define DIM_MENSAJE 100 #define PERMISOS_IPC_SERV IPC_CREAT|0660 #define PERMISOS_IPC_CLIEN 0 #define VALOR_SEM 3 /* Operaciones de semaforos */ struct sembuf espero_servicio = {0, 0, 0}; /* Servidor */ struct sembuf pido_canal = {0, -2, 0}; /* Clientes */ struct sembuf pido_servicio = {0, -1, 0}; /* Clientes */ struct sembuf libero_canal = {0, 3, 0}; /* Servidor */ int semid, shmid ; char *buzon; /* Funcion de declaracion de uso de recursos IPC para el servidor */ int Pido_Recursos_Serv( ) { int ret; /* Obtencion de mecanismos */ semid = semget( KEY_SEMAFORO, NUM_SEMAFOROS, =? ); if ( semid == -1 ) return( ERR_SEMGET ); shmid = shmget( =?, DIM_MENSAJE, PERMISOS_IPC_SERV ); if ( shmid == -1 ) return( ERR_SHMGET ); /* Inicializacion de mecanismos */ if ( semctl( semid, SEMAFORO, =?, VALOR_SEM ) == 1 ) return( ERR_SEMCTL); buzon = (char *)shmat( =?, 0, 0 ); if ( buzon == (void *)-1 ) return( ERR_SHMAT ); return(NO_ERROR); } /* Funcion de declaracion de uso de recursos IPC para los clientes */ int Pido_Recursos_Clien( ) { int ret; /* Obtencion de mecanismos */ semid = semget( KEY_SEMAFORO, NUM_SEMAFOROS, =? ); if ( semid == -1 ) return( ERR_SEMGET ); shmid = shmget( =?, DIM_MENSAJE, PERMISOS_IPC_CLIEN ); if ( shmid == -1 ) return( ERR_SHMGET ); /* Inicializacion de mecanismos */ buzon = (char *)shmat( =?, 0, 0 ); if ( buzon == (void *)-1 ) return( ERR_SHMAT ); return( NO_ERROR ); } /* Funcion invocada por el servidor para recibir peticiones de servicios */ int Espero_Peticion( buff ) mensaje buff; { char *ret_char; /* Esperamos por solicitud de un servicio */ if ( semop( =?, &espero_servicio, NUM_OPERACIONES ) < 0 ) return( ERR_SEMOP ); /* Extraemos el contenido del mensaje */ ret_char = memcpy( buff, (char *)buzon, DIM_MENSAJE ); return( NO_ERROR ); } /* Funcion invocada por los clientes para realizar una peticion */ int Solicito_Servicio( buff ) mensaje buff; { char *ret_char; if ( semop( semid, &pido_canal, NUM_OPERACIONES ) < 0 ) { return( ERR_SEMOP ); } ret_char = memcpy( buzon, buff, DIM_MENSAJE ); if ( semop( =?, &pido_servicio , NUM_OPERACIONES ) < 0 ) { return( ERR_SEMOP ); } return( NO_ERROR ); } /* Funcion invocada por el servidor para permitir mas peticiones */ int Permito_Peticiones( ) { int ret; if ( semop( =?, &libero_canal, NUM_OPERACIONES) < 0 ) { return( ERR_SEMOP ); } return( NO_ERROR ); } /* Funcion de liberacion de recursos ipc para clientes */ int Finaliza_Cliente( ) { if ( shmdt( (void *)buzon ) < 0 ) return( ERR_SHMDT ); else return( NO_ERROR ); } /* Funcion de liberacion y borrado de recursos ipc para servidor */ int Finaliza_Servidor( ) { if ( shmdt( (void *)buzon ) < 0 ) return( ERR_SHMDT ); if ( shmctl( shmid, =?, (struct shmid_ds *)0 ) < 0 ) return( ERR_SHMCTL ); if ( semctl( semid, SEMAFORO, =?, 0) < 0 ) return( ERR_SEMCTL ); return( NO_ERROR ); }