Publicado el 31 de Julio del 2019
471 visualizaciones desde el 31 de Julio del 2019
1,7 MB
18 paginas
Creado hace 8a (21/01/2016)
Programación de Sistemas
Sistema de Archivo de UNIX
Prof: Sergio Bemposta
Dpto: DACA - ESI - ESP
Universidad Europea de Madrid
Indice
Llamadas para el manejo de archivos
Llamadas para el manejo de directorios
Acceso a los atributos de un archivo
Bloqueo de archivos
Redireccionamiento
Pag: 2
1
Llamadas al sistema para el manejo de archivos:
Abrir un fichero
int open(const char *pathname, int flags, [mode_t mode]);
• La llamada devuelve un descriptor de fichero o -1 si se produce un error.
Pathname es el nombre del fichero
•
flags puede ser una combinación OR de cómo se quiere abrir el fichero:
O_RDONLY
Solo lectura
O_WRONLY
Solo escritura
O_RDWR
Lectura/escritura
O_CREAT
Crea el fichero si no existe
O_EXCL
Falla si el fichero ya existe
O_TRUNC
Trunca el fichero a longitud 0
O_APPEND
Se añade por el final
• mode parámetro opcional e indica los permisos de acceso cuando se
crea
Pag: 3
Llamadas al sistema para el manejo de archivos:
Permisos en UNIX
En UNIX, un archivo tiene unos permisos de (lectura,
escritura, ejecución)
Además, un usuario pertenece como mínimo, a un
grupo. Esto nos permite dar permisos al grupo y al
resto de los usuarios de la maquina.
Los permisos se especifican en un numero de 9 bits tal
como se muestra en el cuadro.
rwx
rwx
rwx
usuario
grupo
Resto
Los permisos se junta en grupos de 3 bits: un bit
puesto a 1 activa el permiso correspondiente y lo
desactiva si está puesto a 0.
Pag: 4
2
Llamadas al sistema para el manejo de archivos:
Permisos en UNIX
Por tener grupos de 3 bits, un numero de 3 bits en
octal tiene la misma representación en decimal.
rw-r-- r-- equivale a 110 100 100 y en octal es 0644.
Ejemplo
• Se abre el archivo data.dat en modo solo lectura: Si el
fichero ya existe, se trunca su tamaño a 0 bytes y si no
existe, se crea con el permiso de rw- --- ---
int df;
df = open("data.dat", O_CREAT|O_WRONLY|O_TRUNC, 0600);
if( df == -1)
exit(-1);
Pag: 5
Llamadas al sistema para el manejo de archivos:
Lectura y Escritura.
ssize_t read(int fd, void *buf, size_t n_bytes);
Lee del fd y devuelve el número de bytes leídos o -1 si se produce un
error.
Los bytes leídos se guardan en el buffer apuntado por buf. Este
buffer tiene que tener espacio suficiente para albergar los datos
leidos.
Cuando se leen menos de los bytes especificados, es que se ha
llegado al final del archivo.
Ejemplo: Si el fichero tiene 25 bytes e intentamos leer 100, read()
nos devuelve 25.
ssize_t write(int fd, void *buf, size_t n_bytes);
Escribe en un fichero el contenido de una cadena de caracteres
apuntada por el puntero buf y devuelve el número de bytes escritos o
-1 si se produce un error.
Pag: 6
3
Ejemplo: Copia de 200 bytes
char buffer[200]; //Buffer intermedio
int df1, df2, nbytes;
if (df1 = open("file1", O_RDONLY)== -1){
perror(“file1”);
exit(1)
}
if (df2 = open("file2", O_WRONLY) == -1){
perror(“file1”);
exit(1)
}
if( nbytes = read(df1, buffer, sizeof(buffer)) == -1)
perror(“error lectura”)
exit(1);
}
if( nbytes = write(df2, buffer, sizeof(buffer)) ==-1)
perror(“error lectura”)
exit(1);
}
Pag: 7
Ejemplo: Detectar el final de un archivo
#define MAX 100
size_t nbytes;
char buf[20];
// Para almacenar 20 bytes
nbytes = read(fd, buf, MAX);
if (nbytes < MAX )
printf(“Final del Archivo");
Pag: 8
4
Llamadas al sistema para el manejo de archivos:
Acceso Aleatorio
Todo fichero tiene un puntero que marca la última posición de
lectura.
Se puede colocar el cursor en cualquier posición del fichero
antes de efectuar las operaciones de lectura o escritura.
long lseek (int df, long offset, int origen);
La función lseek devuelve un entero largo que indica la
posición absoluta del puntero del archivo o -1 en caso de
error.
• offset Es un entero que especifica de cuántos bytes hay que
mover el cursor con respecto del punto indicado por el parámetro
origen.
SEEK_SET
Origen del fichero
SEEK_CUR
Posición actual
SEEK_END
Final del fichero
Ejemplo: Leer 20 bytes a partir de la
posición 200 en un fichero.
int pos = 200;
int leidos, nbytes = 20;
char texto [25];
// Coloca el puntero en la posición pos
lseek(df, pos, SEEK_SET);
// leer datos
leidos = read(df, texto, nbytes);
Pag: 9
Pag: 10
5
Llamadas al sistema para el manejo de archivos:
Creación de enlaces.
Enlaces duros
• Las funciones para crear y eliminar enlaces duros (hard links)
int link(const char *f_original, const char *f_enlace);
int unlink(const char *pathname);
• Solo el superusuario puede crear un enlace duro que apunta a un
directorio.
• unlink() no borra necesariamente el fichero original. Sino
descuenta el contador del enlaces, y solo se borra, cuando el
contador llega a cero.
Enlace simbólico.
int symlink(const char *camino, const char *enlace);
• Se crea una nueva entrada de directorio que apunta a camino
Pag: 11
Llamadas al sistema para el manejo de archivos:
Otras funciones.
Descarga de datos al disco.
• El sistema puede mantener los datos en memoria
o bufferes intermedios, varios segundos antes de
que sean volcados a disco.
• Para asegurar la escritura a disco, hay que
invocar a las llamadas sync o fsync que descarga
los datos pendientes a disco
int fsync(int fd);
• Desgarga los datos de un ficheros concreto.
int sync(void);
• Descarga todos los datos pendientes de todos los
archivos abiertos.
Pag: 12
6
Llamadas al sistema para el manejo de archivos:
Otras funciones.
Truncar el contenido de un archivo.
int ftruncate(int fd, size_t tamaño);
• Trunca el contenido de un fichero abierto al
tamaño especificado.
int truncate(char *path, size_t tamaño);
• Trunca el contenido de un fichero en disco al
tamaño especificado. En este caso, no hace
falta abrir el archivo.
Pag: 13
Manejo de directorios:
Abrir un directorio.
Para leer su contenido, hay que abrirlo y leer las
entradas de una en una.
Un directorio se maneja a través de un puntero de tipo
DIR que es una estructura para el control de los
directorios.
DIR *opendir(char *path);
• path es nombre del directorio que se quiere abrir.
• La llamada devuelve un puntero al directorio en caso de
éxito y NULL en caso de error.
// Ejemplo de apertura de un directorio
DIR *pd ;
pd = opendir(“/home/alumno”);
if(pd == NULL)
Pag: 14
7
Manejo de directorios:
Leer el contenido de un directorio.
Para leer las entradas de un directorio, se utiliza la función
struct dirent *readdir(DIR *dirp);
Esta función devuelve un puntero a una estructura de tipo dirent (dir-
entry) que tiene un campo que es el nombre de la entrada leída.
struct dirent {
ino_t d_ino;
// Nodo-i de la entrada
short d_namlen;
// Longitud del nombre
char d_name[MAXNAMELEN + 1] // Nombre
};
La función devuelve una entrada del directorio o NULL en caso de
error.
Pag: 15
Manejo de directorios:
Leer el contenido de un directorio.
Ejemplo de lectura de una entrada de un directorio:
DIR *pd ;
struct dirent *entrada;
pd = opendir(“/home/alumno”);
if (pd == NULL)
exit(-1);
entrada = readdir(pd);
printf(“Nombre de la entrada: %s \n”,entrada->d_name);
//Leer una entrada.
Para leer el contenido de todo el directorio, hay que leerlo
dentro de un bucle hasta llegar al final del directorio. Es decir,
cuando la función nos devuelve NULL.
Pag: 16
8
Manejo de directorios:
Otras llamadas.
Otras llamadas para el manejo de directorios.
Crear un directorio
int mkdir(char *path, mode_t mode);
Borrar un directorio
int rmdir(char *path);
• El directorio se borra, siempre que esté vacío y que no sea
el directorio de trabajo de ningún proceso
Cambiar de directorio
int chdir(char *path);
Rebobinar un directorio
int rewinddir(DIR *dir);
Pag: 17
Manejo de directorios:
Otras llamadas.
situar el puntero de lectura de un directorio
en la posición pos.
int seekdir(DIR *dir, int pos);
Devuelve la posición del cursor de lectura
del directorio
long telldir(DIR *dir);
Cerrar un directorio.
int closedir(DIR *dir);
Pag: 18
9
Acceso a los atributos de un fichero.
Los archivos tienen unos atributos que se pueden consultar.
La información que se mantiene es del tipo de la estructura
<sys/stat.h>
struct stat
{
st_dev; /*device(major and minor numbers)*/
st_ino; /* inode */
st_mode; /* protection and type of file */
/* number of hard links */
dev_t
ino_t
mode_t
nlink_t st_nlink
uid_t
gid_t
dev_t
off_t
unsigned st_blksize; /* blocksize for filesystem */
unsigned st_blocks; /* number of blocks allocated */
time_t
time_t
st_uid; /* user ID of owner */
st_gid; /* group ID of owner */
st_rdev; /* device type (if inode device) */
st_size; /* total size, in bytes */
st_atime; /* time of last access */
st_mtime; /* time of last modification */
};
Pag: 19
Acceso a los atributos de un fichero.
Las llamadas para el manejo de ésta información son:
int stat(const char *pathname, struct stat *buf);
int fstat(int filedes, struct stat *buf);
int lstat(const char *pathname, struct stat *buf);
stat() devuelve una estructura de información de un fichero
fstat() hace lo mismo para un fichero abierto
lstat() es para enlaces simbólicos. Si se llama a stat() con un
enlace simbólico se devuelve la información del fichero al que
apunta el enlace, pero no al enlace mismo.
El comando ls –l es un comando que utiliza la llamada stat()
Pag: 20
10
Acceso a los atributos de un fichero:
Ejemplo de uso: Tipo de archivo
El campo st_mode es una mascara de bits que determina el tipo de archivo;
(regular, directorio, un fifo, un enlace, …)
Existe una serie de macros que nos permiten chequear el tipo
• S_ISDIR()
Un directorio.
• S_ISREG()
Fichero Regular.
• S_ISFIFO()
Un FIFO.
• S_ISLNK()
Un enlace simbólico.
• S_ISCHR()
Disp
Comentarios de: Sistema de Archivo de UNIX - Programación de Sistemas (0)
No hay comentarios