Sie sind auf Seite 1von 68

Programacin de Sistemas

INDICE
Tema 1 : Biblioteca Estndar

Pag 2

Tema 2 : Herramientas de ayuda al desarrollo en el entorno Unix

Pag 5

Tema 3 : Estructura interna de Unix. Introduccin

Pag 8

Tema 4 : Sistemas de Archivos en SVR4

Pag 14

Tema 5 : Primitivas del Kernel

Pag 28

Tema 6 : Procesos

Pag 38

Tema 7 : Seales

Pag 46

Tema 8 : Prioridades en Unix SVR4

Pag 52

Tema 9 : Mecanismos IPCS

Pag 59

Alberto Navarro Ezquerro Pag

Programacin de Sistemas

TEMA 1 : BIBLIOTECA ESTNDAR


stdio.h
Contiene definiciones de macros, prototipos de funciones y declaraciones de variables que
reconocen el entorno.
Definiciones de tipos :
typedef unsigned int
typedef long
typedef long
typedef long

size_t
fpos_t
wchar_t
wint_t

Definiciones de macros :
#define NULL 0
#define EOF -1
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define stdin (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])

Para punteros
Devuelto al leer ms all del final del archivo
Principio de archivo
Posicin actual
Fin de archivo
Entrada estndar
Salida estndar
Salida de errores estndar

Definicin del tipo FILE :


typedef struct _FILE
{ int _cnt ;
Nmero de caracteres disponibles en el buffer
unsigned char *_ptr ;
Puntero al carcter siguiente
unsigned char *_base ;
Puntero al buffer que contiene la info. del archivo
unsigned char _flag ;
Flag de acceso (modo de acceso)
unsigned char _file ;
Descriptor del archivo
unsigned char _buf[2] ;
}FILE ;
Prototipos de funciones para archivos de texto :
int *fclose (FILE *fd)
fd : Descriptor de archivo
int fflush (FILE *fd)
Vacia el contenido de una secuencia de salida. Esta funcin escribe todos
los datos almacenados en el buffer sobre el archivo asociado con fd. Si se
llama a fflush con un puntero nulo se vacan los buffers de todos los
archivos abiertos.
La funcin fflush devuelve 0 si tiene xito ; en otro caso devuelve EOF.

Alberto Navarro Ezquerro Pag

Programacin de Sistemas

FILE *fopen (const char *Nombre, const char *Modo)


Modo
r
w
a
rb
wb
ab
r+
w+
a+
r+b
w+b
a+b

Significado
Abre un archivo de texto para lectura
Crea un archivo de texto para escritura
Abre un archivo de texto para aadir
Abre un archivo binario para lectura
Crea un archivo binario para escritura
Abre un archivo binario para aadir
Abre un archivo de texto para lect/escr
Crea un archivo de texto para lect/escr
Aade o crea un archivo de texto para lect/escr
Abre un archivo binario para lect/escr
Crea un archivo binario para lect/escr
Aadir en un archivo binario en modo lect/escr

Esta funcin devuelve un puntero a un archivo. En caso de error al intentar


abrir el archivo devuelve un puntero nulo.
size_t fread (void *buffer, size_t bytes, size_t num, FILE *fd)
Buffer : Es un puntero a una regin de memoria (contenedor).
Bytes : Nmero de bytes a leer.
Num : Es el nmero de elementos a leer (con bytes de longitud)
Fd
: Es un descriptor de archivo.
La funcin fread devuelve el nmero de elementos ledos. Este valor
puede ser menor que cuenta si se encuentra el final del archivo o si se
produce un error.
size_t fwrite (void *buffer, size_t bytes, size_t num, FILE *fd)
Buffer : Es un puntero a una regin de memoria (contenedor).
Bytes : Nmero de bytes a escribir.
Num : Es el nmero de elementos a escribir (con bytes de longitud)
Fd
: Es un descriptor de archivo.
La funcin fwrite devuelve el nmero de elementos escritos. Este valor
ser igual a cuenta a menos que se produzca un error.
Prototipos de funciones de tratamientos de error :
int feof (FILE *fd)
Devuelve cierto si se alcanzado el final del archivo ; en otro caso,
devuelve 0 (para archivos binarios).
int ferror (FILE *fd)
Determina si se ha producido un error en una operacin sobre un archivo.
Devuelve cierto si se ha producido un error durante la ltima operacin
sobre el archivo, sino devuelve falso.
void clearerr (FILE *fd)
Se utiliza para inicializar a 0 el indicador de error del archivo.
Alberto Navarro Ezquerro Pag

Programacin de Sistemas

Prototipos de funciones de acceso directo :


int fseek (FILE *fd, long numbytes, int origen)
Situa el indicador de posicin del archivo.
Numbytes
: Nmero de bytes a partir de origen que se mover fd.
Origen
: Es una de las siguientes macros (SEEK_SET,SEEK_CUR,
SEEK_END) ;
Devuelve 0 si ha tenido xito y un valor distinto de 0 cuendo hay un error.
void rewind (FILE *fd)
Inicializa el indicador de posicin, al principio del archivo.
long ftell (FILE *fd)
Devuelve el valor actual del indicador de porsicin del archivo. Retorna
-1L cuando se produce un error
(Adems tenemos stdlib.h y string.h)

Alberto Navarro Ezquerro Pag

Programacin de Sistemas

TEMA 2 : HERRAMIENTAS DE AYUDA AL DESARROLLO


EN EL ENTRONO UNIX
Compilador cc
Es un guin shell que traduce el cdigo fuente a cdigo objeto y crea un ejecutable.
Adems enlaza sus mdulos.
Prog.c

1 Fase

Prog.i

2 Fase

Prog.s

Prog.o

3 Fase

Fases al ejecutar : $ cc

4 Fase

Ejecutable
Podemos indicar que se detenga en una fase concreta :
-P : Que se detenga en la primera fase (c sin macros)
-s : Que se detenga en segunda fase (ensamblador)
-c : Que se detenga en la tercera fase
Sin nada llega al ejecutable, que por omisin se llama a.out.
-o nombre : Para darle un nombre al ejecutable.
Las aplicaciones se pueden dividir en mdulos que son ficheros fuente con funciones de
control de flujo de la aplicacin.
$ cc m1.c m2.c .........mk.c -o ejec
Ms opciones :
$ cc -D macro $ cc -D macro = valor
-Aa : Compila en ansi. En caso contrario lo hace en pre ansi.

Alberto Navarro Ezquerro Pag

Programacin de Sistemas

Constructor make
Genero procesos de compilacin de proyectos en c bajo el paradigma de la
descomposicin funcional.
Fichero make :
ejec : s1.o s2.o
cc -o ejec s1.o s2.o
s1.o : s1.c define.h
cc -c s1.c
s2.o : s2.c define.h
cc -c s2.c
A este fichero se le puede dar cualquier nombre. Si se le llama pepe la ejecucin ser
$ make pepe y si se le llama makefile ser $ make.
Bibliotecas de enlace esttico ee y de enlace dinmico ed
Las libreras compartidas permiten que mltiples programas puedan compartir el cdigo de
las funciones incluidas en la librera. Este modo de compartir puede estar implementada de forma
esttica (ed) o dinmica (ee).
En una librera esttica las direcciones virtuales de las funciones son fijas y se enlazan
con el fichero a.out cuando se realiza el linkado, de manera que estas direcciones no se
modifican aunque las funciones sean modificadas. Cuando se realizan cambios en las funciones de
la librera es necesario conocer el espacio de direcciones disponible.
Las libreras dinmicas no residen en direcciones fijas de memoria y las funciones se
enlazan con el fichero a.out en tiempo de ejecucin. Las funciones se pueden cargar en
cualquier direccin de memoria.
Para crear libreras estticas se crean con el comando ar y tienen el nombre genrico
libxxx.a :
$ cc -c func1.c func2.c func3.c
$ ar -r libmia.a func1.o func2.o func3.o
La librera se podr enlazar con el ejecutable de la siguiente manera :
$ cc -ldirectorio main.c fich2.c -lmia
Las libreras dinmicas tienen el nombre genrico libxxx.so :
$ cc -c func1.c func2.c func3.c
$ cc -G libmia.so func1.o func2.o func3.o

Alberto Navarro Ezquerro Pag

Programacin de Sistemas

El editor de enlace incluir en el ejecutable con el que se enlace la librera el nombre del
objeto compartido asi como toda la informacin necesaria para gestionar el enlace en tiempo de
ejecucin.
$ cc -ldirectorio main.c fich2.c -lmia
Es posible incluir libreras estticas y otras libreras dinmicas en la lista de ficheros
especificados para formar la librera dinmica :
$ cc -G libmia.so -ldirectorio func1.0 func2.o func3.o -lcomp
La opcin dn permite desactivar el enlace con libreras dinmicas. La orden cc
proporciona otras dos opciones que permiten combinar enlaces con libreras dinmicas y
estticas :
$ cc -L/home/mlibs/ main.c fich1.c fich2.c -Bstatic lmia fich3.c Bdynamic -lcomp
En la lnea anterior se enlaza la librera esttica libmia.a para resolver las referencias
externas de main.c y fich1.c y fich2.c ; por otro lado se indica que emplee la librera libcomp.so
para resolver las referencias externas no resueltas de esos mismos programas y por ltimo que
emplee la librera estndar libc.so para resolver las referencias externas an no resueltas.
Opciones :
r
d
t
x
dn

: Crea la biblioteca y guarda dentro los archivos especificados. Si ya existe


amplia y reemplaza.
: Elimina los archivos de la biblioteca.
: Lista el contenido del archivo especificado
: Exporta al sistema de archivos ese miembro de la biblioteca.
: Significa no dinmico. Busca bibliotecas de enlace esttico.

Alberto Navarro Ezquerro Pag

Programacin de Sistemas

TEMA 3 : ESTRUCTURA INTERNA DE UNIX


Introduccin

Aplicaciones

K
Subsistema
de
E/S

Subsistema

E
R

de

N
Subsistema
de
Ficheros

Procesos

E
L

Mquina
El nucleo (kernel) de Unix es un programa que siempre est residente en memoria y que,
entre otros, ofrece los siguientes servicios :

Controla los recursos del hardware


Controla los dispositivos perifricos (discos, terminales, impresoras..)
Permite a usuarios distintos compartir recursos y ejecutar sus programas.
Proporciona un sistema de archivos que administra el almacenamiento de informacin.

En la arquitectura Unix podemos distinguir tres niveles bsicos, que son el hardware (la
mquina), el kernel y en un tercer nivel los programas estndar (vi, grep....) y programas
generados por el usuario (a.out).
Estos programas del tercer nivel nunca se comunican de forma directa con el hardware,
por lo que debe existir algn mecanismo que nos permita indicar al kernel que necesitamos operar
sobre algn recurso hardware. Este mecanismo son las llamadas al sistemas (system calls).

Alberto Navarro Ezquerro Pag

Programacin de Sistemas

Las llamadas al sistema y su librera asociada representan la frontera entre los programas
de usuario y el kernel. La librera asociada es el mecanismo que nos permite invocarlas desde un
programa C. Los programas escritos en ensamblador pueden invocarlas directamente sin
necesidad de ninguna librera intermedia.
Las llamadas al sistema se ejecutan en modo kernel y para entrar en ese modo hay que
ejecutar una sentencia en cdigo mquina conocida como trap (o interrupcin software).
La forma de averiguar si una llamada ha fallado es analizar el valor que devuelve. Este
valor es -1 de forma estndar para todas las llamadas cuando se produce un error. Para determinar
el error producido hay que consultar la variable externa errno (en el fichero errno.h hay una
descripcin de los posibles valores que puede tomar esta variable).
Existen dos formas de obtener el mensaje de error asociado a la variable errno que se
exponen a continuacin.
Usar errno como ndice para acceder a la cadena correspondiente de sys_errlist[].
Usar la funcin de librera perror().
Funciones de cada subsistema
Subsistema de procesos

Administracin de la memoria
Planificacin de procesos
Comunicacin entre procesos
Gestionar la creacin y eliminacin de procesos

Sussistema de E/S

Gestionar el acceso a dispositivos en mdo bloque o modo carcter


Implementar los streams
Implementar los drivers virtuales (ej : /dev/null)
Gestionar el tratamiento de los dispositivos fsicos como si fuesen ficheros

Subsistema de ficheros
Mantener en disco las estructuras de de los sistemas de ficheros
Mantener en memoria las estructuras de datos que agilicen el uso y la
compatibilidad de los sistemas de ficheros
Gestionar las llamadas al sistema sobre ficheros

Alberto Navarro Ezquerro Pag

Programacin de Sistemas

Tipos de ficheros en Unix


Ficheros Ordinarios
Contienen ristras de bytes organizados como un array lineal. No tienen una estructura
predefinida y no es necesario hacer una reserva especial de espacio puesto crecen y disminuyen
dinmicamente.
Las operaciones que se pueden hacer con los datos de un fichero son las que se exponen a
continuacin :
Leer o escribir cualquier byte del fichero
Aadir bytes al final del fichero
Truncar el tamao a 0 bytes (borrar el contenido)
Las siguientes operaciones no estn permitidas :
Insertar bytes en un fichero, excepto al final.
Borrar bytes de un fichero (decrementar el tamao)
Truncar el tamao de un fichero a un valor distinto de 0
Un fichero puede ser leido y escrito concurrentemente por dos o ms procesos. Los
resultados de esta operacin dependen del orden de las llamadas de e/s individuales de cada
proceso y de la planificacin que el scheduler haga de los procesos, por lo que, en generalson
impredecibles.
Los ficheros ordinarios, como tales, no tienen nombre y el acceso a ellos se realiza a travs
de los i_nodes.
Directorios
Permiten darle una estructura jerrquica a los sistemas de ficheros Unix. La funcin
fundamental es establecer la relacin que existe entre el nombre de un fichero y su inode
correspondiente.
Estructura de un directorio en Unix System V
En esta versin, un directorio es un fichero cuyos datos son una serie de
entradas,cada una de las cuales contiene un par <n inode / nombre>. Cada uno de estos
pares es un enlace y puede haber varios nombres de ficheros que tengan el mismo nmero
de inode.

Alberto Navarro Ezquerro Pag

10

Programacin de Sistemas

El tamao de cada entrada es de 16 bytes : 2 bytes para el nmero de inodo y 14


para :
offset
0
16
32
64
.
.

inode
45
2
2359
4921
.
.

nombre fichero
.
..
ls
mount
.
.

Las dos primeras entradas (las que hacen referencia al directorio actual . Y al
directorio padre .. estn presentes en todo directorio. En el caso del directorio raz es el
programa mkfs (make file system) el que se encarga de que la entrada .. apunte al propio
directorio raz.
El kernel maneja los datos de un directorio con los mismos procedimientos con
que se manejan los datos de los ficheros ordinarios, usando la estructura inode y los
bloques de acceso directos e indirectos.
No hay razones estructurales que impidan la existencia de mltiples enlaces a un
directorio, sin embargo el kernel los prohibe.
Los permisos de acceso de un directorio tienen los siguientes significados :
Permiso de lectura : Un proceso puede leer ese directorio (ls)
Permiso de ejecucin : Un proceso puede buscar un nombre de fichero
Permiso de escritura
: Permite crear una entrada o borrar una existente
Estructura de un directorio en el sistema 4.3BSD
La diferencia bsica estriba en que los nombre de ficheros en este sistema pueden
tener una longitud mayor de 14 bytes y no se reserva un espacio fijo de bytes para cada
entrada del directorio.
Cada bloque de directorio se compone de tres campos : nmero de inodo, un
puntero al nombre de la entrada y la longitud del nombre.
Los procesos pueden leer el contenido de un directorio pero no pueden
modificarlo, esto es un privilegio del kernel.

Ficheros especiales o de dispositivo

Alberto Navarro Ezquerro Pag

11

Programacin de Sistemas

Este tipo de ficheros permiten comunicarse con los dispositivos perifricos (discos, cintas,
impresoras, terminales. Redes...). Hay dos clases de ficheros especiales :
Modo Bloque
El dispositivo contiene un array de bloques de tamao fijo (generalmente mltiplo
de 512 bytes) y el kernel gestiona un buffer cache que acelera la transferencia de
los datos. El bloque es la unidad mnima de informacin que se transfiere en cada
operacin de E/S.
Modo Carcter
La informacin no se organiza segn una estructura concreta y el vista por el
kernel, o por el usuario, como una secuencia lineal de bytes. Se pueden realizar las
operaciones de E/S en montones pequeos (por ejemplo carcter) o grandes (por
ejemplo pista). No existe un buffer y por tanto las transferencias van a ser a menor
velocidad.
Un mismo dispositivo puede ser accedido en cualquiera de los dos modos (esto es lo
habitual en el caso de los discos).
Los mdulos del kernel que gestionan la comunicacin con los dispositivos se llaman
drivers de dispositivos. Lo normal es cada dispositivo tenga su propio driver, pero puede haber
drivers que controlen toda una familia de dispositivos con caractersticas comunes (por ejemplo
los terminales).
En el caso de los ficheros de dispositivos, el inode contiene dos nmeros :
Major number : Indica el tipo dispositivo (disco, cinta...)
Minor number : Indica el nmero de unidad dentro del dispositivo.
Estos nmeros los utiliza el kernel para buscar dentro de unas tablas (block device switch
table y character device switch table) una coleccin de rutinas que permiten manejar el
dispositivo. Estas rutinas son las que constituyen realmente el driver del dispositivo.
Fifo
Es un fichero con una estructura muy similar a un fichero ordinario. La diferencia est en
que los datos de un fifo son transitorios. Una vez que un dato es ledo de un fifo, desaparece de l
y nunca ms podr ser ledo.
Se pueden emplear para comunicar procesos. Los datos de un fifo se leen en el mismo
orden en que fueron escritos (first in - first out). La sincronizacin en el acceso a un fifo es tarea
del kernel.
El almacenamiento de datos en el fifo se realiza de la misma manera que en un fichero
ordinario, solo que el kernel unicamente emplea las entradas directas de la tabla de direcciones de
bloque del inode del fifo. Por lo tanto un fifo podr almacenar 10 kbytes como mucho
(suponiendo bloques de 1024 bytes).
Alberto Navarro Ezquerro Pag

12

Programacin de Sistemas

Los accesos de lectura/escritura se realizan con las mismas llamadas que en los ficheros
ordinarios (open(), close(), read()....), siendo los accesos de tipo atmico con lo que se garantiza
el sincronismo en el caso de que varios procesos accedan concurrentemente al mismo fifo.
Los fifo tambien se denominan tuberas con nombre ya que se comportan como pipes,
tiene asociado un nombre y ocupan una entrada en el directorio y un inode. Mientras que las
tuberas sin nombre slo existen mientras algn proceso est asociado a ellas, no tienen nombre
aunque si ocupan un inode mientras existen.
Las tuberas sin nombre se crean a travs de la llamada pipe() mientras que los fifo se
crean con la orden mknod (desde la lnea de rdenes) o con la llamada mknod() (desde un
proceso).
Permisos en Unix
El uid real determina al propietario de los archivos que manipula. EL uid efectivo
determina al usuario del fichero.
Si el uid efectivo es 0 el permiso se concede automticamente.
Si el uid efectivo del proceso que intenta hacer uso de un archivo y el uid real del
archivo coinciden se le aplican los permisos del propietario.
Si el uid efectivo de grupo coincide con el uid real de grupo coinciden se le aplican
los permisos de grupo.
Si no coinciden ninguno se le aplican los permisos de otros.

Alberto Navarro Ezquerro Pag

13

Programacin de Sistemas

TEMA 4 : SISTEMAS DE ARCHIVOS EN SVR4

Introduccin
Se denomina sistema de ficheros a la organizacin establecida en disco para el
almacenamiento de los datos, de forma que todos los ficheros de un disco o particin constituyen
un sistema de ficheros. Pero los sistemas de ficheros en Unix presentan una serie de
caractersticas :

Estructura jerquica
No se impone formato a los ficheros
Existencia de los derechos de accesos sobre los ficheros
Tratamiento de los dispositivos perifricos como ficheros
Asignacin dinmica de espacio en disco para los ficheros

Un sistema Unix puede manejar uno o varios discos fsicos, cada uno de los cuales puede
contener uno o varios sistemas de ficheros. Los sistemas de ficheros son particiones lgicas del
disco.
El kernel trata con el sistema de ficheros a un nivel lgico y no trata directamente con los
discos a nivel fsico. Cada disco es considerado como un dispositivo lgico que tiene asociados
unos nmeros, el major number y el minor number, los cuales son empleados para indexar dentro
de una tabla de funciones cual tenemos que emplear para manejar el driver del disco. El driver del
disco es el que transforma direcciones lgicas del sistema de ficheros a direcciones fsicas del
disco.
En SVR4 existen distintos tipos de ficheros :

S5
ufs
nfs
/proc
bfs
fifofs
specfs

Cada uno de estos sistemas contiene un sistema de ficheros de arranque (bfs). Existen
instrucciones para montar cualquiera de estos tipos de sistemas de ficheros excepto los fifofs y los
specfs que no se pueden montar.

Alberto Navarro Ezquerro Pag

14

Programacin de Sistemas

Sistema de ficheros S5
En este sistema de ficheros los discos estn organizados en unidades de acceso llamadas
bloques fsicos. Estos bloques, por lo general ocupan 512 bytes pero para optimizar el acceso a
disco los sistemas de ficheros definen unidades de acceso mayores, es decir, definen bloques
lgicos (ej : 512, 1024, 2048).
La estructura del sistemas de ficheros en Unix System V es :
bloque de boot

superbloque

lista de inodos

bloques de datos

Bloque de arranque
Es el primer bloque de la particin y ocupa 512 bytes (bloque 0). Puede contener
una referencia al programa de arranque. En algunos sistemas el programa de arranque
est ubicado en el sistema de ficheros de arranque (bfs), de manera que este bloque
sigue existiendo pero no es utilizado. La intencin est en independizar el arranque para
que no dependa de un sistema de ficheros en particular.
Superbloque
Segundo bloque de 512 bytes que almacena datos administrativos sobre el sistema
de ficheros tales como : nmero de bloques libres disponibles, lista de bloques libres,
lista de inodos libres.
Lista de inodes
Consiste en una serie de estructuras continuas de 64 bytes y cada una de las se
denomina inodo. Existe un inodo por fichero en el sistema. Esta lista de inodos
comienza en el bloque y su longitud es determinada en el momento de la creacin del
sistema de ficheros.
Bloques de almacenamiento
Comienzan tras el ltimo bloque de la lista de inodos y se extiende hasta el final del
espacio disponible. Estos bloques pueden contener los datos de los ficheros, punteros a
otros bloques del fichero o punteros a bloques libres.

Alberto Navarro Ezquerro Pag

15

Programacin de Sistemas

Descripcin de un inodo
Modo
Nmero de enlaces
Identificador de usuario
Identificador de grupo
Tamao del fichero
Direcciones de bloques
Fecha de acceso
Fecha de modificacin
Fecha de cambio
El Modo hace referencia al tipo de fichero y permisos de acceso y ocupa 2 bytes. El tipo
de fichero es un campo de 4 bits que se asigna cuando se crea el fichero y se incluyen en el campo
modo. Los tipos y los valores asociados son los siguientes :
Tipo
Ordinario
Directorio
Especial-Carcter
Especial-Bloque
Pipe
Enlace simblico
Inodo libre

Valor
1000
0100
0010
0110
0001
1010
0000

Se crea con
open(), creat()
mkdir()
mknod()
mknod()
mknod()
link()

Las direcciones de bloques ocupan 40 bytes y contienen 13 punteros a los bloques de


almacenamiento en ficheros regulares, directorios, o pipes. Los 13 punteros de direccionamiento
de bloques se distribuyen de la siguiente manera :

Del 0 al 9 son punteros directos a bloques lgicos de almacenamiento.


El n 10 es un puntero indirecto indexado en un nivel.
El n 11 es un puntero indexado a dos niveles.
El n 12 y ltimo es un puntero indexado a tres niveles.

Alberto Navarro Ezquerro Pag

16

Programacin de Sistemas

Directo 0
Directo 1
Directo 2
Directo 3
Directo 4
Directo 5
Directo 6
Directo 7
Directo 8
Directo 9
Indirecto
Simple
Indirecto
Doble
Indirecto
Triple

Superbloque
Siempre, una copia del superbloque de los sistemas de ficheros montados se mantiene en
memoria, fundamentalmente porque la informacin del superbloque se utiliza para la asignacin y
liberacin de inodos y de bloques. Los campos del superbloque son :

Direccin de comienzo de los bloques de almacenamiento


Nmero total de bloques (arranque, superbloque, lista de inodos, etc)
Nmero de bloques libres
Nmero de inodos libres
Nombre del sistema de ficheros
Nombre del volumen. Identifica el dispositivo en el que reside el sistema de ficheros
Sanity Flag. Flag indicativo del estado del sistema de ficheros. Puede valer :
OK
: El sistema de ficheros se ha desmontado correctamente.
ACTIVE
: El sistema de ficheros est en uso.
BAD
: El sistema de ficheros no fue desmontado correctamente.

Magic Number. Determina la versin en la que fue creado el sistema de ficheros.


Tamao del bloque lgico. (1 : 512, 2 : 1024, 3 : 2048).
Array de bloques libres. Es una lista de los primeros 50 bloques libres.
ndice del array de bloques libres. Puntero al siguiente bloque libre.
Array de inodos libres. Lista de los 100 primeros inodos libres disponibles.
ndice del array de inodos libres.

Alberto Navarro Ezquerro Pag

17

Programacin de Sistemas

Flag de bloqueo del array de bloques libres. Bloquea dicho array cuando est siendo
modificado.
Flag de bloqueo del array de inodos libres. Con la misma funcin que el anterior.
Flag de modificacin del superbloque. Indica que la versin en memoria del
superbloque ha sido modificada.
Campo de fecha y hora de la ltima modificacin del superbloque.
Flag de slo lectura. Indica si el sistema de ficheros se mont slo para lectura y
cualquier intento de modificacin del sistema de ficheros ser rechazada.
Lista de bloques libres
Durante la creacin de un sistema de ficheros (particin) se genera una lista con todas las
direcciones de todos los bloques lgicos libres. Las direcciones (punteros) de los 50 primeros
bloques libres se sitan en el array de bloques libres del superbloque, que forma el primer nodo de
la lista.
El resto de la direcciones de bloques libres son tambien divididas en grupos de 50. El resto
de los nodos contienen, 50 holding blocks que son punteros a bloques que contienen a su vez 50
punteros a bloques libres.
Asignacin bloques libres
El sistema asigna el siguiente bloque del array de bloques libres siempre que no sea un
holding block. Si el siguiente bloque es un holdong block el sistema coloca los punteros a bloques
libres del holding block en el array de bloques libres.
Liberacin de bloques
Si el array de bloques libres del superbloque no est lleno, le direccin del bloque liberado
se anota en el superbloque incrementndose el ndice del array. Si el array de bloques libres est
lleno, el bloque liberado es usado como holding block.
Lista de inodos libres
Asignacin de inodos : El ltimo ndice de la lista de inodos libres se denomina inodo
recordado de forma que cuando el sistema necesita un nuevo inodo busca en la lista de
inodos libres y si el primero no es el recordado lo asigna. Si se trata del inodo
recordado el sistema busca los siguientes 100 inodos libres empezando a buscar a partir
del inodo recordado y este ser asignado.
Liberacin de inodos : Si el inodo liberado es mayor que el inodo recordado el sistema
no hace nada. Si es menor se sustituye por el inodo liberado.

Alberto Navarro Ezquerro Pag

18

Programacin de Sistemas

Sistema de ficheros UFS


Emplea bloques lgicos de tamao mayor que el sistema enterior y, adems, se divide en
diversas secciones denominadas grupos de cilindros, repitindose en cada uno de ellos la siguiente
estructura (aunque slo uno de ellos tendr bloque de arranque) :
Bloque
de
arranque

Superbloque

Bloque Lista de
de
inodos
grupo
de
cilindros

Bloques de
almacenamiento
.......

Superbloque

Bloque
de
......
grupo de
cilindros

(El tamao de los bloques lgicos es de 4096 o de 8192)


Superbloque (ufs)
Cada grupo de cilindros tiene una copia del superbloque de manera que cuando se monta
un sistema de ficheros el primer superbloque se carga en memoria y mientras el sistema de
ficheros est montado slo el superbloque que est en memoria puede ser modificado. Cuando se
desmonta el sistema de ficheros los cambios se copian en todos los superbloques.
Contenido :

Fecha de la ltima modificacin del superbloque


Nmero total de bloques de almacenamiento en el sistema de ficheros
Nmero total de grupos de cilindros
El tamao de un fragmento
El nmero de cilindros, inodos y bloques para cada grupo de cilindros
Nmero de inodos libres en el sistema de ficheros
Nmero de bloques libres en el sistema de ficheros
Nmero de fragmentos libres
Lista de bloques de datos libres as como su posicin

Descripcin de un inodo
Al igual que en SVR4, un inodo define unicamente a un fichero y cada uno tiene 128 bytes
con la siguiente infomacin :

Modo : tipo de fichero y bits de ejecucin y permisos


Identificacin del propietario del fichero
Identificacin del grupo del fichero
Nmero de enlaces del fichero
Tamao del fichero en bytes
Fecha de la ltima modificacin de los datos
Fecha de la ltima modificacin del inodo
Alberto Navarro Ezquerro Pag

19

Programacin de Sistemas

Nmero de bloques asignados al fichero


15 punteros a bloques de almacenamiento. El mtodo usado para direccionar ficheros
en este sistema es parecido al empleado en SVR4. Los 12 primeros (0..11) son
punteros directos a bloques de almacenamiento, el 13 y el 13 constituyen una
indireccin simple y doble respectivamente y el 14 no se usa.
Aparte de lso tamaos de bloque de datos, se pueden usar otras unidades ms pequeas
que es lo que se denomina fragmento, de manera que tamao de este varia entre 512, 1024, 2048
y 4096 bytes.
Formato del directorio
Se organizan en unidades denominadas chunks o trozos. Estos trozos tienen la siguiente
estructrura :
longitud del chunk

nmero de inodo

longitud del
nombre

nombre del fichero

null

Estos chunks estn separados por huecos (gaps) de 4 bytes y el espacio es asignado a los
directorios en grupos de 512 bytes.

Sistema de ficheros BFS (boot file system)


Es un sistema de ficheros de propsito especfico y se emplea en el procedimiento de
arranque. La existencia de este sistema de ficheros aumenta la rapidez del procedimiento de
arranque e idependiza el arranque del tipo de sistema de ficheros que se vaya a usar.
Es un sistema de ficheros contiguo (los datos se almacenan secuencialmente de forma
continua) y plano (porque slo existe un directorio, el root). Este sistema de ficheros est siempre
montado en el directorio /stand y su estructura es la siguiente :
Superbloque

Inodos

Bloques de almacenamiento

El superbloque contiene la siguiente informacin :


Magic number
Tamao del sistema de ficheros (en bytes)
Varios sanity flags (flags de estado)

Alberto Navarro Ezquerro Pag

20

Programacin de Sistemas

Los inodos contienen la siguiente informacin :

Nmero de inodo (que vale 0 si est libre)


Puntero al primer bloque de datos
Puntero al ltimo bloque de datos
Tipo y modo del fichero
Identificacin de usuario y de grupo
Nmero de enlaces
Fechas de creacin, modificacin y acceso

Las caractersticas de los bloques de almacenamiento son :


Tamao 512 bytes
Las entradas en el directorio ocupan 16 bytes
Los bloques son almacenados de forma contigua de manera que cuando un fichero
se borra los bloques quedan automticamente liberados y para que el sistema los
vuelva a utilizar debe ocurrir que el fichero sea el ltimo o, en caso de no serlo, el
sistema detecta la necesidad de compactacin y la realiza.
Sistema de ficheros /Proc
Este sistema de ficheros est montado en el directorio con el mismo nombre y en l se crea
un fichero cada vez que se ejecuta un proceso. El nombre del fichero creado es el identificador del
proceso, pero es un fichero especial, no es un fichero ascii. Estos ficheros se borran cuando el
proceso termina tras una llamada a exit.
Sistema de ficheros virtuales
Funciones del subsistema de ficheros
El vfs es un discriminador de sistemas de archivos, por ejemplo, todas las llamadas open
iran al vfs y este sabra que orden open ejecutar dependiendo de la particin en la que este el
archivo (SVR4, ufs, ....).
Funciones :

Coordinar las llamadas relacionadas con los archivos (write, read, close, open...)
Coordinacin de los archivos abiertos en el sistema mediante tablas
Validacin de los permisos de acceso a los ficheros
Administracin de los ficheros en disco
Mantener la integridad del sistema de ficheros
Manejar distintos tipos de sistemas de ficheros

Alberto Navarro Ezquerro Pag

21

Programacin de Sistemas

Estructuras
User open file table : Existe una tabla de este tipo para cada proceso del sistema. Esta
tabla se almacena en el rea de usuario del proceso (user area) y tiene una entrada por
cada fichero abierto por el proceso. El descriptor del fichero es el lugar que ocupa el
fichero en dicha tabla.
System file structure : El sistema mantiene una estructura de este tipo por cada llamada
a open() que se haya realizado. Guarda informacin de como se abri el fichero y
tambien el offset del fichero que se est leyendo o escribiendo.
Vnode structure : Existe una estrucutra vnode por cada fichero y almacena informacin
referente a los atributos del fichero, pero es informacin independiente del tipo del
sistema de ficheros al que pertenece dicho fichero. Cada vnode tiene un puntero a una
estructura que se denomina vnodeops que son punteros a rutinas dependientes del tipo
de sistema de ficheros.
Virtual file system switch table : Esta tabla tiene una entrada por cada tipo de sistema
de ficheros que existe en el sistema. Cada una de las entradas de la tabla contiene
punteros a estructuras vfsops y esta estructura contiene, a su vez, punteros a rutinas
dependientes del tipo de sistema de ficheros.
Lista de sistemas de ficheros montados : Esta lista es necesaria para administrar los
diferentes sistemas de ficheros montados en el sistema.
Proyeccin en memoria de un fichero abierto
Cada proceso del sistematiene o posee una zona de memoria privada denominada user
area. Uno de los elementos de este rea es un array de los ficheros abiertos por el proceso. Este
array de punteros y cada uno de ellos apunta a un elemento de la tabla de ficheros del sistema
(system file list).
El array de la user area es el que denominamos user open file table cuyos punteros
apuntan a la lista de ficheros abiertos por el sistema denominada system file list y los punteros de
esta ltima son del tipo struct file.

Alberto Navarro Ezquerro Pag

22

Programacin de Sistemas

User Area

System File List

Archivos abiertos
df = 0

direccin

df = 1

direccin

struct file
struct file

vnode

vnode

vnode

df = k

direccin

struct file

Cada struct file contiene informacin sobre el fichero al que apunta (nmero de veces
referenciado, punteros a la anterior y siguiente estructura....) y entre esa informacin se encuentra
un puntero a la estructura vnode asociada al fichero. Un vnode es una estructura independiente
del sistema de ficheros que contiene, entre otros, los siguientes datos :
v_count : Contador del nmero de ficheros abiertos que hacen referencia a este
vnode.
v_data :

Puntero a la estructura de datos especfica del tipo de sistema de ficheros.

v_op :

Puntero a una estructura de operaciones del vnode.

v_vfsp :

Puntero a estructuras vfs que contienen punteros a funciones especficas


del tipo de sistema de ficheros.

User Open File Table : (/usr/include/sys/user.h)


typedef struct user
{ ......
int
u_nofiles ;
struct ufchunk
u_flist ;
} user_t ;

Nmero de ficheros abiertos


Tabla de ficheros abiertos

#define NFPCHUNK 24
struct ufchunk
{ ......
struct file
*uf_ofile[NFPCHUNK] ;
struct ugchunk
*uf_next ;
};

Alberto Navarro Ezquerro Pag

23

Programacin de Sistemas

Por defecto, cuando un proceso se activa en el sistema se localiza una nica estructura del
tipo ufchunk que ser u_flist. Esta u_flist contiene un array, por lo general, de 24 punteros de tal
forma que si el proceso abriera ms de 24 ficheros se buscara otra estructura ufchunk con otros
24 punteros.
Cuando se realiza la llamada open(), el sistema localiza una nueva struct file de la lista de
ficheros del sistema y retorna su descriptor de fichero. Ese descriptor es el elemento del array
uf_ofile asignado al fichero.
Lista de ficheros del sistema
Cada struct file mantiene informacin acerca de cada fichero abierto en el sistema. La
definicin de esta estructura est en /usr/include/sys/file.h :
typedef struct file
{ struct file
*f_next ;
Puntero al siguiente
struct file
*f_next ;
Puntero al anterior
u_short
f_flag ;
Modo de apertura (O_RDONLY.....)
cnt_t
f_count ;
Nmero de referencias a la estructura
struct vnode
*f_vnode ;
Puntero a la estructura vnode
off_t
t_offset ;
Posicin del ltimo byte leido o escrito
strcut cred
*f_cred ;
Guarda informacin sobre el proceso (id, grupo...)
} file_t ;
Estructura vnode
Almacena informacin administrativa bsica del fichero y cuando se realiza una llamada a
open() se accede al vnode del fichero para obtener ese tipo de informacin. La definicin de esta
estructura se encuentra en /usr/include/sys/vnode.h :
typedef struct vnode
{ u_short
v_flag ;
u_short
v_count ;
struct vfs
*v_vfsmountedhere ;
struct vnodeops *v_op ;
struct vfs
*v_vfsp ;
struct stdata
*v_stream ;
struct page
*v_pages ;
enum vtype
v_type ;
dev_t
v_rdev ;
caddr_t
v_data ;
struct filock
*v_filocks ;
long
v_filler[8] ;
} vnode_t ;

v_flag es un flag que se activa si se trata del vnode de root en un sistema de ficheros.
Alberto Navarro Ezquerro Pag

24

Programacin de Sistemas

v_count es un contador del nmero de referencias al vnode.


v_vfsmountedhere es un puntero a una estructura vfs montada en este vnode.
v_op es un puntero a la estructura de operaciones del vnode. Estas operaciones
depender, del tipo de sistemas de ficheros.
v_vfsp es un puntero a la estructura vfs del sistema de ficheros donde reside el vnode.
Esta estructura tiene funciones dependientes de acceso al sistema de ficheros.
v_pages es un puntero a la lista de pginas del vnode.
v_type recoge el tipo de fichero al que representa el vnode.
v_rdev recoge los valores del major y minor number.
v_data contiene punteros a estructuras de datos especficas del tipo de sistema de
ficheros
v_flocks es un puntero a la primera estructura flock para control de bloqueos.
v_filler[8] se emplea para saber a que directorio pertenece el vnode. Se usa en la
resolucin de pathnames.
Operaciones con vnodes
Cada vnode del sistema contiene un puntero *v_op a la estructura de operaciones del
vnode. La estructura vnodeops est descrita en /usr/include/sys/vnode.h y contiene punteros a
funciones que manipulan vnodes de ficheros individuales, entre las que se incluyen :

Funciones para la apertura del fichero (open())


Funciones para el cierre (close())
Funciones para lectura y escritura (read(), write())
Funciones para determinar los permisos del fichero
Funciones para cambiar sus atributos
Funciones para crear y borrar un fichero
Funciones para crear y borrar un directorio
Funciones para crear un enlace simblico
Funciones para escribir los datos modificados de un fichero desde los buffers a disco
Funciones para obtener las pginas de ficheros de cdigos (a.out) en un fallo de pgina

Alberto Navarro Ezquerro Pag

25

Programacin de Sistemas

Bloqueo de registros y ficheros


Los bloqueos se implementan con la llamada lock() o con fcntl(). Existe la posibilidad de
bloquear un fichero en su totalidad o slo una parte, especificando el offset de inicio y final del
bloqueo.
Existen dos tipos de bloqueo :
Advisory locking : Slo acta para aquellos procesos que comprueban previamente si
se ha bloqueado el registro. Si un proceso intenta acceder a un
registro bloqueado sin comprobacin conseguira el acceso.
Mandatory locking : Los bloqueos actan para todos los procesos que tratan de
acceder a registros bloqueados. Es necesario que el proceso tenga
activado el permiso de bloqueo.
Para controlar los bloqueos el sistema implementa una lista de estructuras de bloqueos, las
cuales se apuntan desde los vnodes de los ficheros. Esta estructura est definida en
/usr/include/sys/flock.h :
typedef struct filock
{ struct flock set ;
union stat
{ int
wakeflag ;
struct blk
{ long sysid ;
pid_t pid ;
}
}
struct filock *prev ;
struct filock *next ;
} filock_t ;

Especfica el tipo de bloqueo

El campo wakeflag se activa si cualquier proceso tiene que pasar a un estado sleep por un
bloqueo. Los procesos durmientes estn en una lista denominada sleep lock list.
Tabla de conmutacin virtual de ficheros (vfs switch table)
La flexibilidad para poder usar distintos tipos de sistemas de ficheros la proporciona el
sistema de ficheros virtual. El sistema mantiene una tabla por cada tipo de sistema de ficheros
presente en el sistema. En esta tabla donde cada una de las entradas es una estructura denominada
struct ufssw que contiene punteros a funciones dependientes del sistema de ficheros para, de esta
forma, manejar el sistema de ficheros en su totalidad.

Dicha estructura est definida en /usr/include/sys/vfs.h :


typedef struct ufssw
Alberto Navarro Ezquerro Pag

26

Programacin de Sistemas

{ char
int
struct vfsops
long
} vfssw_t ;

*vsw_name ; Contiene el nombre del sistema de ficheros


(*vsw_init)() ; Es una funcin de inicializacin para el S.A
*vsw_vffsops ; Es un puntero a la estructura de operaciones
vsw_flag ;

Relacin entre vnode y vfssw


Cada vnode contiene dos elementos que permiten acceder a funciones dependientes del
sistema de ficheros, v_op y v_vfsp.
Las estructuras de las operaciones (vfsops) pueden ser accedidas desde un vnode o desde
vfssw[]. El sistema usa adems una serie de macros definidas en vnode.h y vfs.h para llamar a esas
rutinas dependientes del sistema de ficheros.
Tabla de sistemas de ficheros montados
Cuando un sistema de ficheros ya est montado es posible acceder a cada uno de sus
ficheros. Cada sistema de ficheros reside en un dispositivo del sistema. Antes de montar un
sistema de ficheros este est fsica y lgicamente separado de la jerarqua del sistema. Para montar
un sistema de ficheros podemos usar la llamada al sistema mount() o el comando con el mismo
nombre. Con una llamada a mount() el sistema realiza los siguientes pasos :

Comprueba que el sistema de ficheros se puede montar


El sistema de ficheros se conecta lgicamente a la estructura jerrquica del sistema
Se localiza una entrada en la lista de sistemas de ficheros montados
Se mantiene en memoria una copia del superbloque del sistema de ficheros

La lista de sistemas de ficheros montados se denomina vfs list y tiene las siguientes
funciones :
Proporciona informacin a las rutinas del sistema para resolver los pathnames de los
ficheros cuando se producen cambios en el dispositivo fsico en el que residen esos
ficheros.
Para localizar los superbloques que utilizarn las subrutinas internas.
Para localizar funciones dependientes del sistema de ficheros.

Alberto Navarro Ezquerro Pag

27

Programacin de Sistemas

TEMA 5 : PRIMITIVAS DEL KERNEL


int open(const char *camino, int indic, int modo)
Includes necesarios :
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
Crea una estructura FILE y la conecta con mi programa mediante el descriptor que
devuelve. El campo indic puede tomar los siguientes valores :
O_RDONLY
O_WRONLY
O_RDWR
O_NDELAY
O_NONBLOCK
O_APPEND
O_SYNC
O_CREAT
O_EXCL
O_TRUNC

Slo lectura
Slo escritura
Lectura y escritura
El fichero es abierto de manera no bloqueante. Ninguna operacin que se
haga sobre el descriptor del fichero provocar espera del proceso que la
llame
Situa el puntero del fichero al final del mismo para aadir datos
Permite sincronizar la intencin de escribir con la operacin fsica.
Actualizacin de buffer a disco inmediata
Si el fichero no existe se crea, de lo contrario se obvia
Apertura exclusiva. Si se usa junto a O_CREAT y el fichero existe, open()
devuelve un -1
Si el fichero existe su longitud ser truncada a 0

Casos especiales :
En un fichero FIFO abierto slo para lectura, si O_NDELAY o O_NONBLOCK
no estn activos y el terminal de escritura no est abierto, la siguiente operacin
de lectura de vuelve -1.
En un fichero FIFO abierto slo para escritura, si O_NDELAY o _NONBLOCK
estn activos y el terminal de lectura no est abierto, la siguiente operacin de
escritura devuelve -1.

int close(int df)


Alberto Navarro Ezquerro Pag

28

Programacin de Sistemas

Includes necesarios :
#include <unistd.h>
Devuelve :
0 : ok
1 : Error
int read(int df, void *buffer, unsigned numbytes)
Includes necesarios :
#include <unistd.h>
#include <sys/types.h>
#include <sys/uio.h>
Devuelve :
Nmero de bytes leidos
-1

: ok
: Error

Casos especiales :
Que haya un proceso con un bloqueo imperativo sobre el archivo. Si se abri con
O_NDELAY o O_NONBLOCK entonces read devuelve -1.
Manejo de tuberas vacas. Si intento leer del extremo de lectura de una tubera
cuyo extremo de escritura est cerrado read devuelve 0. Si el terminal de
escritura est abierto y el open usa O_NDELAY read devuelve 0, si el open est
hecho con O_NONBLOCK read devuelve -1 y si ninguno est activo se bloquea.
int write(int df, void *buffer, unsigned numbytes)
Includes necesarios :
#include <unistd.h>
Devuelve :
Nmero de bytes escritos
-1

: ok
: Error

Casos especiales :
Si hay un proceso con un bloqueo imperativo de escritura sobre el archivo y otro
intenta acceder para escribir. Si se abri con O_NDELAY o O_NONBLOCK
entonces write devuelve -1. Si no estn activos se queda bloqueado.

int creat(const char *camino, mode_r modo)


Includes necesarios :
Alberto Navarro Ezquerro Pag

29

Programacin de Sistemas

#include <sys/types.h>
#include <fcntl.h>
Crea el archivo si no existe y lo abre para escritura. Si existe lo abre para escritura y borra
los datos existentes.
int unlink(const char *camino)
Includes necesarios :
#include <unistd.h>
Resta 1 al nmero de enlaces.
off_t lseek(int df, off_t offset, int whence)
Includes necesarios :
#include <unistd.h>
#include <sys/types.h>
Devuelve :
El nuevo offset del puntero de lect/escr
-1

: ok
: Error

Modifica el puntero de lectura/escritura del fichero asociado al handler df de la siguiente


forma :
Si whence vale SEEK_SET, el puntero avanza offset bytes con respecto al inicio
del fichero.
Si whence vale SEEK_CUR, el puntero avanza offset bytes con respecto a su
posicin actual.
Si whence vale SEEK_END, el puntero avanza offset bytes con respecto al final
del fichero.
Hay que tener presente que algunos ficheros no est permitido el acceso aleatorio y por lo
tanto la llamada a lseek no tiene sentido. Ejemplos de estos ficheros son los fifo y los ficheros de
dispositivos en los que la lectura se realiza siempre a travs de un mismo registro o posicin de
memoria.

int dup(int df)


Includes necesarios :
#include <unistd.h>

Alberto Navarro Ezquerro Pag

30

Programacin de Sistemas

Duplica un descriptor de fichero que ya ha sido asignado y que est ocupando una entrada
en la tabla de descriptores de ficheros. La llamada dup va a recorrer la tabla de descriptores y va a
marcar como ocupada la primera entrada que encuentre libre, pasando a devolvernos el descriptor
asociado a esa entrada.
int ustat(dev_t dev, struct ustat *buf)
Includes necesarios :
#include <sys/types.h>
#include <ustat.h>
La informacin administrativa y estadstica de un sistema de ficheros se encuentra en su
superbloque. Para acceder a los aspectos ms relevantes de esta informacin se usa ustat que los
devuelve en la estructura apuntada por buf. Dev es el nmero de dispositivo de la seccin del
disco donde se encuentra el sistema de ficheros. La estructura ustat se define :
struct ustat
{
daddr_t
ino_t
char
char
};

f_tfree ;
f_tinode ;
f_fname[6] ;
f_fpack[6] ;

Nmero de bloques libres


Nmero de inodes libres
Nombre del sistema de ficheros
Nombre del volumen del sistema de ficheros

void sync()
Includes necesarios :
#include <unistd.h>
Produce una sincronizacin entre el buffer cach y el disco, forzando as la consistencia del
sistema. Actualiza tambin el superbloque y los inodos que hayan sufrido modificacin.
void fsync()
Igual que la anterior pero no devuelve el control al programa hasta la consolidacin se
realice.

int mount(const char *particin, cons char *dir, int mflag, int fstype, cons char *datos,
size_t datoslen)
Particin
Dir
Mflag
Fstype
Datos

: Nombre fsico de la particin


: Direccin donde la monto
: Indica si se monta para lectura o escritura
: Indica el tipo del sistema de archivos
: Tipo de bloque
Alberto Navarro Ezquerro Pag

31

Programacin de Sistemas

Datoslen

: Longitud del bloque

Monta un sistema de ficheros desde un programa.


int umount(cons char *archivo)
Desmonta el sistema de ficheros. Archivo es un puntero el path name del fichero de
dispositivo que da acceso al sistema de ficheros que queremos desmontar.
int statvfs(const char *camino, struct statvfs *buf)
int fstatvfs(int desc, struct statvfs *buf)
Includes necesarios :
#include <sys/types.h>
#include <sys/statvfs.h>
Devuelven informacin acerca del sistema de ficheros.
int sysfs(int codop, const char *fsname)
int sysfs(int codop, int fs_indice, char *cadena)
int sysfs(int codop)
Includes necesarios :
#include <sys/fstype.h>
#include <sys/fsid.h>
Valor de codop :
GETFSIND

: Devuelve el ndice dentro de la tabla vfssw[] del sist de


archivos especificado en el segundo argumento.

GETFSTYPE

: Devuelve el nombre del sistema de archivos.

GETNFSTYPE

: Devuelve el n de tipos de sistemas de archivos.

int access(const char *camino, int modoacceso)


Includes necesarios :
#include <unistd.h>
Sirve para preguntar si tengo acceso con ese modo.
Modoacceso :
R_OK
: Lectura
W_OK
: Escritura
X_OK
: Ejecucin
Alberto Navarro Ezquerro Pag

32

Programacin de Sistemas

F_OK

: Existencia

Se deniega cuando :
El usuario efectivo no tenga permiso de ejecucin de alguno de los directorios. La
variable errno se carga con el valor EACCESS.
El modo del archivo no lo permite (errno = EACCESS).
Cuando en el camino especificado hay demasiados enlaces simblicos
= ELOOP ? ?).

(errno

Que alguno de los nombres del camino no sea un directorio (errno = ENOTDIR).
El fichero no existe (errno = ENOENT ? ?).
El archivo especificado por la ruta ...ENOLINK ? ? ?
Cuando el archivo est embebido en un sistema de archivos de slo lectura y
preguntas para escribir (errno = EROFS).
int chmod(const char *camino, mode_t modo)
int fchmod(int fd, mode_t modo)
Includes necesarios :
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
Cambia el modo.

int chown(const char *camino, uid_t usuario, gid_t grupo)


int fchown(int fd, uid_t usuario, gid_t grupo)
Includes necesarios :
#include <sys/types.h>
#include <sys/stat.h>
Cambia el propietario y el grupo de un fichero.
int stat(const char *camino, struct stat *buffer)

Alberto Navarro Ezquerro Pag

33

Programacin de Sistemas

Includes necesarios :
#include <sys/types.h>
#include <sys/stat.h>
Suministra informacin que se almacena en la tabla de inodes sobre el estado de un fichero
concreto. Informacin :

mode_t
ino_t
dev_t
dev_t

st_modo
st_ino
st_dev
st_rdev

: Modo de un archivo.
: Nmero del nodo de ndices del archivo
: Nmero del dispositivo que contiene al inode.
: Si es un archivo especial este campo tendr el major y el
minor del archivo especial.
nlink_t
st_nlink
: Nmero de enlaces.
uid_t
st_uid
: Uid del propietario real.
gid_t
st_gid
: Grupo del propietario.
off_t
st_size
: Tamao del archivo en bytes.
time_t
st_atime
: Fecha del ltimo acceso al fichero.
time_t
st_mtime
: Fecha de la ltima modificacin del fichero.
time_t
st_ctime
: Fecha de la ltima modifcacin administrativa.
longst_blksize
: Tamao del bloque del sistema de archivos.
longst_blocks
: Nmero de bloques.

Dibujo de la mscara del modo de un fichero :

Alberto Navarro Ezquerro Pag

34

Programacin de Sistemas

int fcntl(int df, int orden, arg)


union
{ int val ;
struct flock *lock ;
}arg ;
Includes necesarios :
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
Con la llamada fcntl vamos a tener control sobre un fichero abierto mediante una llamada previa a
open, creat, dup o pipe. Este control va a consistir en las posibilidades de cambiar los modos
permitidos de acceso al fichero, y de bloquear el acceso a parte del mismo o a su totalidad. El
bloqueo tiene especial importancia cuando varios procesos trabajan simultneamente con un
fichero, y es imprescindible que los accesos a determinados registros del mismo sean atmicos.
Valores permitidos para orden :
F_DUPFD : La llamada devuelve el descriptor de un fichero que se encuentra
libre en este instante y que rene las siguientes caractersticas :
Es el menor descriptor de valor mayor o igual arg.val
Tiene asociado el mismo fichero que el descriptor df
Tiene asociado el mismo puntero a fichero que fildes
El modo del fichero referenciado por el nuevo descriptor es el
mismo que el de df
Los flags de estado de fichero de ambos descriptores sern los
mismos
El descriptor se heredar de padres a hijos en las llamadas a exec
F_GETFD : La funcin devuelve el valor del flag close-on-exec asociado al
descriptor df. Si este flag est activo, el fichero no se cerrar
despus de ejecutar una llamada a exec. Del valor devuelto por
fcntl, slo tendr validez el bit menos significativo, que valdr 0 si el
flag no est activo y 1 en caso contrario.
F_SETFD : Activa el flag close-on-exec asociado a df de acuerdo con el bit
menos significativo de arg.val. Si el bit est a 1, el flag estar
activo.

F_GETFL : Devuelve los flags de estado y modo de acceso del fichero referido
Alberto Navarro Ezquerro Pag

35

Programacin de Sistemas

por df : O_RDONLY, O_RDWR, O_NDELAY, O_APPEND, etc.


F_SETFL : Fija los flags de estado de df de acuerdo con el valor de arg.val.
F_GETLK : Devuelve el primer cerrojo que se encuentra bloqueando la regin
del fichero referenciado por df y descrita en la estructura de tipo
struct flock apuntada por arg.lock. La informacin devuelta
sobrescribe la informacin pasada a fcntl en arg. Si no se encuentra
ningn cerrojo sobre esa regin, la estructura es devuelta sin
cambios, excepto en el campo l_type, donde se avtiva el bit
F_UNLCK.
F_SETLK : Activa o desactiva un cerrojo sobre la regin del fichero
referenciado por df y descrita por la estructura de tipo struct flock
apuntada por arg.lock. Se utiliza para establecer un cerrojo de
lectura (F_RDLCK), de escritura (F_WRLCK), o para eliminar uno
existente (F_UNLCK). Si no se puede fijar alguno de estos cerrojos,
la funcin termina inmediatamente y devuelve -1.
F_SETLKW : Esta orden es la misma que F_SETLK, con la diferencia de que si
no se puede establecer algn cerrojo, porque lo impiden otros ya
establecidos, el proceso se pondr a dormir hasta que se den las
condiciones que se lo permitan.
La estructura flock se define como sigue :
struct flock
{
short l_type

Tipo de cerrojo :
F_RDLCK : Lectura
F_WRLCK : Escritura
F_UNLCK : Eliminar el cerrojo

short l_whence

Punto al que se refiere el offset de la regin a bloquear :


SEEK_SET : Origen del fichero
SEEK_CUR : Posicin actal
SEEK_END : Final del fichero

off_t l_start

Offset relativo de inicio de la regin a bloquear

off_t l_leng

Longitud de la regin a bloquear. Si vale 0 se bloquea desde el


punto indicado en l_start hasta el final del fichero.

pid_t l_pid

Identificador del proceso (pid) que tiene fijado el cerrojo. Devuelto


con la orden F_GETLK.

long l_sysid

Identificador del sistema que tiene fijado el cerrojo. Devuelto con


la orden F_GETLK. } ;

Los cerrojos fijados por un proceso sobre un fichero se borran cuando el proceso termina.
Adems, los cerrojos no son heredados por los procesos hijos tras la llamada a fork.

Alberto Navarro Ezquerro Pag

36

Programacin de Sistemas

int mkdir(const char *camino, mode_t permisos)


Includes necesarios :
#include <sys/types.h>
#include <sys/stat.h>
Crea un directorio nuevo en el rbol.
int rmdir(const char *camino)
Includes necesarios :
#include <unistd.h>
Borrar un directorio del rbol.
int chdir(const char *camino)
int fchdir(int df)
Includes necesarios :
#include <unistd.h>
Permiten cambiar de directorio de trabajo al proceso que la ejecuta.
int chroot(const char *camino)
Includes necesarios :
#include <unistd.h>
Permiten cambiar el directorio raiz que tiene asociado un proceso. Slo la puede ejecutar
el administrador.
int pipe(int df[2])
Crea una tubera sin nombre. Te devuelve un descriptor de lectura y otro de escritura.
df[0] = De lectura
df[1] = De escritura

Alberto Navarro Ezquerro Pag

37

Programacin de Sistemas

TEMA 6 : PROCESOS
Estructura de un proceso
Un proceso consta de los siguientes segmentos :
TEXT

DATA

BSS

STACK

USER AREA

TEXT :

Es una copia de la seccin TEXT del ejecutable (cdigo)

DATA :

Contiene las variables globales estticas ya inicializadas

BSS :

Contiene las variables globales estticas no inicializadas

STACK :

Se crea cuando se ejecuta el programa y el sistema gestiona


automticamente el crecimiento de la pila cuando el proceso realiza
llamadas a funciones. En la pila se almacenan :
Entorno del proceso (pares nombre : valor)
Parmetros empleados en la llamda a cada funcin (y main)
Valores de los registros del procesador antes de cada llamada a
funcin asi como los registros de propsito general

USER AREA : Esta zona pertenece al espacio de direccionamiento del kernel,luego


no es accesible por el proceso. Aqu se almacenan los datos necesarios
para la ejecucin del proceso.
La zona marcada como se emplea para la expansin de los segmentos de datos y
pila. Con las rdenes brk() y sbrk() puedo hacer crecer el area BSS y DATOS.
Espacio de direccionamiento del kernel :

TEXT

Rutina trap.c
trap.s

Cdigo
Subsistema de
ficheros

Cdigo
Subsistema de
procesos

Cdigo
Subsistema E/S

Cdigo de
drivers

ESTRUCTURAS
DATA

DEL
USER AREA
proceso en
ejecucin

STACK

KERNEL

Stack del
sistema

Alberto Navarro Ezquerro Pag

38

Programacin de Sistemas

Estructuras relacionadas con procesos


User area
Esta definida en <sys/usr.h>. El kernel slo direcciona una user rea en un instante
determinado, la correspondiente al proceso en ejecucin. No es accesible desde el
propio proceso de usuario. Hay solamente una excepcin que se produce cuando un
proceso padre emplea la llamada ptrace() para depurar un proceso hijo.
El user rea del proceso que se va a ejecutar es mapeada (no copiada) en el
espacio de direccionamiento del kernel.
typedef struct user
{ char
u_stack[KSTKSZ] ; Contiene una copia de la pila del kernel
o_uid_t
u_uid ;
id del propietario efectivo
o_gid_t
u_gid ;
id del grupo efectivo
o_uid_t
u_ruid ;
id del propietario real
o_gid_t
u_rgid ;
id del grupo real
struct vnode *u_cdir ;
Puntero al directorio actual
struct vnode *u_rdir ;
Puntero al directorio root
uint
u_tsize ;
Tamao del rea de cdigo
uint
u_dsize ;
Tamao del rea de datos
uint
u_ssize ;
Tamao de la pila de usuario
struct rlimit u_rlimit[RLIM_NLIMITS] ; Array de lmites de recursos
struct ufchunk u_flist ;
Lista de ficheros abiertos
clock_tu_ticks ;
Ticks de ejecucin
proc_t
*u_procp ;
Puntero a la estructura del proceso
} user_t ;
Process structure
Es, junto con el user rea, la estructura ms importante para gestionar los
procesos de usuario. El kernel la usa para escoger el siguiente proceso a ejecutar y en
situaciones de cambio de contexto.
Cada proceso tiene asociada una estructura de este tipo, direccionable en todo
momento por el kernel. Estas estructuras son asignadas dinmicamente.

Typedef struct proc


Alberto Navarro Ezquerro Pag

39

Programacin de Sistemas

{
char
int
struct cred
struct proc
struct as
k_sigset
struct vnode
pte_t
} proc_t ;

p_stat ;Contiene el estado del proceso


p_pri ;
Prioridad del proceso
*p_cred ;
Credenciales de usuario (permisos....)
*p-link ;
Puntero a la siguiente struct proc
*p_as ;
Puntero al espacio de direccionamiento del proceso
p_sig ;
Seales pendientes del proceso
*p_exec ;
Puntero al fichero ejecutable
*pubptbl ;
Puntero al user rea del proceso

Interface con el sistema operativo


Modos de operacin
El sistema operativo tiene dos modos de operacin :
Modo USER : El procesador ejecutar instrucciones contenidas en el segmento
TEXT del proceso de usuario. No puede acceder nunca a datos del kernel.
Modo SYSTEM : Los procesos pueden ejecutar instrucciones privilegiadas y
acceder a datos del kernel.
Cualquier proceso puede cambiar su modo de operacin debido a tres causas englobadas en
dos tipos de eventos :
Eventos internos al proceso (sncronos)
Traps : Son producidos de forma involuntaria por el proceso que esta en ejecucin
(desbordamiento de pila, violacin del segmento...). En estos casos el kernel
ejecutar rutinas especiales que pueden provocar que el proceso sea abortado.
Todos estos eventos deben ser gestionados en modo system.
Llamadas al sistema : Son un caso especial de traps. En este caso el proceso
provoca un trap de forma deliberada para obtener una va de entrada al kernel y
ejecutar una determinada funcin en modo system (por ejemplo read()).
Eventos externos al proceso (asncronos)
Interrupciones : Este tipo de eventos se pueden producir en cualquier momento no
guardando relacin con el proceso en ejecucin en la mayota de los casos (por
ejemplo la interrupcin del reloj...).

Estados de un proceso
Alberto Navarro Ezquerro Pag

40

Programacin de Sistemas

ejecutndose en
modo usuario
retorno al
modo usuario

1
zombi
llamada al sistema
o interrupcin

durmiendo
en memoria

dormir

retorno

cambio de
contexto

exit
ejecutndose en modo kernel

ejecucin
de otro
proceso

interrupcin
retorno de
una interrupcin
listo para ejecutarse
en memoria

orden de ejecucin por


parte del scheduler

despertar

swap out

swap out

durmiendo
en memoria
secundaria

swap in

despertar

hay suficiente
memoria
creado

no hay suficiente
memoria

listo para ejecutarse


en memoria secundaria

Familia de llamadas exec()


Toda la familia de llamadas exec permiten transferir el control del proceso desde el
programa actal a uno nuevo. En cualquiera de sus formatos, una llamada a exec superpone la
imagen del proceso nuevo sobre la del antiguo lo que implica que si una llamada exec se realiza
sin errores no se puede regresar al proceso inicial.
Exec sustituye el segmento de cdigo del proceso original con el del nuevo y crea un nuevo
segmento de datos. Los descriptores de ficheros abiertos por el programa inicial permanecen
abiertos en el nuevo, con la excepcin de aquellos que tengan activo el bit close_on_exec.
Las zonas de memoria compartidas del programa antiguo no se conectan al nuevo
programa. Los identificadores reales de usuario y de grupo del proceso no se cambian, sin
embargo los efectivos pueden cambiar si estn activos los bits set_user_id o set_group_id.
Una llamada a exec slo vuelve al proceso de llamada en el caso de producirse algn error,
adems, en este caso, la llamada devuelve el valor -1.
La diferencia entre las distintas llamadas a exec est en :
Formato de su argumentos
Entorno de trabajo
La variable PATH
Alberto Navarro Ezquerro Pag

41

fork

Programacin de Sistemas

De manera que todas aquellas llamadas que no exportan el entorno de trabajo de manera
automtica finalizan con la letra e (execle, execve....) y aquellas que realizan una bsqueda
automtica por el PATH finalizan con la letra p (execlp, execvp....).
Las funciones son (<unistd.h>) :
int execv (const char *path, const char *argv[])
Ejecuta el programa indicado por path como un nuevo proceso. El parmetro
argv[] es un array de cadenas terminadas en 0 que se usa para dar valor al
parmetro argv de la funcin main() del programa que se va a ejecutar. El ltimo
elemento de este array debe ser un puntero nulo. Por convencin el primer
elemento de argv es el nombre del fichero. El entorno se exporta automticamente
tomndolo de la variable environ del proceso actual. No se realiza bsqueda
automtica por el path, por lo que habr que especificar el nombre completo del
fichero a ejecutar.
int execl (const char *path, const char *arg0,........, const char *argn)
Igual que execv slo que las cadenas de argv se especifican individualmente. El
ltimo de los argumentos debe ser un puntero nulo.
int execve (const char *path, const char *argv[], const char *env[])
Igual que execv slo que el entorno no se exporta automticamente y se puede
especificar explcitamente en el parmetro env[]. Es un array de cadenas con la
misma forma que la variable environ (nombre=valor).
int execle (const char *path, const char *arg0,...,const char *argn,const char *env[])
Similar a execl pero permite especificar el entorno para el nuevo proceso
explcitamente.
int execvp (const char *fich, const char *argv[])
Igual que execv slo que realiza la bsqueda automtica por le PATH.
int execlp (const char *fich, const char *arg0,....., const char argn)
Similar a execl con la excepcin de que se realiza una bsqueda automtica por el
PATH. El entorno se exporta automticamente.
El programa llamado con exec heredar el user rea del proceso que realiza la llamada por
lo tanto recibir : el PID, PGID y TGID (terminal group id).

Llamada fork()
Permite generar un nuevo proceso o proceso hijo es una copia exacta del proceso padre. El
formato de la llamada fork() es :
#include <sys/types.h>
#include <unistd.h>
Alberto Navarro Ezquerro Pag

42

Programacin de Sistemas

pid_t fork()
Si la llamada tiene xito habr dos procesos, el padre y el hijo, que vern el retorno de la
llamada pero con un valor diferente para cada uno de ellos. Retornar 0 para el proceso hijo y el
identificador del proceso hijo para el padre. Si se produce un error retornar -1 al padre.
El proceso hijo hereda :

Los id real y efectivo de usuario y grupo


El entorno del proceso (las variables que hayan sido exportadas)
Los valores para la manipulacin de seales
La clase del proceso
Los segmentos de memoria compartida
El directorio root y el actual
La mscara de creacin de ficheros
Los lmites de recursos y el terminal de control asociado.

El proceso hijo difiere en :

El hijo tiene un ID de proceso nico


Dispone de una copia privada de los descriptores de ficheros abiertos por el padre
El conjunto de seales pendientes del proceso hijo es vaciado
El hijo no hereda los bloqueos de ficheros establecidos por el padre

Llamada exit
Un proceso puede terminar su ejecucin mediante una llamada a exit() o al recibir una seal
o al finalizar su funcin main(). El formato de exit() es el siguiente :
#include <stdlib.h>
void exit (int status)
Finaliza el proceso liberando los recursos que estaba utilizando : libera reas de memoria,
cierra los ficheros y se autoelimina de la tabla de procesos. El valor de status es pasado a la
llamada wait() del proceso padre y los valores pueden ser :
0
1-255

Todo es correcto
Indican cdigos de error definidos por el usuario

Llamada wait(), waitid() y waitpid()


Wait() suspende la ejecucin que la emplea hasta que uno de los hijos directos terminan o
bien hasta que un hijo que est siendo trazado se detenga al recibir una seal.
#include <sys/types.h>
#include <sys/wait.h>
Alberto Navarro Ezquerro Pag

43

Programacin de Sistemas

pid_t wait (int *status)


Retorna el identificador del proceso que finaliz. En caso de error retorna -1. En status se
almacenar la siguiente informacin :
Si el proceso hijo que est siendo trazado ha sido detenido, los 8 bits de mayor peso
contendrn el nmero de la seal que provoc la parada, los otros 8 bits sern iguales o
tendrn el valor WSTOPFLG.
Si el proceso hijo termin debidoa una llamada a exit() los 8 bits de mayor peso
contendrn los 8 bits de menor peso del argumento en la llamada a exit().
Si el proceso hijo termin debido a la recepcin de una seal, los 8 bits de mayor peso
estarn a 0 y los otros 8 tendrn el nmero de la seal recibida.
La llamada waitid() permite que un proceso sea suspendido hasta que un proceso hijo o un
grupo de procesos cambie de estado. El formato es el siguiente :
int waitid (idtype_t idtype, id_t id, siginfo *infop, int op)
Waitid() retorna 0 si el proceso o los procesos hijos han terminado o si han cambiado de
estado y -1 en caso de error.
Idtype indica el tipo del argumento id, los posibles valores son :
P_PID

: Indica que hay que esperar por el proceso cuyo pid coincida con el valor
de id
P_GID : Espera por todos los procesos del grupo id
P_ALL : Espera por todos los procesos del grupo
En *infop se encuentra el estado del proceso hijo. La estructura siginfo_t tiene los
siguientes campos :
int si_signo
int si_errno
int si_code

: Nmero de seal
: Nmero de error
: Informacin sobre el motivo de la seal

Op es la combinacin de los siguientes flags :


WEXITED
WSTOPPED
WNOHANG
WNOWAIT

Indica que hay que esperar que el proceso o los procesos terminen
Hay que esperar que el proceso o los procesos sean detenidos y
devolver en infop informacin sobre la seal
El proceso debe retornar inmediatamente, no tiene que pasar a
sleep
Para obtener informacin sobre el proceso hijo en infop sin liberar
la estructura de proceso de ese proceso.
Alberto Navarro Ezquerro Pag

44

Programacin de Sistemas

Alberto Navarro Ezquerro Pag

45

Programacin de Sistemas

TEMA 7 : SEALES
Introduccin
Una seal es un mensaje de un proceso a otro con relacin de parentesco. Estas seales
software se envan en un instante determinado pero el proceso no sabe cuando le llega, ni quien se
la enva, pero si sabe que interrupcin le llega.

t0

t1

t2

Seal

Seal

Seal

Kernel

Proceso
usuario

s0
Puede
ignorarla

tj

s1
Rutina de
tratamiento

s2

tk
Fin

Fin

Tratamiento
por defecto

core

Fin

Fin

Seales en Unix SVR4


El Unix SVR4 pone a disposicin del usuario 31 interrupciones (la int. 32 est a disposicin
de cada fabricante).
Las interrupciones 16 y 17 son de usuario y los procesos las pueden utilizar para
comunicarse. Se agrupan en cinco categoras :
Condiciones hardware : Enviadas por el sistema cuando se produce un error durante la
ejecucin de un proceso.
SIGSEV : Ser enviada a un proceso cuando acceda a direcciones que estn fuera
de su espacio de direccionamiento o a zonas de memoria protegidas.
SIGBUS : Cuando se intenta realizar un acceso a un hardware sobre el que no
tengo privilegio.
SIGILL : Ejecucin de una instruccin ilegal.

Alberto Navarro Ezquerro Pag

46

Programacin de Sistemas

Condiciones software : Seales generadas por un requerimiento del usuario.


SIGINT

: Generada cuando se pulsa ctrl-c (es enmascarable).

SIGQUIT

: Generada cuando se pulsa ctrl-esc

SIGTERM

: La enva un usuario a un proceso con la orden kill. El proceso


morir si no est en modo sistema. Si lo est se esperar a que
termine.

SIGHUP

: Indica un corte en la lnea de comunicaciones (apagas el


terminal).

SIGKILL

: Indica muerte imperativa. No es enmascarable.

SIGUSR1

: Definibles por el usuario.

SIGALRM

: Es enviada a un proceso cuando alguno de sus temporizadores


descendientes llega cero.

Que efectan notificaciones de operaciones de E/S


SIGPOLL

: La revive un proceso cuando se est produciendo una e/s por un


stream que est siendo gestionado por una interrupcin poll.

Control de procesos
SIGSTOP

: Saca a un proceso de la zona de swapping (slo en SVR4). Seal


de parada de un proceso.

SIGCONT

: Lleva al proceso a background. Continua la ejecucin del proceso.

SIGCLD

: El hijo la enva la padre cuando cambia de estado.

Control de recursos
SIGXCPU

: Exceso de consumo de CPU o de memoria por parte del proceso.

SIGXFSZ

: El proceso ha sobrepasado el tamao mximo para un archivo.

Alberto Navarro Ezquerro Pag

47

Programacin de Sistemas

Mejoras de SVR4 respecto a SVR3


En SVR3 cuando un usuario armaba a un proceso contra una interrupcin con una rutina
de tratamiento, esta se descargaba y slo vala para una vez. En SVR4 permanece
cargada siempre, hasta que se desarma.
En SVR4 se puede diferir la rutina de tratamiento de una interrupcin y se deja pendiente
de tratamiento.
En SVR3 una rutina de tratamiento poda ser interrumpida por una nueva interrupcin y
en SVR4 no.
Estructuras empleadas en la gestin de seales
El kernel tiene una tabla de rutinas de tratamiento llamada u_signal[] de la cual dona una
copia al user rea de cada proceso. Contiene 32 entradas que se pueden modificar mediante la
llamada a signal(). Estas acciones (las que estn en cada entrada) pueden ser :
Accin por defecto
Ignorar
Manejador propio

: u_signal[i] = = SIG_DFL
: u_signal[i] = = SIG_IGN
: u_signal[i] = = handler (direccin de la funcin a ejecutar)

Y una segunda estructura de tres arrays de 32 bits :


p_sig : Estado de las seales para el proceso. Cada bit indicar si la seal correspondiente
se ha producido o no. Las seales no se encolan dos veces, slo se refleja una
ocurrencia. El bit correspondiente estar activo hasta que se proceso la seal.
p_hold : Cada bit indico si el tratamiento de la seal correspondiente debe ser o no
diferido o retenido. Una seal se puede retener o liberar con sighold() o sigrelease().
p_ignore : Cada bit indica si la seal correspondiente debe ser ignorada o no.

Primitivas para el envo de seales

Alberto Navarro Ezquerro Pag

48

Programacin de Sistemas

int sigsend (idtype_t, idtype, id_t id, int sig)


Permite enviar la seal especificada en sig a un proceso o a un grupo de procesos o a
todos. Los valores de idtype indican el tipo de argumento que es id sus posibles valores
son :
P_PID
P_PGID
P_SID
P_UID
P_GID
P_ALL
P_MYID

: La seal se enva al proceso con identificador id.


: A todos cuyo id de grupo sea id
: Al proceso cuyo n de sesin sea id
: A todos cuyo uid efectivo sea id
: A todos cuyo gid efectivo sea id
: A todos los procesos. Se ignora id
: Al proceso que ejecuta la funcin

Si todo va bien devuelve 0, en caso de error -1. Esta funcin es de SVR4 y necesita los
includes <sys/types.h> y <sys/signal.h> y <sys/procset.h>.
int kill (pid_t pid, int sig)
Permite enviar la seal especificada en sig al proceso o grupo de procesos especificado
en pid. Significado de los valores de pid :
Si el pid es positivo considera que es un pid vlido para enviarle la seal
Si el pid = 0 la seal se enva a todos los que son del grupo del emisor
Si el pid = -1 y el proceso emisor es root se enviar a todos los procesos del
sistema menos el 0 y el 1.
Si el pid = -1 y el proceso emisor no es root se enva a todos los procesos con
el mismo identificador de usuario efectivo.
Si pid != -1 se enva a todos los procesos cuyo identificativo de grupo sea el
valor absoluto de pid.
El valor de retorno es 0 si la seal se envo satisfactoriamente, en caso contrario no se
enva ninguna seal y retorna -1. Esta funcin es de SVR3 y necesita los includes
<sys/types.h> y <signal.h>.

Primitivas para la recepcin de seales


Todos los procesos son susceptibles de recibir seales. Todos los procesos puede protegerse
contra todas las interrupciones enmascarables.
Alberto Navarro Ezquerro Pag

49

Programacin de Sistemas

void (*signal (int sig, void (*trata)(int))) (int)


Es un puntero a funciones que admiten enteros. Devuelve la direccin de la antigua
rutina de tratamiento que estaba instalada. El segundo parmetro puede ser :
SIG_DFL
SIG_IGN
Cualquier funcin de usuario
No hay que olvidar que signal es una funcin de SVR3 y slo carga la rutina de
tratamiento de usuario una vez, la segunda vez que el proceso la reciba se ejecutar la
rutina por defecto y morir.
void (*sigset (int sig, void (*trata)(int))) (int)
Es la versin de signal en SVR4. Carga la rutina de tratamiento de manera indefinida
hasta que se desarme. El segundo parmetro puede ser :
SIG_DFL
SIG_IGN
SIG_HOLD : El tratamiento se difiere hasta que un determinado bit del array
p_hold se ponga a 0.
Rutina de usuario
Otras primitivas
int sigpause (int seal)
Suspende la ejecucin de un proceso hasta que le llega la interrupcin especificada en
seal. Desactiva el bit correspondiente del array p_hold.
int sigignore (int seal)
Instala el handler SIG_IGN para la interrupcin seal.

Alarmas
Es un estado de cuenta atrs, pasado el cual el procedimiento que la instalado recibe una
interrupcin.

Alberto Navarro Ezquerro Pag

50

Programacin de Sistemas

unsigned alarm (unsigned seg)


El proceso no se detiene y pasados seg segundos recibe la seal SIG_ALRM. Si no est
protegido muere. Puedo instalar una alarma n veces pero no se acumulan si no que se
superponen.
Saltos globales
La rutina de tratamiento de una seal puede hacer que el proceso vuelva a alguno de los
estados por los que ha pasado con anterioridad. Esto no slo es aplicable a las rutinas de
tratamiento de seales sino que se puede extender a cualquier funcin. Para ello nos valemos de
dos funciones estndar de librera setjmp y longjmp.
#include <setjmp.h>
int setjmp(jmp_buf env)
void longjmp(jmp_buf env, int val)
Setjmp guarda el entorno de la pila en env para un uso posterior de longjmp. Devuelve 0 en
su primera llamada.
Longjmp restaura el entorno guardado en env por una llamada previa a setjmp. Despus de
haberse ejecutado la llamada a longjmp, el flujo de la ejecucin vuelve al punto donde se hizo la
llamada a setjmp, pero en este caso setjmp devuelve el valor val que hemos pasado mediante
longjmp. En el caso de que val valga 0 setjmp devolver 1.
jmp_buf entorno;
int valor;

valor = setjmp(entorno);
valor = 0

valor = 10

longjmp(entorno,10);

TEMA 8 : PRIORIDADES EN UNIX SVR4


Introduccin
Switching el mtodo empleado por el sistema operativo para planificar la CPU entre los
procesos.
Alberto Navarro Ezquerro Pag

51

Programacin de Sistemas

Tenemos distintos niveles de switching en funcin de la clase del proceso :


Nivel independiente de la clase
Nivel dependiente de la clase
Con dos clases de prioridad :
Clase de tiempo compartido
Clase de tiempo real
Acciones que se aplican al proceso :
switching out
switching in

Aplicado a un proceso significa que el proceso libera la CPU


Aplicado a un proceso significa que dicho proceso pasa a ejecucin

El proceso en ejecucin realiza una llamada a una rutina del kernel denominada switch o
pswitch que son las responsables de realizar el switching out del propio proceso.
Un proceso en ejecucin tiene su user rea mapeada dentro del espacio de direccionamiento
del kernel y la localizacin fsica de ese user rea no cambia, sino que pasa a formar parte del
espacio virtual del kernel.
Cada proceso tiene asignado una rodaja de tiempo time slice para su ejecucin. Este
tiempo depende del nivel de prioridad y de la clase a la que pertenece (tiempo real o tiempo
compartido).

Variables independientes de la clase


El kernel emplea estas variables para coordinar la planificacin de procesos. Son vlidas
para tiempo compartido y para tiempo real :
curproc
curpri
runrun

Puntero a la process structure del proceso en ejecucin.


Prioridad del proceso en ejecucin.
Estos dos deben estar activos para invocar a la funcin switch.
Alberto Navarro Ezquerro Pag

52

Programacin de Sistemas

kprunrun
srunprocs
dispq[]

Recoge el nmero de procesos en espera de ser ejecutados.


Es un array que tiene tantos elementos como prioridades distintas hay en el
sistema. Para cada tipo de prioridad contempla una lista enlazada con
todos los procesos con esa prioridad.
dispq[0]

dispq[79]
maxrunpri
dqactmap

t1

tw

t2

t w+1

Valor mximo de prioridad entre todos los procesos ejecutables


Bitmap que contiene un bit por cada elemento del array dispq[] de manera
que si el bit est activo significa que existen procesos en ese nivel de
prioridad.

Funciones independientes de la clase


Las ms importantes son :
setbackq() y sefrontq()
Se encargan de situar a los procesos al principio o al final de la tabla dispq[]
correspondiente.
preempt (macro)
Examina el indicador kprunrun (flag que identifica la finalizacin de una tarea en
tiempo real) y la extrae si ha acabado.
Evoca a la funcin preempt() que interrumpe la ejecucin de un proceso. Ha de
ejecutar dos rutinas : ts_preempt() y rt_preempt().
Cuando la tarea ha sido desalojada llama a la rutina pswitch() que coger de dispq[]
una tarea para ejecutarla.
pswitch()
Es la encargada de seleccionar el proceso con mayor prioridad y de terminar el cambio
de contexto que se ha iniciado con la funcin preempt().

Colas de prioridades

Alberto Navarro Ezquerro Pag

53

Programacin de Sistemas

dispq[ ]

Depende del nmero de clases de prioridades


En nuestro caso :
ts : 0..99
rt : 100..159

+
M

Cada ndice apunta a una lista enlazada con todos las tareas con esa prioridad. El
planificador de tareas busca de mayor a menor prioridad. En la parte de tiempo real normalmente
hay tareas del sistema y no es aconsejable meter tareas de usuario.
El proceso 0 job scheduler maneja el algoritmo de bsqueda.
Nivel independiente de la clase
Cada clase de prioridad define sus propios algoritmos de asignacin de CPU. Estos
algoritmos estn implementados en las llamadas funciones dependientes de la clase (cada proceso
hereda la prioridad del proceso padre). Un proceso puede modificar su prioridad mediante la
llamada priocntl().
Cada clase de prioridad tiene una entrada en la tabla class[] definida en <sys/class.h>. Cada
elemento de esta tabla es una estructura con el siguiente formato :
typedef struct class
{ char
char
struct classfuncs
} class_t ;

*cl_name ;
(*ct_init)() ;
*cl_funcs ;

Nombre de la clase (RT o TS)


Rutina de inicializacin de cada clase
Puntero a una estructura con las funciones de cada
clase

typedef strcut classfuncs


{ .....
int (*cl_fork)() ;
void (*cl_forkret)() ;
Alberto Navarro Ezquerro Pag

54

Programacin de Sistemas

} classfuncs_t ;
Funciones dependientes de la clase
cl_enterclass()
Funcin empleada para situar un proceso en una clase de prioridad determinada.
cl_exitclass()
Saca a un proceso de una clase de prioridad
cl_tick
Es invocada desde clock() y es la responsable de chequear si el proceso en ejecucin
ha consumido el tiempo asignado, y si es asi se encarga de activar el flag runrun para
activar otro proceso.
cl_sleep()
Se ocupa de pasar un proceso a estado de sleep.
cl_wakeup
Responsable de despertar al proceso que estaba dormido y de pasarlo a dispq.
cl_fork y cl_forknet
Son invocadas desde fork() cuando se genera un nuevo proceso en el sistema. La
primera inicializa una nueva estructura especfica de la clase para el proceso hijo
generado. La segunda es invocada por el proceso padre antes de volver a modo usuario
y se encarga de decidir que proceso retornar antes a modo usuario (en la mayora de
los casos es el proceso hijo).
cl_trapret
Es invocada al retornar de una llamada o trap y es la encargada de ajustar la prioridad
de los procesos.
Clase de tiempo compartido
Un proceso pertenece generalmente a esta clase a no ser que se emplee la llamada al sistema
priocntl() para asignarle una nueva clase de prioridad. El rango de prioridades por defecto va de 0
a 99. Cada proceso tiene asignada una estructura de datos dependiente de la clase.

La prioridad se obtiene a partir de una operacin con dos operandos : uno proporcionado
por el kernel y el otro por el usuario. La porcin del kernel permite calcular el uso de CPU en
funcin de la prioridad del proceso ; si un proceso emplea la CPU la porcin del kernel disminuye,
es decir el proceso tendr menos posibilidades de ser seleccionado por pswitch(). Si un proceso
no emplea la CPU durante un determinado intervalo la porcin del kernel aumenta incrementando
las posibilidades del proceso de ser seleccionado. La porcin de usuario puede ser especificada
con priocntl() siempre que se tengan privilegios de superusuario.
Alberto Navarro Ezquerro Pag

55

Programacin de Sistemas

Tabla de parmetros de la clase tiempo compartido


Se llama ts_dptb[] y est definida en <sys/ts.h>. El contenido de la tabla puede ser
modificado en memoria editando el fichero /etc/conf/packd/ts/space.c.
Cada elemento de la tabla es una estructura del tipo tsdpent cuyos campos ms importantes
son :
ts_globpri Prioridad global del proceso que se asignar a p_pri de la estr. del proceso
ts_quantum Tiempo asignado al proceso (time slice)
ts_tqexp
Nivel de prioridad en el que se situar un proceso que no ha terminado
pero que ha gastado su time slice y ha de ir a dispq[].
ts_slpret
Nivel de prioridad en el que se situar un proceso cuando retorne a modo
usuario desde el modo sleep.
ts_maxait N de segundos que el proceso podr esperar sin consumir su quantum
ts_lwait
Prioridad que se le asignar al proceso cuando expire ts_maxwait
Clase de tiempo real
Cualquier proceso de esta clase tendr una prioridad superior a cualquier proceso de la
clase tiempo compartido. Las prioridades van, por defecto, de 100 a 159.
Para soportar el tiempo real el sistema operativo define los llamados preemption points.
Estos puntos estn simulados en puntos del cdigo donde el proceso en ejecucin puede liberar la
CPU sin afectar a la integridad del sistema y suele hacerse en puntos donde el kernel consume una
cantidad de tiempo considerable.
Para implementar uno de estos puntos el sistema emplea la macro preempt() que chequea el
flag kprunrun y si est activo invoca a preempt() para interrumpir el proceso en ejecucin.
Kprunrun indica que hay un proceso de tiempo real activo.
Estos puntos se ejecutan en puntos de cdigo como los siguientes :

Antes y despus de exec()


Antes y despus de exit()
En la resolucin de pathnames, antes de buscar en cada directorio
En stat(), lstat() y fstat() antes de copiar la informacin solicitada por el usuario
En la creacin de ficheros

Estructura de proceso para definir una clase en tiempo real


Se llama rt_proc() y est definida en <sys/rt.h>. Contiene, entre otros, los siguentes
campos :
rt_pquantum
rt_timeleft

Quantum asignado al proceso. Est tabulado.


Recibe su valor de rt_pquantum y es sometido a un descuento.
Alberto Navarro Ezquerro Pag

56

Programacin de Sistemas

rt_pri
rt_flags

rt_procp
rt_pstat
rt_pprip
rt_next
rt_prev

Prioridad
Puede tomar los siguientes valores :
RTRAN
: El proceso se ha ejecutado en el ltimo swap out
RTBACKQ : Situar al proceso al final de la cola
Puntero a la estructura del proceso
Puntero al campo de estado p_stat de la estructura del proceso
Puntero al campo de estado p_pri de la estructura del proceso
Puntero a la estructura siguiente
Puntero a la estructura anterior

Tabla de parmetros de la clase de tiempo real


Se llama rt_dptbl[] y est definida en <sys/rt.h>. El contenido se puede modificar editando
el fichero /etc/conf/pad.d/rt/space.c.
Cada elemento de la tabla es una estructura de tipo rtdpent cuyos campos son los mismos
que ts_dptbl[].
Sincronizacin entre procesos
Cuando un proceso requiere que un recurso determinado del sistema este disponible o est
esperando a que se complete una operacin de E/S, el proceso pasa automticamente a un estado
de sleep de manera que si se solventan estas situaciones el proceso pasa de nuevo a un estado de
disponible para ejecucin mediante una llamada a wakeprocs().
Bsicamente, wakeprocs(), lo que hace es aadir la estructura del proceso a la cola de
prioridad correspondiente y ser pswitch() la encargada de seleccionar el proceso, y la ejecucin
continuar en el punto siguiente en donde fue interrumpido.
Estados de un proceso :
SZOMB
SRUN

: Representa que el proceso ha ejecutado una funcin exit() pero


todava no ha sido eliminado del sistema.
: Est en alguna cola de espera para ser ejecutado.

SONPROC

: Estado en el cual el proceso se est ejecutando.

SSLEEP

: Est en alguna cola de sleep, dormido.

Estados de un proceso :

Alberto Navarro Ezquerro Pag

57

Programacin de Sistemas

SZOMB

NULL

exit()
sleep
SONPROC
pswitch()

preempt()

SSLEEP

wakeprocs()

SRUN

fork

Alberto Navarro Ezquerro Pag

58

Programacin de Sistemas

TEMA 9 : MECANISMOS IPCS


Introduccin
Los mecanismos IPCS (interprocess communication mechanisms system) permiten
comunicar procesos no relacionados. Existen tres mecanismos : los semforos, que van permitir
sincronizar procesos ; los segmentos de memoria compartida, que van a permitir que los
procesos compartan su espacio de direcciones virtuales ; y las colas de mensajes, que posibilitan
el intercambio de datos con un formato determinado.
Estos mecanismos estn implementados como una unidad y comparten caractersticas
comunes que pasamos a describir :
Cada mecanismo cuando se crea, se dice que ha generado un canal IPCS. El
administrador determina el nmero mximo de mecanismos que se pueden generar
simultneamente. El siguiente grfico muestra la apertura de un canal IPCS :
Devolver id
No
key = = IPC_PRIVATE

Si

Estn llenas las


tablas del sistema ?

No
Existe la clave key_t ?

Si

errno = ENOSPC

Si
No

Est activo el bit


IPC_CREAT ?

No

errno = ENOENT

Si
Estn activados
IPC_CREAT e IPC_EXCL ?

Si

errno = EEXIST

No
Permisos correctos ?

No

errno = EACCESS

Si
Devolver id

Alberto Navarro Ezquerro Pag

59

Programacin de Sistemas

Todo mecanismo est definido por un descriptor. Con rdenes del tipo xxxget se crean
los mecanismos.
descriptor xxxget (clave, permisos)
Si ya est creado el mecanismo te devuelve su descriptor con lo cual te conectas a l.
Dentro de los parmetros de esta llamada se incluye una clave o llave y una mscara de
flags. El kernel busca algn mecanismo ya creado con esa clave. Si la llave toma el valor
IPC_PRIVATE me asegura la privacidad de la clave y que ninguna otra llamada a
xxxget va a poder devolver esa entrada.
Si dentro de la mscara de flags est activo el bit IPC_CREAT, el kernel crea una nueva
entrada en caso de que no haya ninguna que responda a la clave suministrada. Si, adems
de IPC_CREAT, est activo el bit IPC_EXCL, el kernel devuelve un error en caso de
que exista una entrada para la clave suministrada.
Primitivas :
Includes
Creacin o Apertura
Opr. de Control
Opr. de Comunicacin

Colas de Mensajes
sys/msg.h
msgget
msgctl
msgsnd msgrcv

Semforos
sys/sem.h
semget
semctl
semop

Memoria Compartida
sys/shm.h
shmget
shmctl
shmat shmdt

Formacin de claves
Una clave es una variable o constante del tipo key_t que vamos a usar para acceder a los
mecanismos IPC previamente creados o para crear otros nuevos. Hay mltiples formas de crear
claves, una de ellas es mediante la siguiente funcin :
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok (char *camino, int idproyecto)
Ftok devuelve una clave basada en el camino de un fichero y en un id que identifica el
proyecto.
Control de los mecanismos IPC desde la lnea de rdenes
Para ello existen dos rdenes :
$ ipcs [ opciones ]

Alberto Navarro Ezquerro Pag

60

Programacin de Sistemas

Si no se especfica ninguna opcin , ipcs muestra un resumen de la informacin


administrativa que se almacena para los semforos, memoria compartida y colas de mensajes que
hay asignados.
$ ipcrm [ opciones ]
Sirve para borrar un mecanismo.
Semforos
Es una herramienta dirigida al sincronismo entre procesos. Es un mecanismo para prevenir
la colisin que se produce cuando dos o ms procesos solicitan simultneamente el uso de un
recurso que deben compartir.
Todo semforo puede aceptar valores nulos o positivos. Se crean por racimos de semforos.
La cantidad mxima de semforos en un racimo es SEMMSL. Y el valor mximo que puede
tomar un semforo es SEMVMX.
Para cada conjunto de semforos el kernel mantiene una estructura semid_ds definida en
<sys/sem.h> :
struct semid_ds
{ struct ipc_perm
struct sem
ushort
time_t
long
time_t
long
long
}

sem_perm ;
*sem_base ;
sem_nsems ;
sem_otime ;
sem_pad1 ;
sem_ctime ;
sem_pad2 ;
sem_pad3[4] ;

Estructura de permisos
Puntero al primer semforo
Nmero de semforos en el racimo
Hora de la ltima opr. realizada sobre el semforo
Vaco.
Hora de la ltima modificacin
Vaco
Vaco

struct sem
{ ushort
pid_t
ushort
ushort
}

semval ;
sempid ;
semncnt ;
semzcnt ;

Valor del semforo


Pid del ltimo proceso que cambio el semforo
N de procesos en espera de que semval > 0
N de procesos en espera de que semval = 0

Funciones relacionadas con los semforos

Alberto Navarro Ezquerro Pag

61

Programacin de Sistemas

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

int semget (key_t key, int nsems, int semflag)


Permite crear y/o acceder a un conjunto de semforos. Key es la clave o llave que indica a
que grupo de semforos queremos acceder de manera que si key toma el valor IPC_PRIVATE la
llamada crea un nuevo identificador. Nsems indica el nmero de semforos en el conjunto y
semflag es una mscara de bits de indica el modo de adquisicin del conjunto de semforos, los
valores posibles son :
0400 : Permiso de lectura para usuario
0200 : Permiso de modificacin para usuario
0040 : Permiso de lectura para grupo
0020 : Permiso de modificacin para grupo
0004 : Permiso de lectura para otros
0002 : Permiso de modificacin para otros
Junto a los anteriores valores se pueden incluir :
IPC_CREAT: Para crear el grupo de semforos de manera que si el grupo ya existe
se retorna el descriptor de grupo que corresponda.
IPC_EXCL
: Se puede usar combinado con el anterior de manera que si el grupo ya
existe la llamada retorne -1 y errno tome el valor EEXIST.

int semop (int semid, struct sembuf *sops, unsigned nsops)

Permite esperar a que un semforo tome un valor determinado, incrementar un semforo y


esperar q que valga 0. Semid es el identificador del grupo de semforos que nos retorn semget().
Sops es la direccin de comienzo del racimo. Nsops nmero de semforos.
struct sembuf
{ short sem_num ; Nmero de semforos dentro del grupo, el primero es 0
short sem_op ;
Operacin a realizar sobre el semforo
short sem_flg ;
Flags de la operacin a realizar
}
Los posibles valores de sem_op son :
semop < 0 : El proceso se queda suspendido hasta que el semforo tome un valor mayor
o igual que el valor absoluto de semop.
semop > 0 : El proceso le suma al semforo esa cantidad
semop = 0 : Queda suspendido hasta que valga 0
Los posibles valores de sem_flg son :
Alberto Navarro Ezquerro Pag

62

Programacin de Sistemas

IPC_NOWAIT : El proceso no espera ningn cambio y devuelve -1.


SEM_UNDO : Restituir los valores de un semforo que ha sido cerrado a otros
procesos porque el proceso que lo modific ha muerto.

int semctl (int semid, int semnum, int orden, union semun arg)
Permite acceder a informacin administrativa y de control sobre un semforo o un conjunto
de ellos. Semid es el identificador de un grupo de semforos obtenido con una llamada semget().
Sennum es el nmero del semforo del conjunto al que queremos acceder. Orden es la operacin
de control a realizar sobre el semforo, sus posibles valores son :
No necesitan permisos :
GETVAL
SETVAL
GETPID

: Devuelve el valor entero del semforo.


: Poner un valor al semforo que va en arg.
: Devolver el pid del ltimo semforo que realiz un operacin
sobre ese semforo del racimo.
GETZCNT : Devuelve cuantos procesos estn esperando a que valga 0.
GETNCNT : N de procesos que estn esperando a que tenga un valor mayor
igual que al actual.
GETALL
: Devuelve el valor de todos los valores del racimo en arg.
Necesita permiso de alteracin :
SETALL
: Inicializa todo el racimo con arg.
Necesita permiso de lectura :
IPC_STAT : Recupera la informacin de estado de todos.
IPC_SET : Modificar los atributos de estado de todos.
IPC_RMID : Borrar el racimo
Arg se emplea en funcin de cmd y su formato es :
union semun
{ int
struct semid_ds
ushort
}

val ;
*buf ;

Usado por SETVAL


Usado por IPC_STAT y IPC_SET
*array ;
Usado por GETALL y SETALL

Colas de mensajes

Alberto Navarro Ezquerro Pag

63

Programacin de Sistemas

Una cola es una estructura de datos gestionada por el kernel, donde vana poder leer y/o
escribir varios procesos de forma sincronizada. Al contrario que con las tuberas, no es necesario
que exista un proceso en espera de leer los datos para que otro pueda enviar un mensaje a la cola.
Tiene ventajas respecto a las listas enlazadas ya que las operaciones de creacin son atmicas y
las colas de mensajes son heterogneas. Los mensajes no se pueden leer dos veces. Para cada cola
de mensajes el kernel mantiene la siguiente estructura :
struct msqid_ds
{ struct ipc_perm
struct msg
struct msg
ulong
ulong
}

msg_perm ;
*msg_first ;
*msg_last ;
msg_cbytes ;
msg_qbytes ;

struct msg
{ struct msg
long
ushort
ushort
}

*msg_next ; Puntero al siguiente mensaje


msg_type ;
Tipo del mensaje
msg_ts ;
Nmero de bytes del mensaje
msg_spot ;
Direccin del buffer de datos del mensaje

Permisos asociados a la cola


Puntero al primer mensaje de la cola
Puntero al ltimo mensaje de la cola
Nmero de bytes de la cola
N mximo de bytes que puede haber en la cola

Funciones relacionadas con las colas de mensajes


#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget (key_t key, int msgflg)

Permite crear o acceder a una cola de mensajes. Si la llamada funciona devuelve un


identificador de la cola creada, en caso contrario devuelve -1. Key es una clave con el mismo
significado que en los semforos al igual que msgflg.

int msgctl (int msqid, int orden, struct msqid_ds *buf)

Alberto Navarro Ezquerro Pag

64

Programacin de Sistemas

Permite leer y modificar la informacin estadstica de una cola de mensajes. Cmd es el tipo
de operacin, sus posibles valores son :
IPC_STAT
IPC_SET
IPC_RMID

: Lee el estado de la estructura de control de la cola y lo devuelve en buf.


: Inicializa los campos de control de la cola a partir de los valores de buf.
: Borra la cola de mensajes. Si est siendo utilizada el borrado no se hace
efectivo hasta todos los procesos terminan su ejecucin.

int msgsnd (int msqid, struct msgbuf *msgp, int msgsz, int msgflg)
int msgrcv (int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg)
Permiten enviar y recibir mensajes de una cola determinada. El proceso deber tener
permiso de lectura o escritura en dicha cola. En ambas msqid es el identificador de la cola, msgp
apunta al buffer de datos definido por el usuario que vamos a enviar o revibir. El primer campo de
dicho buffer debe ser de tipo long e identifica el tipo del mensaje. Msgz es el tamao en bytes del
mensaje, donde no se incluye el campo tipo.
Msgtyp slo aparece en la llamada de lectura y especifica el tipo de mensaje que queremos
leer. Puede tomar los siguientes valores :
msgtyp = 0 Lee el primer mensaje que haya en la cola
msgtyp < 0 Lee el primer mensaje cuyo tipo es menor o igual que el valor absoluto de
msgtyp y a la vez sea el ms pequeo de los que hay.
msgtyp > 0 Lee el primer mensaje de tipo msgtyp.
Msgflg es un mapa de bits y tiene distintos significados segn aparezca en la llamada de
lectura o de escritura. En la llamada de lectura :
Si msgflg es 0 el proceso permanecer bloqueado hasta que se enve el mensaje (si la
cola est llena), mientras que si toma el valor IPC_NOWAIT el proceso no esperar
y la funcin retornar -1.
En la llamada de escritura :
Si en la cola no hay ningn mensaje del tipo msgtyp y est activo el flag
IPC_NOWAIT la funcin retorna inmediatamente con el valor -1. Si este flag no
est activo el proceso suspende su ejecucin en espera de que haya un mensaje del
tipo deseado.
Si se activa el flag MSG_NOERROR y el mensaje es ms largo que msgsz lo trunca y
no retorna error.
Si se ejecutan bien, msgsnd() retorna 0 y msgrcv() el total de bytes que realmente ha escrito
en el buffer msgp. Si las llamadas fallan, retornan -1.
El formato de struct msgbuf es :
struct msgbuf
Alberto Navarro Ezquerro Pag

65

Programacin de Sistemas

{ long mtype ;
char mtext[x] ;
}

Tipo del mensaje, debe ser > 0


Mensaje (MSGMAX : tamao mximo del mensaje)

Segmentos de memoria compartida


Es la tcnica ms rpida. Permite a dos o ms procesos compartir reas de memoria virtual
(El hecho de que la memoria sea virtual significa que sus direcciones fsicas asociadas podrn
variar con el tiempo ; lo que no va a generar ningn problema ya que los procesos no generan
direcciones fsicas, sino virtuales, y es el kernel el encargado de traducir de unas a otras). El
conjunto de pginas que forman el segmento que se va a compartir se denominan pginas
annimas.
Cuando un proceso se conecta a un segmento de memoria se amplia su rea de datos de
usuario. Para cada uno de los segmentos el kernel mantiene una estructura :
struct shmid_ds
{ struct ipc_perm
int
struct anon_map
ushort
pid_t
pid_t
ulong
time_t
time_t
time_t
}

shm_perm ;
shm_segsz ;
*shm_amp ;
shm_lkcnt ;
shm_lpid ;
shm_cpid ;
shm_nattch ;
shm_atime ;
shm_dtime ;
shm_ctime ;

Estructura con los permisos


Tamao del segmento en bytes
Puntero a la estructura de pg annimas del segmento
Nmero de bloqueos
Pid del proceso que realiz la ltima operacin
Pid del creador del segmento
Nmero de procesos conectados al segmento
Fecha de la ltima unin al segmento
Fecha de la ltima separacin al segmento
Fecha de la ltima modificacin al segmento

Alberto Navarro Ezquerro Pag

66

Programacin de Sistemas

Funciones relacionadas con los segmentos de memoria compartida


#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget (key_t key, int size, int shmflg)
Permite crear o acceder al segmento de memoria. Key es una clave con el mismo significado
que en los semforos al igual que shmflg. Opcionalmente, se puede especificar los siguientes
cdigos en shmflg :
IPC_CREAT
IPC_EXL

: Crea el segmento de memoria en caso de que no exista.


: Se puede utilizar combinado con el anterior de manera que si el
segmento ya existe la llamada devolver error.

int shmctl (int shmid, int orden, struct shmid_ds *buf)


Permite realizar operaciones de control sobre en segmento de memoria compartida. Cmd es
el tipo de operacin, sus posibles valores son :
IPC_STAT
IPC_SET
IPC_RMID

: Lee el estado de la estructura de control del seg. y lo devuelve en buf.


: Inicializa los campos de control del segmento a partir de buf.
: Borra la cola de mensajes. Si est siendo utilizada el borrado no se hace
efectivo hasta todos los procesos terminan su ejecucin.
SHM_LOCK
: Bloquea en memoria el segmento. Esto significa que no se va a realizar
swapping sobre l. Slo los procesos con el uid efectivo igual al del
superusuario podrn realizarlo.
SHM_UNLOCK : Desbloquea el segmento. Slo los procesos con el uid efectivo igual al
del superusuario podrn realizarlo.

int shmat (int shmid, void *shmaddr, int shmflg)


int shmdt (void *shmaddr)

La llamada shmat() permite conectar el segmento creado con shmget al espacio de


direccionamiento del proceso. La llamada shmdt() nos permite desconectarnos pasndole la
direccin devuelta por shmat(). En cualquier caso cuando un proceso termina su ejecucin el
segmento de desconecta automticamente. El campo shmflg indica la forma de acceso a la
memoria y puede tomar el siguiente valor :

Alberto Navarro Ezquerro Pag

67

Programacin de Sistemas

SHM_RDONLY : La memoria ser slo accesible para leer. Por defecto el segmento se
conecta para lec/esc (dando valor 0 al parmetro)

Alberto Navarro Ezquerro Pag

68

Das könnte Ihnen auch gefallen