Logo Studenta

Apuntes completos_ ejercicios y prácticas de Sistemas Operativos II Universidad Politécnica de Teruel_ Threads_ Semáforos_ Sincronización de Procesos___

Esta es una vista previa del archivo. Inicie sesión para ver el archivo original

SO2/Atexit.pdf
Área de Arquitectura y Tecnología de Computadores 
EUPT: Sistemas Operativos II 
 
 1
 
Finalización de Procesos 
 
1- Formas normales 
a) Retorno desde la función main 
b) Llamando a la función exit 
c) Llamando a la función _exit 
 
2- Formas anormales 
d) Llamando a la función abort 
e) Terminación a causa de una señal (signal) 
 
Nota: Si la llamada a la función exit( ) estuviese escrita en C, la llamada a la 
función main( ) podría realizarse de la forma : 
 
exit(main(argc, argv)); 
 
 
Funciones para la finalización normal de un proceso: 
 
 _exit: retorna inmediatamente del kernel 
 
_exit - terminate the current process 
 
 #include <unistd.h> 
void _exit(int status); 
 
 exit: realiza algunas labores de limpieza y retorna del kernel 
 
exit - cause normal program termination 
 
 #include <stdlib.h> 
 void exit(int status); 
 
exit realiza un “clean shutdown” de la “standard I/O library”:se llama a la 
función fclose para todos los “open streams” (todos los datos de salida 
“buffered” son escritos en los ficheros, “flushed”) 
 
 
Nota: Las diferentes cabeceras se deben a que exit está especificada por ANSI 
C, mientras que _exit está especificada por POSIX.1 
 
 exit() y _exit() tienen un único argumento entero que se denomina “exit status”. 
 
 El “exit status” de un proceso está indefinido en los siguientes casos: 
a) main realiza un return sin un valor de return 
b) Si _exit o exit son llamadas sin un “exit status” 
c) Si main realiza un return implícito 
 
Nota: Casi todos los shells Unix permiten recoger el “exit status” de un proceso. 
Área de Arquitectura y Tecnología de Computadores 
EUPT: Sistemas Operativos II 
 
 2
 
Función atexit() 
 
 Con ANSI C un proceso puede registrar hasta 32 funciones que pueden ser 
llamadas automáticamente por exit. Estas funciones se denominan “exit handlers” y se 
registran llamando a la función atexit( ) 
 
 atexit - register a function to be called at normal program termination. 
 
 #include <stdlib.h> 
 int atexit(void (*function)(void)); 
 
 Devuelve: 0 si OK, no cero si error. 
 
 La función exit( ) llama a estas funciones en orden inverso a su registro. 
 
 Los “exit handlers” aparecen con ANSI C y se suministran para SVR4 y 
4.3+BSD 
 
 Con ANSI C y POSIX.1, exit( ) primero llama a los “exit handlers” y luego 
“fcloses” los “open streams”. 
 
 Ejemplo: 
 
// Finalizanción de procesos: atexit( ) 
 
#include "error.h" 
 
static void exit1(); 
static void exit2(); 
 
int main( ) 
{ 
 if (atexit(exit2) != 0) error("No se registro exit2"); 
 if (atexit(exit1) != 0) error("No se registro exit1"); 
 
 printf("\n main se acabo \n"); 
 
 exit(0); 
} 
 
static void exit1() 
{ 
 printf("\n exit handler 1 \n"); 
} 
 
static void exit2() 
{ 
 printf("\n exit handler 2 \n"); 
} 
SO2/Practicas_SOII/Ejercicios Operativos I/anillo.c
/*
*** anillo.c ***
Área de Arquitectura y Tecnología de Computadores
EUPT: Sistemas Operativos II
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
int Realiza_Operacion(int num_1, int num_2);
void handler();
int hijo1, hijo2, hijo3;
int main(int argc, char *argv[]){
 int pid_t, pidaux, pidwait;
 int numero, alarma, nuevo_numero, nbytes;
 int buf = 0, status = 0, cont_hijos_fin = 0; 
 int fpipe[3][2];
 pipe(fpipe[0]);
 pipe(fpipe[1]);
 pipe(fpipe[2]);
 numero = atoi(argv[1]);
 alarma = atoi(argv[2]);
 printf("\n Paso 1 del testigo: %d", numero); 
 printf("\n Tiempo máximo permitido para la ejecución %d seg.\n", alarma); 
 alarm(alarma);
 fflush(stdout); 
 sleep(1); 
 if ((hijo1 = fork()) == 0) 
 { 
 close(fpipe[0][1]); 
 close(fpipe[1][0]); 
 close(fpipe[2][0]); 
 close(fpipe[2][1]); 
 read(fpipe[0][0], &buf, 4);
 nuevo_numero = Realiza_Operacion(numero, buf);
 printf("\n Paso 2 del testigo: %d", nuevo_numero); fflush(stdout);
 write(fpipe[1][1], &nuevo_numero, 4);
 exit(1);
 }
 
 if ((hijo2 = fork()) == 0)
 {
 close(fpipe[0][0]);
 close(fpipe[0][1]);
 close(fpipe[1][1]);
 close(fpipe[2][0]);
 read(fpipe[1][0], &buf, 4);
 
 nuevo_numero = Realiza_Operacion(numero, buf);
 printf("\n Paso 3 del testigo: %d", nuevo_numero); 
 fflush(stdout);
 
 write(fpipe[2][1], &nuevo_numero, 4);
 exit(2);
 }
 if ((hijo3 = fork()) == 0)
 {
 close(fpipe[0][0]);
 close(fpipe[1][0]);
 close(fpipe[1][1]);
 close(fpipe[2][1]);
 read(fpipe[2][0], &buf, 4);
 nuevo_numero = Realiza_Operacion(numero, buf);
 printf("\n Paso 4 del testigo: %d", nuevo_numero); fflush(stdout);
 write(fpipe[0][1], &nuevo_numero, 4);
 exit(3);
 }
 signal(SIGALRM, handler);
 sleep(10); //Todos los procesos hijos deben de estar en ejecucion
 write(fpipe[0][1], &numero, 4);
 close(fpipe[0][1]);
 nbytes = read(fpipe[0][0], &buf, 4);
 waitpid(hijo1, &status, 0); 
 printf("\n Proceso %d ha finalizado y su estado es %d", hijo1, status);
 waitpid(hijo2, &status, 0);
 printf("\n Proceso %d ha finalizado y su estado es %d", hijo2, status);
 waitpid(hijo3, &status, 0);
 printf("\n Proceso %d ha finalizado y su estado es %d", hijo3, status);
 if (nbytes == 4)
 printf("\n El resultado de la ejecución del anillo es: %d \n", buf);
 else
 printf("\n La ejecución del anillo ha sido INCORRECTA. \n");
 
 exit(0);
} 
int Realiza_Operacion(int num_1, int num_2)
{
 int num_opera;
 /* */
 // Nuevo código de la función;
 /* */
 num_opera = num_1 * num_2;
 return(num_opera);
}
void handler()
{
 kill(hijo1, SIGKILL);
 kill(hijo2, SIGKILL);
 kill(hijo3, SIGKILL);
 printf("La ejecucion ha sido abortada por incumpliento del tiempo");
 exit(-1);
}
SO2/Practicas_SOII/Ejercicios Operativos I/dimepar.c
//
//	DIMEPAR.C
//
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, char * argv[])
{
 int numero, result=1;
 int status=1;
 numero = atoi(argv[1]);
 if (fork()==0)
 execl("./par", "par", argv[1], NULL);
 else {
 wait(&status);
 result=(status);
 if (result == 1) printf("\n El numero %d: es PAR \n", numero);
 else if (result == 0) printf("\n El numero %d: es IMPAR \n", numero);
 }
 return(0);
}
SO2/Practicas_SOII/Ejercicios Operativos I/impar.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include "itoa.c"
int main(int argc, char * argv[])
{
 int numimpar;
 int presult;
 int status;
 char buf[10];
 
 numimpar=atoi(argv[1]);
 if(numimpar == 0) exit(0);
 else
 {
 numimpar = numimpar - 1;
 itoa(numimpar, buf);
 if (fork()==0)
 execl("./par", "par", buf, NULL);
 else {
 wait(&status); 
 presult=status/256;
 //printf("hola");
 exit(presult);
 }
 }
}
SO2/Practicas_SOII/Ejercicios Operativos I/itoa.c
#include <string.h>
 /* reverse: reverse string s in place */
 void reverse(char s[])
 {
 int i, j;
 char c;
 
 for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
 c = s[i];
 s[i] = s[j];
 s[j] = c;
 }
}
/* itoa: convert n to characters in s */
 void itoa(int n, char s[])
 {
 int i, sign;
 
 if ((sign = n) < 0) /* record sign */
 n = -n; /* make n positive */
 i = 0;
 do { /* generate digits in reverse order */
 s[i++] = n % 10 + '0'; /* get next digit */
 } while ((n /= 10) > 0); /* delete it */
 if (sign < 0)
 s[i++] = '-';
 s[i] = '\0';
 reverse(s);
 }
 
SO2/Practicas_SOII/Ejercicios Operativos I/listaP.c
# include <stdio.h>
int pid_padre, pid_hijo, i=1;
int repeticiones=3;
int main () {
 pid_padre=getpid();
 printf("Soy el proceso creador %d; \n", pid_padre); 
 while (i<=repeticiones) { 
 if (fork()!=0) {
 sleep(1);
 exit(0);
 } else{
 pid_padre=getppid(); 
 pid_hijo=getpid();
 printf("Soy el nuevo proceso %d; mi padre es %d; \n", pid_hijo, pid_padre);
 printf("Mi numero
de orden es %d; \n", i); 
 while (getppid()!=1) {
	wait();
 }
 printf("Mi padre ha finalizado, ahora soy el proceso maestro \n");
 i++;
 }
 }
 exit(0);
}
SO2/Practicas_SOII/Ejercicios Operativos I/par.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include "itoa.c"
int main(int argc, char * argv[])
{
 int presult;
 int numpar;
 int status;
 char buf[10];
 numpar=atoi(argv[1]);
 if(numpar == 0) exit(1);
 else
 {
 numpar = numpar - 1;
 itoa(numpar, buf);
 //printf(buf);
 if (fork()==0)
 execl("./impar", "impar", buf, NULL);
 else {
 //printf("hola");
 wait(&status);
 presult=(status/256);
 exit(presult);
 }
 }
}
// /* itoa: convert n to characters in s */
// void itoa(int n, char s[])
// {
// int i, sign;
// 
// if ((sign = n) < 0) /* record sign */
// n = -n; /* make n positive */
// i = 0;
// do { /* generate digits in reverse order */
// s[i++] = n % 10 + '0'; /* get next digit */
// } while ((n /= 10) > 0); /* delete it */
// if (sign < 0)
// s[i++] = '-';
// s[i] = '\0';
// reverse(s);
// }
// 
// 
// 
// 
// /* reverse: reverse string s in place */
// void reverse(char s[])
// {
// int i, j;
// char c;
// 
// for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
// c = s[i];
// s[i] = s[j];
// s[j] = c;
// }
 
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_1/listaP.c
# include <stdio.h>
int pid_padre, pid_hijo, i=1;
int repeticiones=3;
int main () {
 pid_padre=getpid();
 printf("Soy el proceso creador %d; \n", pid_padre); 
 while (i<=repeticiones) { 
 if (fork()!=0) {
 sleep(1);
 exit(0);
 } else{
 pid_padre=getppid(); 
 pid_hijo=getpid();
 printf("Soy el nuevo proceso %d; mi padre es %d; \n", pid_hijo, pid_padre);
 printf("Mi numero de orden es %d; \n", i); 
 while (getppid()!=1) {
	wait();
 }
 printf("Mi padre ha finalizado, ahora soy el proceso maestro \n");
 i++;
 }
 }
 exit(0);
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_2/anillo.c
/*
*** anillo.c ***
Área de Arquitectura y Tecnología de Computadores
EUPT: Sistemas Operativos II
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
int Realiza_Operacion(int num_1, int num_2);
void handler();
int hijo1, hijo2, hijo3;
int main(int argc, char *argv[]){
 int pid_t, pidaux, pidwait;
 int numero, alarma, nuevo_numero, nbytes;
 int buf = 0, status = 0, cont_hijos_fin = 0; 
 int fpipe[3][2];
 pipe(fpipe[0]);
 pipe(fpipe[1]);
 pipe(fpipe[2]);
 numero = atoi(argv[1]);
 alarma = atoi(argv[2]);
 printf("\n Paso 1 del testigo: %d", numero); 
 printf("\n Tiempo máximo permitido para la ejecución %d seg.\n", alarma); 
 alarm(alarma);
 fflush(stdout); 
 sleep(1); 
 if ((hijo1 = fork()) == 0) 
 { 
 close(fpipe[0][1]); 
 close(fpipe[1][0]); 
 close(fpipe[2][0]); 
 close(fpipe[2][1]); 
 read(fpipe[0][0], &buf, 4);
 nuevo_numero = Realiza_Operacion(numero, buf);
 printf("\n Paso 2 del testigo: %d", nuevo_numero); fflush(stdout);
 write(fpipe[1][1], &nuevo_numero, 4);
 exit(1);
 }
 
 if ((hijo2 = fork()) == 0)
 {
 close(fpipe[0][0]);
 close(fpipe[0][1]);
 close(fpipe[1][1]);
 close(fpipe[2][0]);
 read(fpipe[1][0], &buf, 4);
 
 nuevo_numero = Realiza_Operacion(numero, buf);
 printf("\n Paso 3 del testigo: %d", nuevo_numero); 
 fflush(stdout);
 
 write(fpipe[2][1], &nuevo_numero, 4);
 exit(2);
 }
 if ((hijo3 = fork()) == 0)
 {
 close(fpipe[0][0]);
 close(fpipe[1][0]);
 close(fpipe[1][1]);
 close(fpipe[2][1]);
 read(fpipe[2][0], &buf, 4);
 nuevo_numero = Realiza_Operacion(numero, buf);
 printf("\n Paso 4 del testigo: %d", nuevo_numero); fflush(stdout);
 write(fpipe[0][1], &nuevo_numero, 4);
 exit(3);
 }
 signal(SIGALRM, handler);
 sleep(10); //Todos los procesos hijos deben de estar en ejecucion
 write(fpipe[0][1], &numero, 4);
 close(fpipe[0][1]);
 nbytes = read(fpipe[0][0], &buf, 4);
 waitpid(hijo1, &status, 0); 
 printf("\n Proceso %d ha finalizado y su estado es %d", hijo1, status);
 waitpid(hijo2, &status, 0);
 printf("\n Proceso %d ha finalizado y su estado es %d", hijo2, status);
 waitpid(hijo3, &status, 0);
 printf("\n Proceso %d ha finalizado y su estado es %d", hijo3, status);
 if (nbytes == 4)
 printf("\n El resultado de la ejecución del anillo es: %d \n", buf);
 else
 printf("\n La ejecución del anillo ha sido INCORRECTA. \n");
 
 exit(0);
} 
int Realiza_Operacion(int num_1, int num_2)
{
 int num_opera;
 /* */
 // Nuevo código de la función;
 /* */
 num_opera = num_1 * num_2;
 return(num_opera);
}
void handler()
{
 kill(hijo1, SIGKILL);
 kill(hijo2, SIGKILL);
 kill(hijo3, SIGKILL);
 printf("La ejecucion ha sido abortada por incumpliento del tiempo");
 exit(-1);
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/dimepar
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/dimepar.c
//
//	DIMEPAR.C
//
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, char * argv[])
{
 int numero, result=1;
 int status=1;
 numero = atoi(argv[1]);
 if (fork()==0)
 execl("./par", "par", argv[1], NULL);
 else {
 wait(&status);
 result=(status/256);
 if (result == 1) printf("\n El numero %d: es PAR \n", numero);
 else if (result == 0) printf("\n El numero %d: es IMPAR \n", numero);
 }
 return(0);
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/dimepar.c~
//
//	DIMEPAR.C
//
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, char * argv[])
{
 int numero, result=1;
 int status=1;
 numero = atoi(argv[1]);
 if (fork()==0)
 execl("./par", "par", argv[1], NULL);
 else {
 wait(&status);
 result=(status);
 if (result == 1) printf("\n El numero %d: es PAR \n", numero);
 else if (result == 0) printf("\n El numero %d: es IMPAR \n", numero);
 }
 return(0);
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/impar
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/impar.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include "itoa.c"
int main(int argc, char * argv[])
{
 int numimpar;
 int presult;
 int status;
 char buf[10];
 
 numimpar=atoi(argv[1]);
 if(numimpar == 0) exit(0);
 else
 {
 numimpar = numimpar - 1;
 itoa(numimpar, buf);
 if (fork()==0)
 execl("./par", "par", buf, NULL);
 else {
 wait(&status); 
 presult=status/256;
 //printf("hola");
 exit(presult);
 }
 }
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/itoa.c
#include <string.h>
 /* reverse: reverse string s in place */
 void reverse(char s[])
 {
 int i, j;
 char c;
 
 for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
 c = s[i];
 s[i] = s[j];
 s[j] = c;
 }
}
/* itoa: convert n to characters in s */
 void itoa(int n, char s[])
 {
 int i, sign;
 
 if ((sign = n) < 0) /* record sign */
 n = -n; /* make n positive */
 i = 0;
 do { /* generate digits in reverse order */
 s[i++] = n % 10 + '0'; /* get next digit */
 } while ((n /= 10) > 0); /* delete it */
 if (sign < 0)
 s[i++] = '-';
 s[i] = '\0';
 reverse(s);
 }
 
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/par
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/par.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include "itoa.c"
int main(int argc, char * argv[])
{
 int presult;
 int numpar;
int status;
 char buf[10];
 numpar=atoi(argv[1]);
 if(numpar == 0) exit(1);
 else
 {
 numpar = numpar - 1;
 itoa(numpar, buf);
 //printf(buf);
 if (fork()==0)
 execl("./impar", "impar", buf, NULL);
 else {
 //printf("hola");
 wait(&status);
 presult=(status/256);
 exit(presult);
 }
 }
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/par.c~
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include "itoa.c"
int main(int argc, char * argv[])
{
 int presult;
 int numpar;
 int status;
 char buf[10];
 numpar=atoi(argv[1]);
 if(numpar == 0) exit(1);
 else
 {
 numpar = numpar - 1;
 itoa(numpar, buf);
 //printf(buf);
 if (fork()==0)
 execl("./impar", "impar", buf, NULL);
 else {
 //printf("hola");
 wait(&status);
 presult=(status/256);
 exit(presult);
 }
 }
}
// /* itoa: convert n to characters in s */
// void itoa(int n, char s[])
// {
// int i, sign;
// 
// if ((sign = n) < 0) /* record sign */
// n = -n; /* make n positive */
// i = 0;
// do { /* generate digits in reverse order */
// s[i++] = n % 10 + '0'; /* get next digit */
// } while ((n /= 10) > 0); /* delete it */
// if (sign < 0)
// s[i++] = '-';
// s[i] = '\0';
// reverse(s);
// }
// 
// 
// 
// 
// /* reverse: reverse string s in place */
// void reverse(char s[])
// {
// int i, j;
// char c;
// 
// for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
// c = s[i];
// s[i] = s[j];
// s[j] = c;
// }
 
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/char
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/char.c
#include <sys/types.h>
#include <stdio.h> 
void charatatime(char *str);
 
int main()
{ 
 pid_t pid;
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) charatatime("salida del hijo \n");
 else {
 charatatime("salida del padre \n");
 }
 exit(0);
}
void charatatime(char *str)
{
 char *ptr;
 int c;
 setbuf(stdout, NULL);
 ptr = str;
 do
 {
 c = *ptr;
 putc(c, stdout);
 } while (*ptr++ != '\0');
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/char.c~
#include <sys/types.h>
#include <stdio.h> 
void charatatime(char *str);
 
int main()
{ 
 pid_t pid;
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) charatatime("salida del hijo \n");
 else {
 wait();
 charatatime("salida del padre \n");
 }
 exit(0);
}
void charatatime(char *str)
{
 char *ptr;
 int c;
 setbuf(stdout, NULL);
 ptr = str;
 do
 {
 c = *ptr;
 putc(c, stdout);
 } while (*ptr++ != '\0');
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/charv2
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/charv2.c
#include <sys/types.h>
#include <stdio.h> 
void charatatime(char *str);
 
int main()
{ 
 pid_t pid;
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) charatatime("salida del hijo \n");
 else {
 wait();
 charatatime("salida del padre \n");
 }
 exit(0);
}
void charatatime(char *str)
{
 char *ptr;
 int c;
 setbuf(stdout, NULL);
 ptr = str;
 do
 {
 c = *ptr;
 putc(c, stdout);
 } while (*ptr++ != '\0');
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/charv2.c~
#include <sys/types.h>
#include <stdio.h> 
void charatatime(char *str);
 
int main()
{ 
 pid_t pid;
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) charatatime("salida del hijo \n");
 else {
 charatatime("salida del padre \n");
 }
 exit(0);
}
void charatatime(char *str)
{
 char *ptr;
 int c;
 setbuf(stdout, NULL);
 ptr = str;
 do
 {
 c = *ptr;
 putc(c, stdout);
 } while (*ptr++ != '\0');
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/charv3
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/charv3.c
#include <sys/types.h>
#include <stdio.h> 
void charatatime(char *str);
 
int main()
{ 
 pid_t pid;
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) {
 wait();
 charatatime("salida del hijo \n");
 }
 else {
 charatatime("salida del padre \n");
 }
 exit(0);
}
void charatatime(char *str)
{
 char *ptr;
 int c;
 setbuf(stdout, NULL);
 ptr = str;
 do
 {
 c = *ptr;
 putc(c, stdout);
 } while (*ptr++ != '\0');
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/charv3.c~
#include <sys/types.h>
#include <stdio.h> 
void charatatime(char *str);
 
int main()
{ 
 pid_t pid;
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) {
 wait();
 charatatime("salida del hijo \n");
 exit(0);
 }
 else {
 charatatime("salida del padre \n");
 }
 exit(0);
}
void charatatime(char *str)
{
 char *ptr;
 int c;
 setbuf(stdout, NULL);
 ptr = str;
 do
 {
 c = *ptr;
 putc(c, stdout);
 } while (*ptr++ != '\0');
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_5/sigpipe
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_5/sigpipe.c
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void handler();
int main() 
{
 char* mensaje="hola";
 int df[2];
 
 pipe(df);
 signal(SIGPIPE, handler);
 if (fork()==0) {
 close(df[0]);
 }
 else {
 close(df[0]);
 write(df[1], mensaje, 5);
 }
}
void handler() 
{
 printf("Señal SIGPIPE controlada. \n");
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_5/sigpipe.c~
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void handler();
int main() 
{
 char* mensaje="hola";
 int df[2];
 
 pipe(df);
 if (fork()==0) {
 close(df[0]);
 }
 else {
 close(df[0]);
 write(df[1], mensaje, 5);
 }
}
void handler() 
{
 printf("Señal SIGPIPE controlada. \n");
}
SO2/Practicas_SOII/Ejercicios Operativos I/Problema_6/interprete.c
SO2/Practicas_SOII/fuentes_luisapa/calcular.x
/* 
 Luis C. Aparicio
 Sistemas Operativos
 Área de Arquitectura y Tecnología de computadores
 Fichero de interfaz para la definición de las llamadas a procedimientos remotos (RPC).
 
 calcular.x
*/
program CALCULAR
{
 version UNO
 {
	int sumar(int a, int b) = 1;
	int restar(int a, int b) = 2;
 } = 1;
} = 497307;
SO2/Practicas_SOII/fuentes_luisapa/clientRPC.c
/* 
 Luis C. Aparicio
 Sistemas Operativos
 Área de Arquitectura y Tecnología de computadores
 Programa cliente para la suma y resta de dos enteros utilizando RPC 
 
 clientRPC.c
*/
#include "calcular.h"
int main(int argc, char *argv[])
{
 int num1, num2;
 char *host;
 CLIENT *sv;
 int *ressum, *resres;
 host = argv[1];
 num1 = atoi(argv[2]);
 num2 = atoi(argv[3]);
 sv = clnt_create(host, CALCULAR, UNO, "tcp");
 if (sv == NULL)
 {
 clnt_pcreateerror(host);
 exit(0);
 }
 ressum = sumar_1(num1, num2, sv);
if (ressum == NULL)
 {
 clnt_perror(sv, "error en suma RPC");
 exit(0);
 }
 printf ("La suma %d + %d = %d \n", num1, num2, *ressum);
 resres = restar_1(num1, num2, sv);
 if (resres == NULL)
 {
 clnt_perror(sv, "error en resta RPC");
 exit(0);
 }
 printf ("La resta %d - %d = %d \n", num1, num2, *resres);
 clnt_destroy(sv);
 exit(0);
}
SO2/Practicas_SOII/fuentes_luisapa/clieTCP.c
/* 
 Luis C. Aparicio
 Sistemas Operativos
 Área de Arquitectura y Tecnología de computadores
 Programa cliente para la suma utilizando sockets stream (TCP) 
 
 clieTCP.c
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
 struct sockaddr_in server_addr;
 struct hostent *hp;
 
 char *namehost; 
 int sd, puerto, res;
 int num[2];
 /* Tratamiento de parámetros */
 namehost = argv[1];
 puerto = atoi(argv[2]);
 num[0] = atoi(argv[3]);
 num[1] = atoi(argv[4]);
 sd = socket(AF_INET, SOCK_STREAM, 0);
 /* Se obtine y se rellena la dirección del servidor */
 bzero((char *)&server_addr, sizeof(server_addr));
 /* hp = gethostbyname("esquinazo.unizar.es"); */
 hp = gethostbyname(namehost);
 if (hp == NULL)
 {
 printf("\n Error en la llamada gethostbyname");
 exit(0);
 }
 
 bcopy (hp->h_addr, (char *)&(server_addr.sin_addr), hp->h_length);
 server_addr.sin_family = AF_INET;
 /*server_addr.sin_port = htons(4200); */
 server_addr.sin_port = htons(puerto); 
 /* Se establece la conexión */ 
 if (connect(sd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0)
 {
 perror("\n Error en la llamada connect");
 exit(0);
 } 
 
 /* envía la petición */
 //write(sd, (char *) num, 2 *sizeof(int));
 write(sd, &num, 2 *sizeof(int));
 /* recibe la respuesta */
 //read(sd, (char *)&res, sizeof(int));
 read(sd, &res, sizeof(int));
 printf("\n El resultado es %d \n", res);
 close(sd);
 
 exit(0);
}
SO2/Practicas_SOII/fuentes_luisapa/clieUDP.c
/* 
 Luis C. Aparicio
 Sistemas Operativos
 EUPT: Área de Arquitectura y Tecnología de computadores
 Programa cliente para la suma utilizando sockets datagram (UDP) 
 
 clieUDP.c
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
 struct sockaddr_in server_addr, client_addr;
 struct hostent *hp;
 
 char *namehost; 
 int sd, puerto, res;
 int num[2];
 /* Tratamiento de parámetros */
 namehost = argv[1];
 puerto = atoi(argv[2]);
 num[0] = atoi(argv[3]);
 num[1] = atoi(argv[4]);
 sd = socket(AF_INET, SOCK_DGRAM, 0);
 /* Se optine y se rellena la dirección del servidor */
 bzero((char *)&server_addr, sizeof(server_addr));
 /* hp = gethostbyname("esquinazo.unizar.es"); */
 hp = gethostbyname(namehost);
 if (hp == NULL)
 {
 printf("\n Error en la llamada gethostbyname");
 exit(0);
 }
 
 bcopy (hp->h_addr, (char *)&(server_addr.sin_addr), hp->h_length);
 server_addr.sin_family = AF_INET;
 /*server_addr.sin_port = htons(4400); */
 server_addr.sin_port = htons(puerto); 
 /* Se rellena la dirección del cliente, cuando se utiliza el número de puerto 0,
 el sistema se encarga de asignarle uno */
 bzero((char *) &client_addr, sizeof(client_addr));
 client_addr.sin_family = AF_INET;
 client_addr.sin_addr.s_addr = INADDR_ANY;
 client_addr.sin_port = htons(0); /* puerto asignado por el sistema */
 bind(sd, (struct sockaddr *)&client_addr, sizeof(client_addr));
 
 //sendto(sd, (char *)num, 2 * sizeof(int), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
 sendto(sd, num, 2 * sizeof(int), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
 //recvfrom(sd, (char *)&res, sizeof(int), 0, NULL, NULL);
 recvfrom(sd, &res, sizeof(int), 0, NULL, NULL);
 printf("\n El resultado es %d \n", res);
 close(sd);
 
 exit(0);
}
SO2/Practicas_SOII/fuentes_luisapa/echoall
SO2/Practicas_SOII/fuentes_luisapa/error.h
/*** *** *** *** *** ***/
/*
//	 	LUIS CARLOS APARICIO CARDIEL
// Sistemas Operativos I
//		Ingenieria Tecnica en Informatica de Gestion
//	 	error.h
//		En este fichero se define la funcion syserr()
//		Incluir "error.h" detras de todos los demas includes
*/
#include<errno.h>
#include<stdio.h>
void syserr(char *men)
{
 extern int errno, sys_nerr;
 extern char *sys_errlist[]; 
 fprintf(stderr, "Error %s (%d", men, errno);
 if (errno > 0 && errno < sys_nerr)
 fprintf(stderr, "; %s)\n", sys_errlist[errno]);
 else
 fprintf(stderr, ")\n");
 exit( 1 );
}
void error(char *men)
{
 extern int errno, sys_nerr;
 extern char *sys_errlist[];
 fprintf(stderr, "Error %s (%d", men, errno);
 if (errno > 0 && errno < sys_nerr)
 fprintf(stderr, "; %s)\n", sys_errlist[errno]);
 else
 fprintf(stderr, ")\n");
 
 exit( 2 );
}
SO2/Practicas_SOII/fuentes_luisapa/funcpri.c
#include "funcpri.h"
long cuenta_primos(long min, long max)
{
 long i, contador;
 contador = 0;
 
 for (i = min; i <= max; i++)
 if (esprimo(i)) contador = contador + 1;
 return (contador);
}
long encuentra_primos(long min, long max, long vector[])
{
 long i, contador;
 contador = 0;
 for (i = min; i <= max; i++)
 if (esprimo(i)) vector[contador++] = i;
 return (contador);
}
int esprimo(long n)
{
 long i;
 for (i = 2; i*i <= n; i++)
 if ((n % i) == 0) return (0);
 return (1);
}
SO2/Practicas_SOII/fuentes_luisapa/funcpri.h
#include <stdio.h>
#define MINIMO 1L
#define MAXIMO 1000000L
/* Cuenta los primos entre min y max */
long cuenta_primos(long min, long max);
/* Cuenta y encuentra los primos entre min y max y los devuelve en un vector */
long encuentra_primos(long min, long max, long vector[]);
/* Devuelve TRUE si n es primo */
int esprimo(long n);
SO2/Practicas_SOII/fuentes_luisapa/prac1.c
/* Sistemas Operativos II */
/* prac1.c */
#include <sys/types.h>
#include <unistd.h>
int main()
{
 int glob = 6;
 char buf[] = "Mensaje para la salida estándar \n";
 int var = 88;
 pid_t pid;
 if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
 perror("write error");
 printf("Mensaje antes de función fork \n");
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0)
 {
 glob++;
 var++;
 }
 else sleep(2);
 printf("pid = %d, glob = %d, var = %d \n", getpid(), glob, var);
 exit(0);
}
SO2/Practicas_SOII/fuentes_luisapa/prac10.c
/* Sistemas Operativos II */
/* prac10.c */
#include <unistd.h>
#include <sys/times.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
void do_cmd(char *cmd);
void pr_times(clock_t real, struct tms *tmsstar, struct tms *tmsend);
void pr_exit(int estado);
int main(int argc, char *argv[])
{
 int i;
 for (i = 1; i < argc; i++) do_cmd(argv[i]);
 exit(0);
}
void do_cmd(char *cmd)
{
 struct tms tmsstart, tmsend;
 clock_t start, end;
 int status;
 fprintf(stderr, "\n command: %s \n", cmd);
 if ((start = times (&tmsstart)) == -1) perror("times error");
 if ((status = system(cmd)) < 0) perror("system() error");
 if ((end = times(&tmsend)) == -1) perror("times error");
 pr_times(end - start, &tmsstart, &tmsend);
 pr_exit(status);
}
void pr_times(clock_t real, struct tms *tmsstart, struct tms *tmsend)
{
 static long clktck = 0;
 if (clktck == 0)
 if ((clktck = sysconf(_SC_CLK_TCK)) < 0) perror("sysconf error");
 fprintf(stderr, " real: %7.2f \n", real / (double) clktck);
 fprintf(stderr, " user: %7.2f \n", (tmsend->tms_utime
- tmsstart->tms_utime) / (double) clktck);
 fprintf(stderr, " sys: %7.2f \n", (tmsend->tms_stime - tmsstart->tms_stime) / (double) clktck);
 fprintf(stderr, " child user: %7.2f \n", (tmsend->tms_cutime - tmsstart->tms_cutime) / (double) clktck);
 fprintf(stderr, " child sys: %7.2f \n", (tmsend->tms_cstime - tmsstart->tms_cstime) / (double) clktck);
}
void pr_exit(int estado)
{
 if (WIFEXITED(estado)) printf("Terminacion normal, exit status = %d\n", WEXITSTATUS(estado));
 else if (WIFSIGNALED(estado))
 { 
 printf("Terminacion anormal, numero de signal = %d ", WTERMSIG(estado));
 if (WCOREDUMP(estado)) printf("(se genero fichero core)\n");
 else printf(" \n");
 }
 else if (WIFSTOPPED(estado)) printf("Hijo detenido, numero de signal = %d\n", WSTOPSIG(estado));
}
SO2/Practicas_SOII/fuentes_luisapa/prac11.c
/* Sistemas Operativos II */
/* prac11.c */
#include <stdio.h>
#define READ 0 /* Indice de la terminacion de lectura del pipe */
#define WRITE 1 /* Indice de la terminacion de escritura del pipe */
char *frase = "Soy el proceso hijo y me encuentro bien";
int main()
{
 int fd[2];
 int bytesRead;
 char mensaje[100]; /* Buffer de mensajes del proceso padre */
 pipe (fd); /* Creacion de un unnamed pipe */
 if (fork() == 0) /* El hijo escritor */
 {
 close(fd[READ]); /* Cierro terminacion del pipe no usada */
 write(fd[WRITE], frase, strlen(frase)+1); /* Incluye NULL */
 close(fd[WRITE]);
 }
 else /* El padre lector */
 {
 close(fd[WRITE]); /* Cierre terminacion del pipe no usada */
 bytesRead = read(fd[READ], mensaje, 100);
 printf("El padre ha leido %d bytes: %s \n", bytesRead, mensaje);
 close(fd[READ]);
 }
 exit(0);
}
SO2/Practicas_SOII/fuentes_luisapa/prac13.c
/* Sistemas Operativos II */
/* prac13.c */
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define DEF_PAGER "/usr/bin/more" /* paginador por defecto */
#define MAXLINE 4096
int main(int argc, char *argv[])
{
 int n;
 int fd[2];
 pid_t pid;
 char line[MAXLINE];
 char *s;
 char *pager, *argv0;
 FILE *fp;
 if (argc != 2)
 {
 perror("usage: a.out <pathname>");
 exit(1);
 }
 if ((fp = fopen (argv[1], "r")) == NULL)
 {
 perror(argv[1]);
 exit(1);
 }
 if (pipe(fd) < 0) perror("Error en pipe");
 if ((pid = fork()) < 0) perror("Error en fork");
 
 else if (pid > 0)
 {
 close(fd[0]);
 while (fgets(line, MAXLINE, fp) != NULL)
 {
 n = strlen(line);
 if (write(fd[1], line, n) != n) perror("Error de escritura en la pipe");
 }
 
 if (ferror(fp)) perror("Error en fgets");
 
 close(fd[1]);
 if (waitpid(pid, NULL, 0) < 0) perror ("Error en waitpid");
 exit(0);
 }
 else
 {
 close(fd[1]);
 if (fd[0] != STDIN_FILENO)
 {
 if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) perror("dup2 error to stdin");
 close(fd[0]);
 }
 if ((pager = getenv("PAGER")) == NULL) pager = DEF_PAGER;
 
 if ((argv0 = strrchr(pager, '/')) != NULL) argv0++;
 else argv0 = pager;
 
 if (execl(pager, argv0, 0) < 0) perror(pager);
 }
 
}
SO2/Practicas_SOII/fuentes_luisapa/prac16.c
/* Sistemas Operativos II */
/* prac16.c */
#include <stdio.h>
#define READ 0
#define WRITE 1
int main(int argc, char *argv[])
{
 int fd[2];
 pipe(fd); /* Creación de unnamed pipe */
 if (fork() != 0) /* Padre escritor */
 {
 close(fd[READ]); /* Cierre terminal no usada de la pipe */
 dup2(fd[WRITE], 1); /*Duplicar la terminación usada en stdout */
 
 close(fd[WRITE]); /* Cierre terminación usada original */
 execlp(argv[1], argv[1], NULL); /* Ejecución programa escritor */
 perror("connect");
 }
 else /* Hijo lector */
 {
 close(fd[WRITE]); /* Cierre terminal no usada de la pipe */
 dup2(fd[READ], 0); /* Duplicar la terminación usada en stdin */
 close(fd[READ]); /* Cierre terminación usada original */
 execlp(argv[2], argv[2], NULL); /* Ejecución programa lector */
 perror("connect");
 }
}
SO2/Practicas_SOII/fuentes_luisapa/prac19.c
/* Sistemas Operativos II */
/* prac19.c */
/* Código del proceso padre */
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#define MAXLINE 4096	 /* max line lengh */
static void (sig_pipe(int singo));
int main()
{
 int n;
 int fd1[2], fd2[2];
 pid_t pid;
 char line[MAXLINE];
 if (signal(SIGPIPE, sig_pipe) == SIG_ERR) perror("signal error");
 if (pipe(fd1) < 0 || pipe(fd2) < 0) perror("pipe error");
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid > 0)
 {
 close(fd1[0]);
 close(fd2[1]);
 while(fgets(line, MAXLINE, stdin) != NULL)
 {
 n = strlen(line);
 if (write(fd1[1], line, n) != n) perror("write error to pipe");
 if ((n = read(fd2[0], line, MAXLINE)) < 0) perror("read error form pipe");
 if (n == 0)
 {
	perror("chid close pipe");
 break;
 }
 line[n] = '\0';
 if (fputs(line, stdout) == EOF) perror("fputs error");
 }
 if (ferror(stdin)) perror("fgets error on stdin");
 exit(0);
 }
 else
 {
 close(fd1[1]);
 close(fd2[0]);
 
 if (fd1[0] != STDIN_FILENO)
 {
 if (dup2(fd1[0], STDIN_FILENO) != STDIN_FILENO) perror("dup2 error to stdin");
 close(fd1[0]);
 }
 if (fd2[1] != STDOUT_FILENO)
 {
 if (dup2(fd2[1], STDOUT_FILENO) != STDOUT_FILENO) perror("dup2 error to stdout");
 close(fd2[1]);
 }
 if (execl("./suma2", "suma2", 0) < 0) perror("execl error");
 }
}
static void (sig_pipe(int signo))
{
 printf("SIGPIPE caught \n");
 exit(1);
}
SO2/Practicas_SOII/fuentes_luisapa/prac19_new.c
/* Sistemas Operativos II */
/* prac19.c */
/* Código del proceso padre */
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#define MAXLINE 4096	 /* max line lengh */
static void (sig_pipe(int singo));
int main()
{
 int n;
 int fd1[2], fd2[2];
 pid_t pid;
 char line[MAXLINE];
 if (signal(SIGPIPE, sig_pipe) == SIG_ERR) perror("signal error");
 if (pipe(fd1) < 0 || pipe(fd2) < 0) perror("pipe error");
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid > 0)
 {
 close(fd1[0]);
 close(fd2[1]);
 while(fgets(line, MAXLINE, stdin) != NULL)
 {
 n = strlen(line);
 if (write(fd1[1], line, n) != n) perror("write error to pipe");
 if ((n = read(fd2[0], line, MAXLINE)) < 0) perror("read error form pipe");
 if (n == 0)
 {
	perror("chid close pipe");
 break;
 }
 line[n] = '\0';
 if (fputs(line, stdout) == EOF) perror("fputs error");
 }
 if (ferror(stdin)) perror("fgets error on stdin");
 exit(0);
 }
 else
 {
 close(fd1[1]);
 close(fd2[0]);
 
 if (fd1[0] != STDIN_FILENO)
 {
 if (dup2(fd1[0], STDIN_FILENO) != STDIN_FILENO) perror("dup2 error to stdin");
 close(fd1[0]);
 }
 if (fd2[1] != STDOUT_FILENO)
 {
 if (dup2(fd2[1], STDOUT_FILENO) != STDOUT_FILENO) perror("dup2 error to stdout");
 close(fd2[1]);
 }
 if (execl("./pr20", "pr20", 0) < 0) perror("execl error");
 }
}
static void (sig_pipe(int signo))
{
 printf("SIGPIPE caught \n");
 exit(1);
}
SO2/Practicas_SOII/fuentes_luisapa/prac2.c
/* Sistemas Operativos II */
/* prac2.c */
#include <sys/types.h>
#include <unistd.h>
// #include <vfork.h>	/* Requerido por algunos sistemas */
int main()
{
 int glob = 6;
 int var = 88;
 pid_t pid;
 printf("Mensaje antes de funcion vfork \n");
 if ((pid = vfork()) < 0) perror("vfork error");
else if (pid == 0)
 {
 glob++;
 var++;
 printf("pid = %d, glob = %d, var = %d \n", getpid(), glob, var);
 exit(0);
 }
 
 printf("pid = %d, glob = %d, var = %d \n", getpid(), glob, var);
 exit(0);
}
SO2/Practicas_SOII/fuentes_luisapa/prac20.c
/* Sistemas Operativos II */
/* prac20.c */
#include <stdio.h>
#define MAXLINE 4096 /* max line lengh */
int main()
{
 int int1, int2;
 char cadena[100];
 char line[MAXLINE];
 /*if (setvbuf(stdin, NULL, _IOLBF, 0) != 0) perror("setvbuf error"); 
 if (setvbuf(stdout, NULL, _IOLBF, 0) != 0) perror("setvbuf error"); */
 while (fgets(line, MAXLINE, stdin) != NULL)
 {
 if (sscanf(line, "%d %d", &int1, &int2) == 2)
 { 
 if (printf("%d \n", int1 + int2) == EOF) perror("printf error");
 }
 else
 {
 if (printf("Args. Inválidos \n") == EOF) perror("printf error");
 }
 }
 exit(0);
}
SO2/Practicas_SOII/fuentes_luisapa/prac20_new.c
/* Sistemas Operativos II */
/* prac20.c */
#include <stdio.h>
#define MAXLINE 4096 /* max line lengh */
int main()
{
 int int1, int2;
 char cadena[100];
 char line[MAXLINE];
 if (setvbuf(stdin, NULL, _IOLBF, 0) != 0) perror("setvbuf error"); 
 if (setvbuf(stdout, NULL, _IOLBF, 0) != 0) perror("setvbuf error"); 
 while (fgets(line, MAXLINE, stdin) != NULL)
 {
 if (sscanf(line, "%d %d", &int1, &int2) == 2)
 { 
 if (printf("%d \n", int1 + int2) == EOF) perror("printf error");
 }
 else
 {
 if (printf("Args. Inválidos \n") == EOF) perror("printf error");
 }
 }
 exit(0);
}
SO2/Practicas_SOII/fuentes_luisapa/prac21_e.c
/* Sistemas Operativos II */
/* prac21_e.c */
/* Proceso escritor de named pipe denominado "miPipa" */
#include <stdio.h>
#include <fcntl.h>
int main()
{
 int fd, messageLen, i;
 char message[100];
 sprintf(message, "Hola de PID %d", getpid());
 messageLen = strlen(message) + 1;
 do 
 {
 fd = open ("miPipa", O_WRONLY);
 
 if (fd == -1) 
 {
 printf("\n Error, la FIFO no existe.\n");
 sleep(1);
 }
 } while (fd == -1);
 printf("\n OK, la FIFO ya existe.\n Enviando mensajes ...\n");
 for (i = 1; i <= 3; i++)
 {
 write(fd, message, messageLen);
 sleep(3);
 }
 close(fd);
}
SO2/Practicas_SOII/fuentes_luisapa/prac21_l.c
/* Sistemas Operativos II */
/* prac21_l.c */
/* Proceso lector de named pipe denominado "miPipa" */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int readLine(int fdaux, char *straux);
int main()
{
 int fd;
 char str[100];
 unlink("miPipa");
 mknod("miPipa", S_IFIFO, 0);
 chmod("miPipa", 0770);
 fd = open ("miPipa", O_RDONLY);
 while (readLine(fd, str) > 0) printf("%s\n", str);
 close(fd);
}
int readLine(int fdaux, char *straux)
{
 int n;
 do
 {
 n = read(fdaux, straux, 1);
 } while (n > 0 && *straux++ != NULL);
 return (n);
}
SO2/Practicas_SOII/fuentes_luisapa/prac22.c
/* Sistemas Operativos II */
/* prac22.c */
#include <unistd.h>
#include <signal.h>	/* Requerida por pause */
static void sig_usr(int signo);	/* one handler for both signal */
int main()
{
 if (signal(SIGUSR1, sig_usr) == SIG_ERR)
 {
 perror("can't catch SIGUSR1");
 exit(1);
 }
 if (signal (SIGUSR2, sig_usr) == SIG_ERR)
 {
 perror("can´t catch SIGUSR2");
 exit(1);
 } 
 while (1) pause();
}
static void sig_usr(int signo)
{
 if (signo == SIGUSR1) printf("received SIGUSR1 \n");
 else if (signo == SIGUSR2) printf("received SIGUSR2 \n");
 else
 {
 printf("recieved signal %d \n", signo);
 exit(1);
 }
 return;
}
SO2/Practicas_SOII/fuentes_luisapa/prac23.c
/* Sistemas Operativos II */
/* prac23.c */
#include <pwd.h>
#include <unistd.h>
#include <signal.h>
static void my_alarm();
int main()
{
 int cuenta = 0;
 struct passwd *ptr;
 signal(SIGALRM, my_alarm);
 alarm(1);
 
 while (1)
 {
 cuenta++;
 if ((ptr = getpwnam("luisapa")) == NULL)
 {
 perror("getpwnam error");
 // exit(1);
 }
 
 else if (strcmp(ptr->pw_name, "luisapa") != 0)
 {
 printf("return value corrupted !, pw_name = %s | cuenta %d \n", ptr->pw_name, cuenta);
 cuenta = 0;
 }
 
 }
}
static void my_alarm()
{
 struct passwd *rootptr;
 signal(SIGALRM, my_alarm);
 printf("in signal handler \n");
 if ((rootptr = getpwnam("root")) == NULL)
 {
 perror("gerpwnam(root) error");
 exit(1);
 }
 alarm(1);
 return;
}
SO2/Practicas_SOII/fuentes_luisapa/prac24.c
/* Sistemas Operativos II */
/* prac24.c */
#include <sys/types.h>
#include <stdio.h>
#include <signal.h>
static void sig_cld();
int main()
{
 pid_t pid;
 if (signal(SIGCHLD, sig_cld) == -1) perror ("signal error");
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0)
 {
 sleep(2);
 _exit(0);
 }
 pause();
 exit(0);
}
static void sig_cld()
{
 pid_t pid;
 int status;
 printf("SIGCHLD received \n");
 if (signal(SIGCHLD, sig_cld) == -1) perror("signal error");
 if ((pid = wait(&status)) < 0) perror("wait error");
 printf("pid = %d \n", pid);
 return;
}
SO2/Practicas_SOII/fuentes_luisapa/prac25.c
/* Sistemas Operativos II */
/* prac25.c */
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
static void sig_alrm();
unsigned int sleep2(unsigned int nsecs);
int main()
{
 printf("Acabo de emperzar y me voy a dormir \n");
 sleep2(10);
 printf("Me acabo de despertar \n");
 exit(0);
}
static void sig_alrm()
{
 printf("Estoy en el signal hadler\n");
 return;
}
unsigned int sleep2(unsigned int nsecs)
{
 printf("Estoy en sleep2 \n");
 if(signal (SIGALRM, sig_alrm) == SIG_ERR) return(nsecs);
 alarm(nsecs);	/* start the timer */
 pause();	/* next caught signal wakes us up */
 printf("Salgo de sleep2 \n");
 return(alarm(0));	/* turn off timer, return unslept time */
}
SO2/Practicas_SOII/fuentes_luisapa/prac26.c
/* Sistemas Operativos II */
/* prac26.c */
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#define MAXLINE 4096
static void sig_alrm();
int main()
{
 int n;
 char line[MAXLINE];
 if (signal(SIGALRM, sig_alrm) == SIG_ERR)
 {
 perror("signal(SIGALRM) error");
 exit(1);
 }
	
 alarm(10);
 if ((n = read(STDIN_FILENO, line, MAXLINE)) < 0)
 {
 perror("read error");
 exit(1);
 }
	
 alarm(0);
 write(STDOUT_FILENO, line, n);
 exit(1);
}
static void sig_alrm()
{
 printf("\n Estoy en el hadler\n");
 return;
}
SO2/Practicas_SOII/fuentes_luisapa/prac3.c
/* Sistemas Operativos II */
/* prac3.c */
	
#include <sys/types.h>
#include <sys/wait.h>
void pr_exit(int estado);
int main()
{
 pid_t pid;
 int status;
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) exit(7);
 if (wait(&status) != pid) perror("wait error");
 pr_exit(status);
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) abort();
 if (wait(&status) != pid) perror("wait error");
 pr_exit(status);
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) status = status / 0;
 if (wait(&status) != pid) perror("wait error");
 pr_exit(status);
 exit(0);
}
void pr_exit(int estado)
{
 if (WIFEXITED(estado)) printf("Terminación normal, exit status = %d\n", WEXITSTATUS(estado));
 else if (WIFSIGNALED(estado))
 {
 printf("Terminación anormal, numero de signal = %d ", WTERMSIG(estado));
 if (WCOREDUMP(estado)) printf("(se genero fichero core)\n");
 else printf(" \n");
 }
 else if (WIFSTOPPED(estado))
printf("Hijo detenido, numero de signal = %d\n", WSTOPSIG(estado));
}
SO2/Practicas_SOII/fuentes_luisapa/prac3_1.c
/* Sistemas Operativos II */
/* prac3.c */
	
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
void pr_exit(int estado);
int main()
{
 pid_t pid;
 int status;
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) exit(7);
 if (wait(&status) != pid) perror("wait error");
 pr_exit(status);
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) abort();
 if (wait(&status) != pid) perror("wait error");
 pr_exit(status);
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) status = status / 0;
 if (wait(&status) != pid) perror("wait error");
 pr_exit(status);
	
	printf("\n Prueba hijos STOPPED	\n"); fflush(stdout);
	
	if ((pid = fork()) < 0) perror("fork error");
	else if (pid == 0)
	{
		sleep(40);
		kill (getpid(), SIGSTOP);
		exit(11);
	}
	if (waitpid(pid, &status, WUNTRACED) != pid) perror("waitpid error");
	pr_exit(status);
	
	printf("\n Envía señal SIGCONT o señal de Fin al proceso PDI: %d \n", pid); fflush(stdout);
	
	if (wait(&status) != pid) perror("wait error");
	pr_exit(status);
	
 exit(0);
}
void pr_exit(int estado)
{
 if (WIFEXITED(estado)) printf("Terminación normal, exit status = %d\n", WEXITSTATUS(estado));
 else if (WIFSIGNALED(estado))
 {
 printf("Terminación anormal, numero de signal = %d ", WTERMSIG(estado));
 if (WCOREDUMP(estado)) printf("(se genero fichero core)\n");
 else printf(" \n");
 }
 else if (WIFSTOPPED(estado)) printf("Hijo detenido, numero de signal = %d\n", WSTOPSIG(estado));
}
SO2/Practicas_SOII/fuentes_luisapa/prac4_1.c
/* Sistemas Operativos II */
/* prac4_1.c */
#include <sys/types.h>
#include <stdlib.h>
int main()
{
 pid_t pid;
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) exit(0);
 
 sleep(4);
 
 system("ps -l");
 
 exit(0);
}
SO2/Practicas_SOII/fuentes_luisapa/prac4_2.c
/* Sistemas Operativos II */
/* prac4_2.c */
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
 pid_t pid;
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0)
 {
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid > 0) exit(0);
 sleep(2);
 printf("Second child, parent pid = %d \n", getppid());
 exit(0);
 }
 if (waitpid(pid, NULL, 0) != pid) perror("waitpid error");
 
 exit(0);
}
SO2/Practicas_SOII/fuentes_luisapa/prac5.c
/* Sistemas Operativos II */
/* prac5.c */
#include <sys/types.h>
#include <stdio.h>
void charatatime(char *str);
int main()
{
 pid_t pid;
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0) charatatime("salida del hijo \n");
 else charatatime("salida del padre \n");
 
 exit(0);
}
void charatatime(char *str)
{
 char *ptr;
 int c;
 setbuf(stdout, NULL);
 ptr = str;
 do
 {
 c = *ptr;
 putc(c, stdout);
 } while (*ptr++ != '\0');
}
SO2/Practicas_SOII/fuentes_luisapa/prac6_1.c
/* Sistemas Operativos II */
/* prac6_1.c */
#include <stdio.h>
	
int main(int argc, char *argv[])
{
 int i;
 char **ptr;
 extern char **environ;
	
 for (i = 0; i < argc; i++) printf("argv[%d]: %s \n", i, argv[i]);
	
 ptr = environ;
	
 while (*ptr != NULL)
 {
 printf("%s \n", *ptr);
 ptr++;
 }
	
 exit(0);
}
SO2/Practicas_SOII/fuentes_luisapa/prac6_2.c
/* Sistemas Operativos II */
/* prac6_2.c */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
	
int main()
{
 char *env_init[] = {"USER=unknown", "PATH=/tmp", NULL};
	
 pid_t pid;
 printf("\n Inicio del primer hijo \n\n"); 
 fflush(stdout);		
 
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0)
 {
 if (execle("/export/home0/practicas/atc/soii/echoall", "echoall", "my arg1", "MY ARG2", (char *) 0, env_init) < 0) perror("execle error");
 }
	
 if (waitpid (pid, NULL, 0) < 0) perror("wait error");
 printf("\n\n Finalización del primer hijo \n\n\n"); 
 printf("\n Inicio del segundo hijo \n\n"); 
 fflush(stdout);
	
 if ((pid = fork()) < 0) perror("fork error");
 else if (pid == 0)
 {
 if (execlp("echoall", "echoall", "only 1 arg", (char *) 0) < 0) perror("execlp error");
 }
 if (waitpid (pid, NULL, 0) < 0) perror("wait error");
	
 printf("\n\n Finalización del segundo hijo \n\n\n");
 fflush(stdout);
 exit(0);
}
SO2/Practicas_SOII/fuentes_luisapa/prac7.c
/* Sistemas Operativos II */
/* prac7.c */
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void pr_exit(int estado);
int main(int argc, char *argv[])
{
 int status;
 if (argc < 2)
 {
 perror("Se requiere como argumento una línea de orden");
 exit(1);
 }
 if ((status = system(argv[1])) < 0) perror ("system() error");
 pr_exit(status);
 exit(0);
}
void pr_exit(int estado)
{
 if (WIFEXITED(estado)) printf("Terminación normal, exit status = %d\n", WEXITSTATUS(estado));
 else if (WIFSIGNALED(estado))
 {
 printf("Terminación anormal, numero de signal = %d ", WTERMSIG(estado));
 if (WCOREDUMP(estado)) printf("(se genero fichero core)\n");
 else printf(" \n");
 }
 else if (WIFSTOPPED(estado)) printf("Hijo detenido, numero de signal = %d\n", WSTOPSIG(estado));
}
SO2/Practicas_SOII/fuentes_luisapa/prac9.c
/* Sistemas Operativos II */
/* prac9.c */
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
int mi_system(char *cmdstring);
void pr_exit(int estado);
int main()
{
 int status;
 if ((status = mi_system("date")) < 0) perror("system() error");
 pr_exit(status);
 if ((status = mi_system("nosuchcommand")) < 0) perror("system() error");
 pr_exit(status);
 if ((status = mi_system("who; exit 44")) < 0) perror("system() error");
 pr_exit(status);
 exit(0);
}
void pr_exit(int estado)
{
 if (WIFEXITED(estado)) printf("Terminacion normal, exit status = %d\n", WEXITSTATUS(estado));
 else if (WIFSIGNALED(estado))
 { 
 printf("Terminacion anormal, numero de signal = %d ", WTERMSIG(estado));
 if (WCOREDUMP(estado)) printf("(se genero fichero core)\n");
 else printf(" \n");
 }
 else if (WIFSTOPPED(estado)) printf("Hijo detenido, numero de signal = %d\n", WSTOPSIG(estado));
}
SO2/Practicas_SOII/fuentes_luisapa/servidRPC.c
/* 
 Luis C. Aparicio
 Sistemas Operativos
 Área de Arquitectura y Tecnología de computadores
 Funciones RPC del servidor para la suma y resta de dos enteros
 
 servidRPC.c
*/
#include "calcular.h"
int *sumar_1_svc(int a, int b, struct svc_req *rqstp)
{
 static int r;
 r = a + b;
 return(&r);
}
int *restar_1_svc(int a, int b, struct svc_req *rqstp)
{
 static int r;
 r = a - b;
 return(&r);
}
SO2/Practicas_SOII/fuentes_luisapa/servTCP.c
/* 
 Luis C. Aparicio
 Sistemas Operativos
 Área de Arquitectura y Tecnología de computadores
 Programa servidor de suma utilizando sockets stream (TCP) 
 
 servTCP.c
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
int main()
{
 struct sockaddr_in server_addr, client_addr;
 int sd, sc, salir;
 int size, res;
 int num[2];
 sd = socket(AF_INET, SOCK_STREAM, 0);
 /* Asigna la dirección al socket */
 bzero((char *)&server_addr, sizeof(server_addr));
 server_addr.sin_family = AF_INET;
 server_addr.sin_addr.s_addr = INADDR_ANY;
 server_addr.sin_port = htons(5500);
 bind(sd, &server_addr, sizeof(server_addr));
 listen(sd, 5);
 size = sizeof(client_addr);
 salir = 0;
 while (salir ==
0)
 {
 printf("Esperando conexión en el puerto: 5500\n"); fflush(stdout);
 sc = accept(sd, (struct sockaddr *)&client_addr, &size);
 if(sc < 0) salir = 1;
 else
 {
 /* recibe la petición, dos número enteros */
 //read(sc, (char*) num, 2*sizeof(int));
 read(sc, &num, 2*sizeof(int));
 res = num[0] + num[1];
 printf("\nServicio: %d + %d = %d \n", num[0], num[1], res); fflush(stdout);
 /* envía el resultado y cierra la conexión */
 //write(sc, (char*)&res, sizeof(int));
 write(sc, &res, sizeof(int));
 close (sc);
 }
 }
 printf("\n Error en accept \n"); fflush(stdout);
 close(sd);
 exit(0);
}
SO2/Practicas_SOII/fuentes_luisapa/servUDP.c
/* 
 Luis C. Aparicio
 Sistemas Operativos
 EUPT: Área de Arquitectura y Tecnología de computadores
 Programa servidor de suma utilizando sockets datagram (UDP) 
 
 servUDP.c
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
int main()
{
 struct sockaddr_in server_addr, client_addr;
 int sd;
 int size, res;
 int num[2];
 sd = socket(AF_INET, SOCK_DGRAM, 0);
 /* Asigna la dirección al socket */
 bzero((char *)&server_addr, sizeof(server_addr));
 server_addr.sin_family = AF_INET;
 server_addr.sin_addr.s_addr = INADDR_ANY;
 server_addr.sin_port = htons(4400);
 bind(sd, (struct sockaddr *)&server_addr, sizeof(server_addr));
 size = sizeof(client_addr);
 while (1)
 {
 printf("\nEsperando conexión en el puerto: 4400"); fflush(stdout);
 //recvfrom (sd, (char*) num, 2 * sizeof(int), 0, (struct sockaddr *)&client_addr, &size);
 recvfrom (sd, num, 2 * sizeof(int), 0, (struct sockaddr *)&client_addr, &size);
 
 res = num[0] + num[1];
 printf("\nServicio: %d + %d = %d \n", num[0], num[1], res); fflush(stdout);
 /* Envía la petición al cliente. 
 La estructura client_addr contiene la dirección del socket del cliente */
 
 //sendto(sd, (char*)&res, sizeof(int), 0, (struct sockaddr *)&client_addr, size); 
 sendto(sd, &res, sizeof(int), 0, (struct sockaddr *)&client_addr, size); 
 }
}
SO2/Practicas_SOII/fuentes_luisapa/suma2.c
/* Sistemas Operativos II */
/* suma2.c */
/* Código del filtro que actua como coproceso */
/* Lee dos enteros de la entrada estandard y devuelve su suma por la
 salida estándar */
#include <stdio.h>
#include <unistd.h>
#define MAXLINE 4096	 /* max line lengh */
int main()
{
 int n, int1, int2;
 char line[MAXLINE];
 char c;
 
 while ((n = read(STDIN_FILENO, line, MAXLINE)) > 0)
 { 
 line[n] = '\0';
 if (sscanf(line, "%d %d", &int1, &int2) == 2)
 {
 sprintf(line, "%d \n", int1 + int2);
 n = strlen(line);
 if (write(STDOUT_FILENO, line, n) != n) perror("Error de escritura");
 }
 else
 {
 if (write(STDOUT_FILENO, "Args. no válidos \n", 18) != 18) perror("Error de escritura");
 }
 }
 
 exit(0);
}
SO2/Practicas_SOII/operativos.c
Problema2.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

//NOTA: Para unix la estructura cambia
union semun{
 int val; /*Para SETVAL*/
 struct semid_ds *buf; /*buffer para IPC_STAT y IPC_SET*/
 unsigned short int *array; /*array para GETALL, SETALL*/
 struct seminfo *_buf; /*buffer para IPC_INFO*/
}arg; 

int main(){

 int id_semaforo; //manejador del vector de semaforos
 int key = 5; //Clave numerica que identifica al vector de semaforos
 int cant_sem = 5; // Numero de semaforos a crear
 int i,valor;

/*
la funcion semget, crea un vector se semaforos.
1 argumento: Clave numerica que identifica al vector de semaforos
2 argumento: Numero de semaforos que se quieren crear
3 argumento: Permisos del conjunto de semaforos
*/

 printf("\nParte A: Creo un vector con %d semaforos\n", cant_sem);
 fflush(stdout);

if((id_semaforo = semget(key, cant_sem, IPC_CREAT|0666))!=-1){
 printf("El identificador del vector de semaforos es %d\n\n", id_semaforo);

 printf("Parte B: Inicializo cada semaforo\n");
 i = 0;

/*
La funcion semctl, inicializa los semaforos 
1 argumento: Es el numero del vector que contiene los semaforos
2 argumento: Es el indice del semaforo, dentro de vector.
3 argumento: Comando a ejecutar.
4 argumeto: Puede estar o no, si esta, ira acorde con 
el tercer argumento.
*/
 for(i = 0; i < cant_sem; i++){
 printf("Inicializo el semaforo nº %d\n", i);
 arg.val = 1;
 semctl(id_semaforo, i, SETVAL, arg);
 }
 
 printf("\n");
 fflush(stdout);
 
 printf("Parte C: Enseño los valores de cada semaforo\n");
 
 
 
 for(i = 0; i < cant_sem; i++){
 printf("Muestro el valor del semaforo nº %d, su valor es: \n", i);
 valor = semctl(id_semaforo, i, GETVAL);
 printf("%d\n", valor);
 }
 
 printf("Preparando el resto de la ejecucion...\n\n");
 
 }else{
 printf("ERROR: No se ha podido crear el semaforo\n");
 exit(1);
 
 
 }

}

Filosofos.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>

union semun{
 int val; /*Para SETVAL*/
 struct semid_ds *buf; /*buffer para IPC_STAT y IPC_SET*/
 unsigned short int *array; /*array para GETALL, SETALL*/
 struct seminfo *_buf; /*buffer para IPC_INFO*/
}arg;

void op_signal(int sem, int n);
void op_wait(int sem, int n);

int main(int argc, char *argv[]){

int i, valor_aux, pos_filosofo, tiempo_pensamiento;

int id_semaforo; // Variable donde recogemos el identificador del semaforo
int key = 5; // Clave que identifica al vector de los semaforos.
int cant_sem = 5; // Numero de semaforos que tiene el vector de semaforos.
int valor;				 // En este caso son los palillos chinos.

pos_filosofo = (atoi(argv[1]));
tiempo_pensamiento = (atoi(argv[2]));

if ((id_semaforo = semget(key, cant_sem, 0)) != -1){

	while(1){
		printf("El filosofo %d esta PENSANDO\n\n", pos_filosofo);
		fflush(stdout);
		sleep(tiempo_pensamiento);
		
		//El sleep, se introduce para simular, que el filosofo esta pensando, se intenta
		//que el tiempo de pensamiento para todos los filosofos no sea el mismo
		//Asi es mas divertido :) 
		
		//Ejecucion asimetrica
		if(pos_filosofo % 2 == 0){//La posicion es PAR	

		 printf("El filosofo %d esta EMPEZANDO A COMER\n\n", pos_filosofo);
		 
		 op_wait(id_semaforo, pos_filosofo);
		 op_wait(id_semaforo, ((pos_filosofo + 1) % 5));
		
		 //Sleep para que lo filosofos coman.
		 sleep(tiempo_pensamiento);
		
		
		 printf("El filosofo %d esta TERMINANDO DE COMER\n\n", pos_filosofo);
		 fflush(stdout);
		 
		}else{//Si es impar
		
		//printf("\n pos: %d | pos + 1: %d",pos_filosofo, (pos_filosofo + 1)%5 );
		// fflush(stdout);
		
		 op_wait(id_semaforo, ((pos_filosofo + 1) % 5));
		 op_wait(id_semaforo, pos_filosofo);
		 
		 printf("El filosofo %d esta EMPEZANDO A COMER\n\n", pos_filosofo);
			fflush(stdout);
		
		 for(i = 0; i < 5; i++){
 valor = semctl(id_semaforo, i, GETVAL);
 }
		 //Sleep para que lo filosofos coman.
		 sleep(tiempo_pensamiento);
		
		 printf("El filosofo %d esta TERMINANDO DE COMER\n\n", pos_filosofo);
		 fflush(stdout);
		}
		
		op_signal(id_semaforo, pos_filosofo);
		op_signal(id_semaforo, ((pos_filosofo + 1) % 5));
	}
}else{
	printf("La llamada semget ha fallado su valor es -1\n");
}

	exit(0);
}


void op_signal(int sem, int n){
	
	int valor_semop_signal = 0;
	
	struct sembuf sop; /*Construir un elemento de vector de operaciones*/
	
	sop.sem_num = n;
	sop.sem_op = 1; /*Operacion signal o liberar una copia recurso*/
	sop.sem_flg = 0;
	
	valor_semop_signal = semop(sem, &sop, 1); /*Operacion signal propiamente dicha*/
	
	if(valor_semop_signal == -1){
		printf("ERROR:El valor de semop es -1 en signal\n");
	}//else{
		//printf("El valor de semop es %d\n", valor_semop_signal);
	//}
}

void op_wait(int sem, int n){
	
	int valor_semop_wait = 0;	
	
	struct sembuf
sop; /*Construir un elemento de vectos de operaciones*/
	
	sop.sem_num = n;
	sop.sem_op = -1; /*Operacion wait u obtencion una copia recurso*/
	sop.sem_flg = 0;
	
	valor_semop_wait = semop(sem, &sop, 1); /*Operacion wait propiamente dicha*/
	
	if(valor_semop_wait == -1){
		printf("ERROR: El valor de semop en wait es -1\n");
	}//else{
		//printf("El valor de semop es %d\n", valor_semop_wait);
	//}
}

Prueba_filosofos.sh
#!/bin/bash

./problema2
./filosofos 0 1 &
./filosofos 1 1 &
./filosofos 2 1 &
./filosofos 3 1 &
./filosofos 4 1 &

4 FILOSOFOS SE SIENTAN A LA MESA Y UNO SE QUEDA FUERA
Creasem.c
/*
 * Programa que crea un vector de semaforos
 * para el problema de los filósofos.
 * 
 */

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>


int main() {
 
 
 union semun {
	int val;
	struct semid_ds *buf;
	ushort *array;
 } arg;
 
 int semid;
 int key = 125;
 int numsem = 6;
 int tenedor;
 ushort valtenedor[6] = {1,1,1,1,1,4};
 
 
 //borramos semaforos preexistentes
 if ((semid = semget(key, numsem, 0)) != -1) {
	semctl(semid, 0, IPC_RMID);
 }
 
 //creamos vector de semaforos
 if ((semid = semget(key, numsem, IPC_CREAT | 0600)) != -1) {
 
	//inicializamos semaforo objetos
	/*arg.val = 1;
	for (tenedor = 0; tenedor < 5; tenedor++) {
	 semctl(semid, tenedor, SETVAL, arg);
	} */
	
	arg.array = valtenedor;
	semctl(semid, 0, SETALL, arg);

 }
 
 //Comprobamos que las inicializaciones son correctas
// for (tenedor = 0; tenedor < 6; tenedor++) {
// 	printf("TENEDOR %d = %d \n", tenedor, semctl(semid, tenedor, GETVAL));
// } 
// 
 
 /* semctl(semid, 0, GETALL, arg);
 
 for (tenedor = 0; tenedor < 5; tenedor++) {
	printf("TENEDOR %d = %d \n", tenedor, arg.array[tenedor]);
 }*/
 
 
 return(0);
 
}

Filosofo.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>



void op_wait(int sem, int n);

void op_signal(int sem, int n);

void comer(int n, int numfilosofo);

void pensar(int n, int numfilosofo);


int main(int argc, char* argv[]) {
 
 int semid;
 int key = 125;
 int numsem = 6;
 
 int tiempo;
 int numfilosofo;
 
 
 tiempo = atoi(argv[2]);
 numfilosofo = atoi(argv[1]);
 semid = semget(key, numsem, 0);
 
 
 while(1) {
	pensar(tiempo, numfilosofo); 

	op_wait(semid,5); 	

	printf("El filosofo %d se sienta en la mesa\n", numfilosofo); 
	fflush(stdout);
	op_wait(semid, numfilosofo); 
	op_wait(semid, (numfilosofo + 1) % 5 ); 
 
	comer(tiempo, numfilosofo);
	
	op_signal(semid, numfilosofo);
	op_signal(semid, (numfilosofo + 1) % 5 );
	printf("El filosofo %d se levanta de la mesa\n", numfilosofo); 
	fflush(stdout);
	op_signal(semid, 5);
 }
}


void op_wait(int sem, int n) {
 struct sembuf sop;		/* Construir un elemento de vector de operaciones */
 sop.sem_num = n;
 sop.sem_op = -1;		/* Operación wait u obtención una copia recurso */
 sop.sem_flg = 0;
 semop(sem, &sop, 1);	/* Operación wait propiamente dicha */
}

void op_signal(int sem, int n) {
 struct sembuf sop;		/* Construir un elemento de vector de operaciones */
 sop.sem_num = n;
 sop.sem_op = 1;		/* Operación signal o liberar una copia recurso */
 sop.sem_flg = 0;
 semop(sem, &sop, 1);	/* Operación signal propiamente dicha */
}

void comer(int n, int numfilosofo) {
 printf("\nFilosofo %d empezando a comer...\n", numfilosofo); 
 fflush(stdout);
 sleep(n);
 printf("\nFilosofo %d terminando de comer...", numfilosofo); 
 fflush(stdout);
}

void pensar(int n, int numfilosofo) {
 printf("Filosofo %d pensando...\n", numfilosofo);
 fflush(stdout);
 sleep(n);
}




LECTOR ESCRITOR VERSIÓN 2.
Lec_esc_inicializar.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/types.h>

//#define key_t key;

int crear_sem(int key, int num_sem);
int inicializar_sem(int manejador, int componente, int valor_sem);
int valor_sem (int semid, int pos);
void op_wait(int semid, int pos);
void op_signal(int semid, int pos);



int main(int argc,char *argv[]){
	int semid, num_sem, clave;
	
	if (argc != 3) {
		printf("Error en el numero de argumentos, [clave, num_sem] \n");
		exit(0);
		
	}else{
		
		//obtengo los valores pasados como argumento por consola
		clave = atoi(argv[1]); 	//clave 578557	
		num_sem = atoi(argv[2]);
		int num_lectores = 3;
		
		semid = crear_sem(clave, num_sem);
		inicializar_sem(semid, 0, 1);	//mutex=1
		inicializar_sem(semid, 1, num_lectores);	//lectores = Num_lectores
		
		printf("Se ha creado el semaforo con identificador %d para el problema lector-escritor correctamente \n", semid);
		fflush(stdout);
	}
}


int crear_sem(int key, int num_sem){
	int manejador= 0 ;
	
	manejador = semget(key, num_sem, IPC_CREAT | 0600); //semget devuelve el manejador que identifica al semaforo
	
		if (manejador >=0 ){ //si se ha creado correctamente el identif del sem sera 0 o mayor de cero
		printf("Se ha creado correctamente un vector de semaforos con %d componentes \n", num_sem);
		printf("Ha sido creado correctamente el semaforo con clave= %d\n", key);
		fflush(stdout);
		return(manejador);	
	}else{
		printf("Error al crear el semaforo con clave %d\n ", key);
		exit(1);
	}
}

int inicializar_sem(int manejador, int componente, int valor_sem){
	union semun{
			int val; //para SETVAL
			struct semid_ds *buf; //IPC_STAT y IPC_SET
			unsigned short int *array; //GETALL y SETALL
			struct seminfo *__buf;
	} semctl_arg;
	semctl_arg.val = valor_sem;

	if(semctl(manejador, componente, SETVAL, semctl_arg) == 0) {
		printf("Se ha inicializado correctamente a %d la componente %d del semaforo %d\n", valor_sem, componente, manejador);
		fflush(stdout);
		return(0);
	}else{
		printf("Error al inicializar la componente %d del semaforo %d\n", componente, manejador);
		fflush(stdout);
		return(-1);
	}
}

int valor_sem (int semid, int pos){
		int val_sem; 
		
	 union semun {
	 int val; /* valor para SETVAL */
	 struct semid_ds *buf; /* buffer para IPC_STAT, IPC_SET */
	 unsigned short int *array; /* array para GETALL, SETALL */
	 struct seminfo *__buf; /* buffer para IPC_INFO */
	} semctl_arg;

		val_sem= semctl(semid, pos, GETVAL, semctl_arg);
		if (val_sem <0) {
			fflush(stdout);
			exit(0);
		}else{
			return (val_sem);
		}
	}

Lector.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <unistd.h>

void op_wait(int semid, int pos);
void op_signal(int semid, int pos);
int valor_sem (int semid, int pos);


union semun {
	 int val; /* valor para SETVAL */
	 struct semid_ds *buf; /* buffer para IPC_STAT, IPC_SET */
	 unsigned short int *array; /* array para GETALL, SETALL */
	 struct seminfo *__buf; /* buffer para IPC_INFO */
	} semctl_arg;

int main (int argc, char *argv[]) {
	int clave, num_lector, tiempo, semid;
	
	
	if (argc != 4) {
		printf("Error en el lector");
		exit(0);
		
	}else{
		
	/* mutex=0
	 * lectores=1
	 */	
	 	
	num_lector =atoi(argv[1]);
	clave =atoi(argv[2]);
	tiempo =atoi(argv[3]);
	int iteraciones = 5;
	int j= 0;
	
	semid = semget(clave, 2, 0); //accedo al semaforo
	
	 while (j < iteraciones) {
		 printf("LECTOR %d: INTENTO \n",num_lector);
		 fflush(stdout);
		 
		 op_wait(semid, 0); //wait(mutex)
		 op_wait(semid, 1); //wait(lectores)
		 op_signal(semid, 0); //signal(mutex)
		 
		printf("LECTOR %d: LEYENDO \n",num_lector); fflush(stdout);
		sleep(tiempo);
		op_signal(semid, 1); //signal(lectores)
		printf("LECTOR %d: FIN \n",num_lector);
		fflush(stdout);
		j++;
	}	
 }
}


int valor_sem (int semid, int pos){
		int val_sem; 
		
	 union semun {
	 int val; /* valor para SETVAL */
	 struct semid_ds *buf; /* buffer para IPC_STAT, IPC_SET */
	 unsigned short int *array; /* array para GETALL, SETALL */
	 struct seminfo *__buf;
/* buffer para IPC_INFO */
	} semctl_arg;

		//int posi;
		val_sem= semctl(semid, pos, GETVAL, semctl_arg);
		if (val_sem <0) {
			exit(0);
		}else{
			return (val_sem);
		}
	}
		
void op_wait(int semid, int pos){
		struct sembuf sop; //estructura menejo de operaciones sobre el semaforo	
			/*Inicializar valores*/
			sop.sem_num= pos;
			sop.sem_op= -1;
			sop.sem_flg= 0;
			/* Ejecución de una operación Down sobre sem_id: */
			semop(semid,&sop,1);
	}
	
void op_signal(int semid, int pos){
	struct sembuf sop; //estructura menejo de operaciones sobre el semaforo	
	/*Inicializar valores*/
	sop.sem_num= pos;
	sop.sem_op= 1;
	sop.sem_flg= 0;
	/* Ejecución de una operación Up sobre sem_id: */
	semop(semid,&sop,1);
}	
	

Escritor.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <unistd.h>

void op_wait(int semid, int pos);
void op_signal(int semid, int pos);
int valor_sem (int semid, int pos);

int main (int argc, char *argv[]) {
	int clave, num_escritor, tiempo, semid, i;
	
	
	if (argc != 4) {
		printf("Error en el escritor");
		exit(0);
		
	}else{
		
	num_escritor =atoi(argv[1]);
	clave =atoi(argv[2]);
	tiempo =atoi(argv[3]);
	int iteraciones = 5;
	int j=0;
	
	semid = semget(clave, 2, 0); //accedo al semaforo
	
	
	
	 while (j < iteraciones) {
		 printf("ESCRITOR %d: INTENTO\n",num_escritor);
		 fflush(stdout);
		 op_wait(semid, 0); //wait(mutex)
		 
		 for (i=1; i<=3; i++) {
			op_wait(semid, 1); //wait(lectores)
		}
		printf("ESCRITOR %d: ESCRIBIENDO\n",num_escritor); fflush(stdout);
		sleep(tiempo);		
		for (i=1; i<=3; i++) {
			op_signal(semid, 1); //signal(lectores)
		}
		
		op_signal(semid, 0); //signal(mutex)
		printf("ESCRITOR %d: FIN\n",num_escritor); fflush(stdout);
		j++;
		}
	}
}
		 
int valor_sem (int semid, int pos){
		int val_sem; 
		
	 union semun {
	 int val; /* valor para SETVAL */
	 struct semid_ds *buf; /* buffer para IPC_STAT, IPC_SET */
	 unsigned short int *array; /* array para GETALL, SETALL */
	 struct seminfo *__buf; /* buffer para IPC_INFO */
	} semctl_arg;

		val_sem= semctl(semid, pos, GETVAL, semctl_arg);
		if (val_sem <0) {
			fflush(stdout);
			exit(0);
		}else{
			return (val_sem);
		}
	}		
void op_wait(int semid, int pos){
		struct sembuf sop; //estructura menejo de operaciones sobre el semaforo	
			/*Inicializar valores*/
			sop.sem_num= pos;
			sop.sem_op= -1;
			sop.sem_flg= 0;
			/* Ejecución de una operación Down sobre sem_id: */
			semop(semid,&sop,1);
	}
	
void op_signal(int semid, int pos){
	struct sembuf sop; //estructura menejo de operaciones sobre el semaforo	
	/*Inicializar valores*/
	sop.sem_num= pos;
	sop.sem_op= 1;
	sop.sem_flg= 0;
	/* Ejecución de una operación Up sobre sem_id: */
	semop(semid,&sop,1);
}	
	

Lanzar_lect_escritor.sh
#!/bin/sh

gcc -O2 -o lec_esc_inicializar lec_esc_inicializar.c
gcc -O2 -o lector lector.c
gcc -O2 -o escritor escritor.c

# inicializo un semaforo con clave 578557 y componenetes
./lec_esc_inicializar 578557 2

./escritor 1 578557 2 & #num_lector, clave, tiempo
./escritor 2 578557 2 &
./escritor 3 578557 2 &
./lector 1 578557 2 &
./lector 2 578557 2 &
./lector 3 578557 2 &










PRODUCTOR CONSUMIDOR
Inicioprodcons.c
#include <sys/types.h>
#include <string.h>

#define MUTEX 0
#define HUECOS 1
#define OBJETOS 2
#define MAX_BUFFER 10
#define VALORINICIAL 5

union semun{
 int val;
 struct semid_ds *buf;
 ushort *array;
}arg;

int main(int argc, char *argv[]){

	//union semun arg;
	int semid, i , control;
	
	int key = atoi(argv[1]);
	int nsems = atoi(argv[2]);

	//semid = semget(key, nsems, IPC_CREAT|0600);
	
	if((semid = semget(key, nsems, MUTEX)) != -1) 	// Obtengo el manejador en modo uso (0)
		semctl(semid, MUTEX, IPC_RMID);		// Borro el anterior conjunto de semaforos

	if((semid = semget(key, nsems, IPC_CREAT|0600)) != -1){
		

		arg.val = 1;		//Inicializo MUTEX a 1
		semctl(semid,MUTEX,SETVAL,arg);
		arg.val = 5;		//Inicializo HUECOS a 5
		semctl(semid, HUECOS, SETVAL, arg);	
		arg.val= 5;			//Inicializo OBJETOS a 5
		semctl(semid,OBJETOS,SETVAL,arg);
	}
	
	control = semctl(semid,MUTEX,SETVAL,arg);
 printf("Control del semaforo mutex:%d\n", control);
	fflush(stdout);
	
	control = semctl(semid,HUECOS,GETVAL);
	printf("VALOR del semaforo huecos:%d\n", control);
	fflush(stdout);
	
	control = semctl(semid,OBJETOS,GETVAL);
	printf("VALOR del semaforo objetos:%d\n", control);
	fflush(stdout);

	printf("\nFIN Inicializacion\n");fflush(stdout);
	//exit(0);

}

Productor.c
#include <sys/types.h>

#define MUTEX 0
#define HUECOS 1
#define OBJETOS 2

#define KEY 123
#define MAX_BUFFER 10

union semun{
 int val;
 struct semid_ds *buf;
 ushort *array;
} arg;

void op_wait(int sem, int n);
void op_signal(int sem, int n);

int main(int argc, char *argv[]){

//	union semun arg;
 int semid;

	int nsems = 3;
	int numprod, key, delay;
	int huecos, objetos;

	key = atoi(argv[1]);
	numprod = atoi(argv[2]);
	delay = atoi(argv[3]);

 	semid = semget(key, nsems, MUTEX);

	if(semid == -1){
	 printf("\nHa ocurrido un error al acceder al semaforo.");fflush(stdout);	
	}
 
	printf("\nProductor %d manejador del semaforo:%d\n",numprod, semid);fflush(stdout);
	
	while (1){
	
		//printf("\n");fflush(stdout);
		sleep(delay);
		
		if (semctl(semid,HUECOS,GETVAL,arg)>0) {
		
			op_wait(semid, HUECOS);		//wait(huecos)
			huecos = semctl(semid,HUECOS,GETVAL,arg);		//Se obtienen los huecos
	
			op_wait(semid, MUTEX);		//wait(mutex)
			op_signal(semid, MUTEX);	//signal(mutex)
 
			op_signal(semid, OBJETOS);	//signal(objetos)
			objetos = semctl(semid,OBJETOS,GETVAL,arg);		//Se obtiene los objetos

			printf("\nProductor %d añade un objeto, Objetos:%d, Huecos:%d\n",numprod, objetos,huecos);
			fflush(stdout);
		}else {
			printf("Productor %d, NO HAY HUECOS, NO PUEDO PRODUCIR\n",numprod);
			fflush(stdout);
		}
	}
}

void op_wait(int sem, int n){
 struct sembuf sop;

 sop.sem_num = n;
 sop.sem_op = -1;
 sop.sem_flg = 0;
 semop(sem, &sop,1);
}

void op_signal(int sem, int n){
 struct sembuf sop;

 sop.sem_num = n;
 sop.sem_op = 1;
 sop.sem_flg = 0;
 semop(sem, &sop,1);
}

Consumidor.c
#include <sys/types.h>
#include <stdio.h>

#define MUTEX 0
#define HUECOS 1
#define OBJETOS 2

#define MAX_BUFFER 10


union semun {
	int val; // Value for SETVAL
	struct semid_ds *buf; // Buffer for IPC_STAT, IPC_SET
	unsigned short *array; // Array for GETALL, SETALL
	struct seminfo *__buf; // Buffer for IPC_INFO (Linux-specific)
}arg;


void op_signal(int sem, int n);
void op_wait(int sem, int n);

int main(int argc, char *argv[]){

//	union semun arg;

	int semid;
	int nsems = 3;
	int numcons, key, delay;
	
	int objetos, huecos;

	key = atoi(argv[1]);
	numcons = atoi(argv[2]);
	delay = atoi(argv[3]);

	semid = semget(key, nsems, MUTEX);

	if(semid == -1){
		printf("\nHa ocurrido un error al acceder al semaforo.");
		fflush(stdout);	
	}
 
	printf("Consumidor %d manejador del semaforo:%d\n", numcons, semid);fflush(stdout);

	
	while (1){

		sleep(delay);
		
		if (semctl(semid,OBJETOS,GETVAL,arg)>0) {
			
		
		op_wait(semid, OBJETOS); 
		objetos = semctl(semid,OBJETOS,GETVAL,arg);		//Obtiene el valor del semaforo 2

		op_wait(semid, MUTEX);
			
		op_signal(semid, MUTEX);	//signal(mutex)
		op_signal(semid, HUECOS);	//signal(huecos)
		huecos = semctl(semid,HUECOS,GETVAL,arg);		//Obtiene el valor del semaforo 1
			printf("Consumidor %d, quita un objeto. Objetos:%d, Huecos:%d\n",numcons, objetos, huecos);
			fflush(stdout);
		}else {
			printf("Consumidor %d, NO HAY OBJETOS, NO PUEDO CONSUMIR\n",numcons);
			fflush(stdout);
		}
	}
}

void op_signal(int sem, int n){
 struct sembuf sop;
 sop.sem_num = n;
 sop.sem_op = 1;
 sop.sem_flg = 0;
 semop(sem, &sop,1);
}

void op_wait(int sem, int n){
 struct sembuf sop;
 sop.sem_num = n;
 sop.sem_op = -1;
 sop.sem_flg = 0;
 semop(sem, &sop,1);
}

Prodcons.sh
#!/bin/bash
./inicioprodcons 123 3 ##inicioprodcons KEY NumeroSems
./productor 123 1 2 & ##productor

Otros materiales