Publicado el 14 de Enero del 2017
771 visualizaciones desde el 14 de Enero del 2017
89,4 KB
29 paginas
Creado hace 25a (09/03/2000)
Sistemas Operativos II
T EM A 7
Programación en UNIX
Contenido
7.1. Introducción
7.2. Gestión de Errores
7.3. Gestión de Ficheros Regulares
7.3.1. Apertura de un fichero: open()
7.3.2. Lectura de datos de un fichero: read()
7.3.3. Escritura de datos en un fichero: write()
7.3.4. Cierre de un fichero: close()
7.3.5. Acceso aleatorio: lseek()
7.3.6. Duplicación de un descriptor: dup()/dup2()
7.3.7. Información sobre un fichero: stat()
7.3.8. Modificación del modo de un fichero: chmod()
7.3.9. Creación de enlaces: link()
7.3.10. Borrado de un fichero: unlink()
7.3.11. Operaciones sobre descriptores de fichero: fcntl()
7.4. Gestión de Directorios
7.4.1. Creación de un directorio: mknod(), mkdir()
7.4.2. Borrado de un directorio: rmdir()
7.4.3. Apertura de un directorio: opendir()
7.4.4. Lectura de un directorio: readdir()
7.4.5. Cierre de un directorio: closedir()
7.4.6. Cotrol del puntero de lectura de un directorio: seekdir(), telldir(), rewinddir()
7.5. Gestión de Procesos
7.5.1. Creación de un proceso: fork()
7.5.2. Obtención de identificadores: getuid(), getgid(), ...
7.5.3. Finalización de un proceso: exit()
7.5.4. Espera de terminación de un hijo: wait()
7.5.5. Ejecución de programas: exec()
7.6. Señales
7.6.1. EnvÃo de una señal: kill()
7.6.2. Tratamiento de una señal: signal()
7.7. Comunicación entre procesos
7.7.1. Creación de un pipe: pipe()
7.8. Referencias
7.9. Apendice 1: Programas ejemplo
7.9.1. Programa copy.c
7.9.2. Programa info.c
7.9.3. Programa padre_hijo.c
7.9.4. Programa pipe.c
7.9.5. Programa pipe_sh.c
7.9.6. Programa signal.c
Sistemas Operativos II
TEMA 7
PROGRAMACIÓN EN UNIX
7.1. Introducción
La programación en UNIX se basa en el uso de un conjunto de funciones que se denominan llamadas al
sistema. Éstas constituyen un conjunto básico de elementos que permiten construir programas que
pueden explotar los recursos del sistema. Mediante llamadas al sistema el programador puede:
q Utilizar el sistema de ficheros.
q Ejecutar varios procesos de forma concurrente.
q Comunicar y sincronizar procesos tanto de forma local como en red.
Las llamadas al sistema tienen un formato estándar, tanto en la documentación que suministra el
manual del sistema como en la forma de invocación. Por ejemplo, la llamada al sistema read() tiene el
siguiente formato:
int read(df, buf, contador)
int df ;
char *buf ;
int contador ;
La forma de uso de una llamada al sistema es idéntica a cualquier otra función del lenguaje C. La
mayorÃa de las llamadas devuelven un valor, que suele indicar si la operación se ha efectuado con éxito o
7.2. Gestión de Errores
Cuando se produce un error al realizar una llamada al sistema, ésta devuelve el valor -1. Todo proceso
contiene una variable global llamada errno, de manera que cuando una llamada al sistema termina de
forma satisfactoria, el valor de esta variable permanece inalterado, pero cuando la llamada falla, en errno
se almacena un código de error. errno no da información detallada sobre el error que se ha producido.
Por otro lado, existe una función, perror(), que describe los errores que se producen en las llamadas al
sistema.
void perror(cadena)
char *cadena ;
El siguiente programa muestra el uso de errno y perror(). En primer lugar se trata de abrir un
fichero que no existe y después se trata de abrir en modo escritura un fichero del que no se posee tal
permiso.
#include <stdio.h>
#include <sys/file.h>
#include <errno.h>
main()
{
int fd ;
fd = open("/asdaf", O_RDONLY) ;
if (fd == -1)
{
printf("errno = %d\n", errno) ;
perror("main") ;
}
if ((fd = open("/", O_WRONLY)) == -1)
{
_________________________________________________________________________________
___
TEMA 7. Programación en Unix
Pág. 1
Sistemas Operativos II
printf("errno = %d\n", errno) ;
perror("main") ;
}
}
7.3. Gestión de Ficheros Regulares
Cada proceso en UNIX dispone de 20 descriptores de ficheros, numerados de 0 a 19. Por convención, los
tres primeros descriptores se abren automáticamente cuando el proceso empieza su ejecución, y tienen un
significado especial:
q descriptor 0: entrada estándar
q descriptor 1: salida estándar
q descriptor 2: error estándar
Cada descriptor de fichero posee un conjunto de propiedades privadas y que no depende del tipo de
fichero que esté asociado al descriptor:
q Desplazamiento (offset) del fichero.
q Un indicador (flag) que indica si el descriptor se debe de cerrar de forma automática si el proceso
utiliza la llamada al sistema exec().
q Un indicador que indica si la salida hacia el fichero debe de añadirse al final del mismo.
Existe información adicional que tiene sentido si el fichero asociado al descriptor es un fichero
especial.
7.3.1. Apertura de un fichero: open()
int open (ruta, indicadores [,modo])
char *ruta ;
int indicadores ;
mode_t modo ;
- open() permite abrir o crear un fichero para lectura y/o escritura.
- ruta es el nombre de fichero a abrir y puede estar expresado en forma de direccionamiento absoluto o
relativo.
- indicadores es una máscara de bits, lo que significa que varias opciones pueden estar presentes
usando el operador lógido OR (|) a nivel de bits. Indica al kernel el modo de apertura del fichero.
- modo indica los permisos de acceso del fichero en el caso de que éste vaya a ser creado. Se expresa
octal.
Los indicadores de lectura/escritura son los siguientes:
q O_RDONLY
q O_WRONLY
q O_RDWR
Abrir para sólo lectura.
Abrir para sólo escritura.
Abrir para lectura/escritura.
esté
mode.
q O_EXCL
Otros indicadores son los siguientes:
q O_APPEND
q O_CREAT
El desplazamiento (offset) se sitúa al final del fichero.
No tiene efecto si el fichero existe, a no ser que el indicador O_EXCL
activo. Si el fichero no existe, se crea con los permisos indicados en
Si el indicador O_CREAT está presente, open() da un mensaje de error si el
fichero ya existe.
q O_TRUNC
Si el fichero existe trunca su longitud a cero bytes.
Ejemplos:
int fd ;
/*
* Abrir un fichero en modo sólo lectura
_________________________________________________________________________________
___
TEMA 7. Programación en Unix
Pág. 2
Sistemas Operativos II
*/
fd = open("datos", O_RDONLY) ;
/*
* Abrir un fichero en modo sólo escritura. Si el fichero existe,
truncar
* su tamaño a cero bytes. Si no existe, crearlo con permisos de
lectura
* y escritura para el propietario y ningun permiso para el grupo y el
* resto de los usuarios.
*/
fd = open("datos", O_WRONLY | O_TRUNC | O_CREAT, 0600) ;
7.3.2.
Lectura de datos de un fichero: read()
int read (df, buf, contador)
int df ;
char *buf ;
int contador ;
- read() copia contador bytes desde el fichero referenciado por df en el buffer apuntado por buf.
Si no existen errores, read() devuelve el número de bytes leÃdos y copiados en buf. Este número
será menor o igual que contador. Es cero si se intenta leer cuando se ha llegado al final del fichero.
- La llamada read() es de bajo nivel y no tiene las capacidades de formateo de datos de scanf()
buffers adicional de
la biblioteca de funciones de C, por lo que es muy rápida.
Ejemplos:
int fd, nbytes ;
char buf1[1024] ;
float buf2[20] ;
/*
* Leer en un buffer de 1024 caracteres.
*/
nbytes = read(fd, buf1, sizeof(buf1)) ;
/*
* Leer en un array de 20 elementos float.
*/
nbytes = read(fd, buf2, 20 * sizeof(float)) ;
7.3.3. Escritura de datos en un fichero: write()
int write (df, buf, contador)
int df ;
char *buf ;
int contador ;
- write() copia contador bytes desde el buffer apuntado por buf en el fichero referenciado por
df. Si no existen errores, write() devuelve el número de bytes escritos. Este número será menor o
igual que contador.
- La llamada write() es de bajo nivel y no tiene las capacidades de formateo de datos de
printf(). Tiene la ventaja de que no usa el sistema de buffers adicional de la biblioteca de
funciones de C, por lo que es muy rápida.
_________________________________________________________________________________
___
TEMA 7. Programación en Unix
Pág. 3
Sistemas Operativos II
Ejemplos:
int fd, nbytes ;
char *cadena = "Ejemplo de uso de write" ;
double num ;
/*
* Ejemplos de uso de la llamada write.
*/
nbytes = write(fd, cadena, strlen(cadena)) ;
nbytes = write(fd, &num, sizeof(double)) ;
_________________________________________________________________________________
___
TEMA 7. Programación en Unix
Pág. 4
Sistemas Operativos II
7.3.4. Cierre de un fichero: close()
int close (df)
int df ;
- close() libera un descriptor de fichero df y devuelve el valor 0. Si df era el último descriptor de
fichero asociado con un fichero abierto, el kernel libera los recursos asociados con ese fichero.
- Al cerrar un fichero, la entrada que ocupaba en la tabla de descriptores de ficheros del proceso queda
liberada y puede ser usada por una llamada a open().
- Si un proceso no cierra los ficheros que tiene abiertos, al terminar su ejecución el kernel los cierra.
Ejemplos:
int fd, err ;
/*
* Leer en un buffer de 1024 caracteres.
*/
err = close(fd) ;
7.3.5. Acceso aleatorio: lseek()
long lseek (df, desp, modo)
int df ;
int desp ;
int modo ;
- lseek() modifica el puntero de lectura/escritura (offset) asociado a df según el valor del parámetro
mode:
q SEEK_SET: el puntero avanza desp bytes con respecto al inicio del fichero.
q SEEK_CUR: el puntero avanza desp bytes con respecto a su posición actual.
q SEEK_END: el puntero avanza desp bytes con respecto al final del fichero.
- El puntero avanza hacia el final del fichero o hacia el principio dependiendo del signo de desp.
- En caso de fallo se devuelve -1, y en caso de éxito se devuelve un número entero no negativo que
presenta el nuevo desplazamiento del puntero de lectura/escritura con respecto al pr
Comentarios de: Sistemas Operativos II - Tema 7 - Programación en UNIX (0)
No hay comentarios