• No se han encontrado resultados

Sistemas Operativos. Tema 2

N/A
N/A
Protected

Academic year: 2021

Share "Sistemas Operativos. Tema 2"

Copied!
19
0
0

Texto completo

(1)

Sistemas Operativos

Tema 2

Interfaces del sistema Operativo. Llamadas al sistema

Para gestión de procesos

Relacionadas con señales

Para gestión de ficheros

Para gestión de directorios

Para protección

(2)

Punto 6. Llamadas al sistema (SYSTEM CALLS)

Acceso al SOP a través de una interrupción software.

ejemplo:

open() es una unción de librería de C que genera una interrupción soft. read() en realidad no 'toca' para nada el disco. Consiste en

read ( . . . ) {

paso de parámetros trap

devolución de parámetros }

Las funciones del SOP trabajan sobre las dos abstracciones: proceso y fichero Proceso:

- Manejo de procesos y memoria - Señales Fichero: - Manipulación de ficheros - Directorios - Protección de ficheros Tiempo

(3)

Llamadas al sistema para gestión de procesos: fork, wait, exec, exit, brk, getpid

pid = fork ()

pid del proceso hijo o 0 crea un proceso con copia de la imagen en memoria del padre Genera un proceso hijo que hereda del padre el core image:

1. UID y GID reales y efectivos

2. Descriptores de ficheros. Todos los ficheros que tiene abiertos el padre también los tiene el hijo.

3. Gestión de señales. Igualmente a los descriptores 4. Directorio de trabajo

5. Máscara de protección 6. Contador de programa Diferencias entre hijo y padre:

1. PID. Es un proceso diferente 2. PPID. Tiene un padre distinto

3. Se anulan posibles alarmas pendientes

Importante: Las variables son copias, no son compartidas.

fork devuelve en pid: 0 en el proceso hijo.

-1 caso de no haberse podido crear al hijo. Identificador del hijo en el proceso padre

ejemplo:

while (TRUE) { // bucle infinito

leer_comando(comando,parametros); // lee del

terminal

if (fork() != 0) { // crea proceso hijo

wait(&status); // código que sigue ejecutando el padre }

else {

execve(comando,parametros,0) // código que sigue ejecutando el hijo }

(4)

pid = wait ( &status );

pid del hijo que ejecuta exit

exit ( status );

El proceso padre la ejecuta el proceso hijo cuando finaliza su ejecución

estado de finalización estado del hijo

16 bits

estado de finalización espera al hijo

Valor de status:

-1 => El padre no tiene ningún hijo 0 => El hijo ha terminado normalmente

(5)

Posibilidades:

1º.- Padre ejecuta wait y después el hijo ejecuta exit.

Padre => espera a que termine el hijo antes de continuar.

Hijo => ejecuta exit.

Padre => mata a su hijo.

2º.- Hijo ejecuta exit y después el padre ejecuta wait

Hijo => finaliza la ejecución pero no es destruido.

En este estado al hijo se le denomina ZOMBIE Padre => ejecuta wait y destruye al hijo.

Padre

Hijo_1 Hijo_2 Hijo_3

Padre

Hijo_1

Hijo_N

Figura (a) Figura (b)

En fig a si el padre ejecuta wait, no se puede saber a qué hijo está esperando, de forma que esperará a que termine alguno

En fig b si el padre ejecuta wait y el Hijo_1 ejecuta exit, el proceso Hijo_N se queda huérfano, con lo que su padre pasaría a ser el proceso INIT.

Es importante que un nodo tenga padre, de otra manera, no será destruido. INIT deberá efectuar un bucle infinito con la sentencia wait, para que todos los hijos que tenga y adopte, pueda destruirlos, cuando finalicen su ejecución. Existe, en este punto, una diferencia importante entre UNIX y MINIX:

- En fig b, si Hijo_1 ejecuta exit, automáticamente se queda ZOMBIE. - En MINIX, INIT no adopta a Hijo_N hasta que Hijo_1 no es destruido - En UNIX, INIT adopta a Hijo_N cuando Hijo_1 se queda ZOMBIE.

(6)
(7)

s = execve ( nombre, argv, envp );

-1 caso de error

cambia la imagen del proceso que la invoca

fichero a ejecutar

puntero a vector de variables de entorno puntero a vector de

argumentos

Todos los atributos permanecen salvo dos:

- Tratamiento de la señales capturadas, es decir, si se había ejecutado signal(sig,f) para asociar la ejecución de la función f a la señal sig, ahora tomará la función por defecto SIB_DFL.

- Si el fichero ejecutable tiene un bit SETUID activo, el UID efectivo del proceso se asigna al owner UID del fichero.

tam = brk ( dirección )

establece nueva dirección de terminación del segmento de datos

dirección final del segmento de datos tamaño del segmento

de datos

pid = getpid ( )

proporciona el identificador de un proceso

(8)

Llamadas al sistema relacionadas con señales: signal, kill, alarm, pause

- Si un proceso recibe una señal que no estaba esperando, se mata al proceso - Cuando la señal es esperada, se trata en segundo nivel de interrupción

- Después de recibir una señal hay que reactivar la captura para que siga siendo efectiva

funcant = signal ( señal, func )

habilita al proceso para el tratamiento de señales

señal anterior tratamiento

(SIG_DFL, SIG_IGN, . . . ) nombre de la señal

a capturar

s = kill ( pid, señal )

envía una señal a un proceso

(SIGKILL no puede capturarse ni ignorarse)

señal enviada pid destinatario

-1 caso de error

residual = alarm ( segundos )

tiempo restante envía SIGALRM

(cancela anterior)

s = pause ()

suspende al ejecutor

hasta la siguiente señal

(9)

Llamadas al sistema para gestión de ficheros: creat, mknod, open, close, read, write, lseek, stat, fstat, dup, pipe, ioctl

fd = creat ( nombre, modo )

crea un fichero y lo deja abierto para escritura

descriptor fichero creado código octal de permisos

fd = mknod ( nombre, modo, direccion )

crea un fichero especial o un directorio (sólo superusuario)

descriptor fichero especial creado

0111111 tipo (car. ó bloq.)

permisos

0x1111

número secundario número principal

fd = open ( nombre, acceso )

abre un fichero

descriptor fichero a abrir

( 0 lectura ) ( 1 escritura ) ( 2 lect./escrit. ) s = close ( fd ) cierra un fichero descriptor de fichero

(10)

n = read ( fd, buffer, nbytes )

lee de un fichero

cantidad leida

descriptor de fichero

buffer destino cantidad a leer

n = write ( fd, buffer, nbytes )

escribe en un fichero

cantidad escrita

descriptor de fichero

buffer origen

cantidad a escribir

pos = lseek ( fd, posición, referencia )

posición absoluta

descriptor de fichero

posición relativa a

base para posicionar posicionamiento del puntero de un fichero

la referencia

(principio, final, actual) en el fichero

(11)

s = stat ( nombre, &buffer )

obtiene el estado de un fichero

s = fstat ( fd, &buffer )

descriptor del fichero

Puntero a destino

El contenido de buffer es: struct stat {

short st_dev; // dispositivo dende reside el nodo-i unsigned short st_ino; // número del nodo-i

unsigned short st_mode; // códigos de protección (modo) short st_nlink; // número de enlaces

short st_uid; // identificador del propietario short st_gid; // identificador del grupo

short st_rdev; // número ppal/sec en ficheros especiales long st_size; // tamaño del fichero

long st_atime; // idéntico a st_mtime

long st_mtime; // instante de la última modificación long st_ctime; // idéntico a st_mtime

};

Estructura de datos utilizada por STAT y FSTAT para devolver información. Existen tres campos relacionados con tiempo por razones de compatibilidad con UNIX.

(12)

fd = dup ( fd1 )

duplica el descriptor de un fichero

nuevo descriptor del

mismo fichero descriptor originaldel fichero Redireccionar_salida (s) char *s; { int fd; fd = creat (s,0666); close (STD_OUTPUT); dup (fd); close (fd); } Redireccionar_entrada (e) char *e; { int fd;

fd = open (e, RD_ONLY); close (STD_INPUT); dup (fd);

close (fd); }

(13)

s = pipe ( &fd[0] )

fd[0] descriptor para lectura crea un pipe

fd[1] descriptor para escritura

Ejemplo: Esqueleto de programa para disponer dos procesos en cadena. # define STD_INPUT 0 // descriptor de fichero entrada estandar # define STD_OUTPUT 1 // descriptor de fichero salida estandar cadena(proceso1, proceso2)

char *proceso1, *proceso2; // punteros a nombres de programa {

int fd[2]; pipe(&fd[0]); if (fork() != 0) {

close(fd[0]); // el proceso 1 no ha de leer del tubo close(STD_OUTPUT); // preparación de la nueva salida estandar dup(fd[1]); // salida estandar vinculada a fd[1]

close(fd[1]); // ya no se necesita más el tubo execl(proceso1,proceso2,0);

} else {

close(fd[1]); // el proceso 2 no escribe en el tubo

close(STD_INPUT); // preparación de la nueva entrada estandar dup(fd[0]); // entrada estandar vinculada a fd[0]

close(fd[0]); // ya no se necesita más el tubo execl(proceso2, proceso2,0)

} }

(14)

s = iotcl ( fd, petición, &argp )

operaciones particulares en ficheros especiales

descriptor de fichero especial

función a realizar

puntero a registro de bits de estado

(15)

Llamadas al sistema para gestión de directorios: link, unlink, mount, umount, sync, chdir, chroot

s = link ( nombre, enlace )

asocia un nodo-i existente a un nuevo nombre

nombre del fichero nombre del enlace

16 81 40 correo juegos prueba /usr/ast 31 70 59 bin memo f.c /usr/jim 38 prog1 16 81 40 correo juegos prueba /usr/ast 31 70 59 bin memo f.c /usr/jim 38 prog1 70 nota

(a) Dos directorios antes de enlazar /usr/jim/memo al directorio de ast. (b) Los mismos directorios después del enlace

(a) (b)

s = unlink ( nombre )

anula la asociación de nombre con el nodo-i

nombre del fichero que se borra

s = mount ( especial, nombre, rwindic )

monta un sistema de ficheros en otro

nombre de fichero especial de bloques

(16)

s = unmount ( especial )

desmonta un sistema de ficheros

nombre de fichero especial de bloques

s = sync ()

copia modificaciones de caché a disco (ejecutada por 'update')

s = chdir ( nombre )

cambia el directorio de trabajo

nuevo directorio de trabajo

s = chroot ( nombre )

cambia el directorio raiz

nuevo directorio raiz (sólo superusuario)

(17)

Llamadas al sistema para protección: chmod, getuid, getgid, setuid, setgid, chown, umask, access

s = chmod ( nombre, modo )

cambia la protección de un fichero

fichero 0 1 1 1

usuario grupo otros

s = getuid ()

obtiene el usuario efectivo

s = getgid ()

obtiene el grupo efectivo

s = setuid ( uid )

asigna valor al uid del proceso llamador (sólo superusuario)

nuevo valor del uid

s = setuid ( uid )

asigna valor al gid del proceso llamador (sólo superusuario)

nuevo valor del gid

s = chown ( nombre, propietario, grupo )

cambia el usuario y grupo de un fichero

fichero nuevo propietario nuevo grupo

anterior = umask ( máscara )

inhibe permiso (los hijos heredan la máscara)

(18)

s = access ( nombre, modo )

comprueba si uid real tiene permiso

fichero 0 1 4 lectura 2 escritura 1 ejecución 0 comprueba accesibilidad

(19)

Llamadas al sistema para gestión de tiempo: time, stime, utime, times

segundos = time ( &segundos )

obtiene el tiempo desde 1.1.1970 en seg.

s = stime ( tp )

ajusta la hora. (sólo superusuario)

s = utime ( fichero, instante )

actualiza el valor de st_mtime en el nodo_i de un fichero

s = times ( buffer )

tiempo de procesador consumido por un proceso y por el sistema en su nombre y el total acumulado de los hijos

Referencias

Documento similar