Sistemas Operativos Práctica 3 Sesión 1 Curso 2005/2006 Sistemas operativos curso 2005/2006 1 DIRECTORIO Constituyen un tipo diferenciado de archivos dentro del sistema operativo Unix/Linux. ● La información que almacenan establece la correspondencia entre los nombres ● de los ficheros contenidos en el directorio y su número de inodo asociado. Este número nos permite acceder a la estructura inodo, que contiene la ● información referente al archivo en cuestión (propietario del archivo, permisos asociados, fecha de creación del archivo, tiempos de último acceso y modificación). La información se gestiona a través de unas estructuras de datos definidas en ● unos archivos de cabecera del sistema (.h), existentes en los directorios /usr/include y /usr/include/sys. Sistemas operativos curso 2005/2006 2 DIRECTORIO Manejaremos la biblioteca estándar de funciones de acceso a directorios y las llamadas al sistema que permite acceder a la información almacenada en la tabla de inodos sobre el estado de los archivos en concreto. opendir, closedir, readdir, scandir y seekdir. La información de los directorios esta estructurada, por lo tanto estas llamadas operan sobre una estructura de datos denominada DIR, cuya definición y descripción de sus campos se encuentra en el archivo de cabecera del sistema <dirent.h>. typedef struct __dirdesc{ int dd_fd; /*descriptor de archivo asociado al directorio*/ long dd_loc; /*offset en el buffer actual*/ long dd_size; /*número de datos devuelto por getdirentries*/ char dd_buf; /*buffer de datos*/ long dd_size; /*tamaño del buffer*/ } DIR; Sistemas operativos curso 2005/2006 3 DIRECTORIO opendir llamada para abrir un archivo de directorio DIR *opendir(char *dirname); dirname es una cadena que contiene el pathname del directorio al que se va a abrir. Devuelve un puntero a una estructura tipo DIR. Si se produce un error en la apertura del directorio devuelve NULL. closedir llamada para cerrar un archivo de directorio. int closedir (DIR *dirp) dirp es un puntero a una estructura previamente abierta. ejecución correcta devuelve 0, en caso contrario -1. readdir accedemos a las entradas de directorio que forman el archivo de directorio. struct dirent *readdir(DIR *dirp) dirp es un puntero a una estructura DIR previamente abierta. Sistemas operativos curso 2005/2006 4 DIRECTORIO Su funcionamiento correcto hace que readdir lea la entrada donde se encuentra situado el puntero de lectura de ese directorio, actualizando el puntero a la siguiente entrada. Lectura secuencial. Devuelve la entrada leída a través de un puntero a una estructura de tipo struct dirent definida en el archivo cabecera dirent.h. (al igual que la estructura DIR) typedef struct dirent { ino_t d_ino; /* Número de inode asociado a esa entrada */ short d_reclen; /* Longitud de la entrada al directorio */ short d_namlen; /* Longitud del string que hay en d_name */ char d_name[256]; /* Nombre del archivo */ }; Sistemas operativos curso 2005/2006 5 DIRECTORIO El manejo de punteros de acceso a los elementos del directorio se hace necesario para ofrecer toda la flexibilidad posible en el desarrollo de aplicaciones. Este manejo se realiza con las llamadas al sistema: seekdir posiciona el puntero de lectura en un elemento determinado del directorio. void seekdir(DIR *dir, off_t offset); telldir devuelve la posición actual. off_t telldir(DIR *dir); rewinddir reposiciona el puntero al principio del directorio. void rewinddir(DIR *dir); Sistemas operativos curso 2005/2006 6 stat, lstat y fstat Conocido el número de inodo asociado a un archivo, puede ser necesario acceder a la información contenida en el inodo. Para ello, se emplean las llamadas al sistema stat, lstat y fstat, las cuales devuelven la información almacenada en la tabla de inodos sobre el estado de un archivo concreto. La diferencia entre stat y lstat es que lstat devuelve el symlink y stat el archivo al que apunta symlink. La diferencia entre stat y fstat, es que la primera reciba como primer parámetro un puntero al path del archivo, mientras la segunda emplea un archivo ya abierto. La sintaxis de las llamadas son: int stat (const char *path, struct stat *buf) int lstat (const char *path, struct stat *buf) int fstat (int fildes, struct stat *buf) Sistemas operativos curso 2005/2006 7 Stat Estas llamadas devuelven la información almacenada en una estructura del tipo struct stat, la cual está definida en el archivo de cabecera <sys/stat.h> y cuyos tipos incluidos se definen en el archivo <sys/types.h> (normalmente como alias a tipos base como el short, int o long). Entre sus campos, el que indica el modo del archivo, contiene información heterogénea distribuida en sus bits. Para acceder a esa información existen un conjunto de constantes definidas en <sys/mode.h> que aplicadas mediante una operación and (&), sobre el campo correspondiente, devuelven la información requerida. Sus campos estándar se citan a continuación: Sistemas operativos curso 2005/2006 8 stat struct stat { dev_t st_dev; /* dispositivo */ ino_t st_ino; /* inodo */ mode_t st_mode; /* protección */ nlink_t st_nlink; /* número de enlaces duros */ uid_t st_uid; /* UID propietario */ gid_t st_gid; /* GID del nodo */ dev_t st_rdev; /* tipo de dispositivo */ off_t st_size; /* tamaño total en bytes */ blksize_t st_blksize; /* tamaño de bloque para la E/S */ blkcnt_t st_blocks; /* numero de bloques asignados */ time_t st_atime; /* último acceso */ time_t st_mtime; /* última modificación (fichero)*/ time_t st_ctime; /* última modificación (inodo) */ }; Sistemas operativos curso 2005/2006 9 Macros para el campo st_mode ● #define S_IFMT /* tipo de fichero */ – #define S_IFIFO /* named pipe (fifo) */ – #define S_IFCHR /* character */ – #define S_IFDIR /* directory*/ – #define S_IFBLK /* block */ – #define S_IFREG /* regular */ – #define S_IFLNK /* symbolic link */ – #define S_IFSOCK /* socket */ – #define S_IFWHT /* whiteout */ Macros para el cálculo del tipo de fichero. Se comparan con: st_mode & S_IFMT ● #define S_ISUID /* usuario */ ● #define S_ISGID /* grupo */ ● #define S_ISVTX /* para directorios, flag para restricción de eliminación */ ● #define S_IRWXU /* lectura, escritura y ejecución para propietario */ ● #define S_IRUSR /* propietario, permiso de lectura */ ● #define S_IWUSR /* propietario, permiso de escritura */ ● #define S_IXUSR /* propietario, permiso de ejecución */ Sistemas operativos curso 2005/2006 10 Macros para el campo st_mode #define S_IRWXG /* lectura, escritura y ejecución para grupo */ #define S_IRGRP /* grupo, permiso de lectura */ #define S_IWGRP /* grupo, permiso de escritura */ #define S_IXGRP /* grupo, permiso de ejecución */ #define S_IRWXO /* lectura, escritura y ejecución para el resto */ #define S_IROTH /* el resto, permiso de lectura */ #define S_IWOTH /* el resto, permiso de escritura */ #define S_IXOTH /* el resto, permiso de ejecución */ S_IRWXU = OR de S_IRUSR, S_IWUSR y S_IXUSR S_IRWXG = OR de S_IRGRP, S_IWGRP y S_IXGRP S_IRWXO = OR of S_IROTH, S_IWOTH y S_IXOTH Sistemas operativos curso 2005/2006 11 Ejemplo #include <stdio.h> #include <sys/stat.h> /* Para la estructura stat */ #include <unistd.h> main(int argc, char **argv) { struct stat buf; printf("%s\n",argv[0]); if ( stat(argv[0], &buf) == -1 ) { perror(argv[0]); exit(-1); } else { printf("Tamaño del archivo %s %d bytes.\n",argv [0],buf.st_size; } } Sistemas operativos curso 2005/2006 12