#include <fcntl.h> int creat (nombre, mode_t permisos); const char *nombre; mode_t permisos;
Si existe el fichero :
No modifica los permisos. Si tiene permiso de escritura borra el contenido, sino.. dara error.
Devuelve un entero:
Sino hay error: entre 0 y 19 (el descriptor del fichero). Devolver el mas bajo que este libre (no asociado)
Devuelve:
El nmero de caracteres que ha podido escribir (n_escritos).
Ejemplos:
int n_escritos, fprueba; fprueba =creat(fprueba,0666); n_escritos= write(fprueba,Esto es el dato del fichero\0,28); ## /0 = final de la cadena
O_RDONLY (0) El fichero se abre para lectura. El puntero en byte 0. O_WRONLY (1) El fichero se abre para escritura. Puntero en byte 0. O_RDWR (2) El fichero se abre en modo lectura/escritura O_CREAT Sino existe el fichero se crea. O_TRUNC Si existe se borra la informacin que contiene. O_EXCL Con O_CREAT la llamada falla si el fichero existe. O_APPEND El puntero del fichero apunta al final del mismo. Para activar varios modos a la vez se usa un OR. Ejemplos: fd=open(fichero,1|O_CREAT,0666);
fd=open(fichero,O_WRONLY|O_CREAT|O_TRUNC,0644);
Modos:
Hay que abrir previamente el fichero. El puntero del fichero queda indicando el siguiente byte a leer. Tras una operacin se avanza el puntero.
Devuelve:
El nmero de carcter ledo (puede ser menor que bytes si se ha alcanzado el final del fichero). -1 si ha ocurrido un error en la llamada. #include <stdio.h> #include <unistd.h> #include <fcntl.h> int main() { int fd, i, vector[10], dato, leidos; fd= creat(prueba,0600); for (i=0;i<10;i++) vector[i]; write(fd,vector,sizeof(vector)); close(fd); fd= open(prueba,O_RDONLY); while ((leidos= read(fd,&dato,sizeof(int)))>0) { printf(Leido el nmero %d\n,dato); } close(fd); exit(0); }
escribir en prueba de 0 a 9
#include <stdio.h> int main() { int i, j; if (fork()!=0) { for (i=0;i<100;i++) { for (j=0;j<100000;j++); printf(Proceso padre. Indice i=%d\n,i); } } else { for (i=0;i<100;i++) { for (j=0;j<100000;j++); printf(Proceso hijo. Indice i=%d\n,i); } } } exit(0);
execlp
#include <unistd.h> int execlp(fichero,arg0,arg1,arg2, , argN, (char *)0); const char *fichero; const char *arg0; const char *arg1; const char *arg2; . const char *argN;
execvp
#include <unistd.h> int execvp(fichero, argv); const char *fichero; const char *argv[];
Ejemplos :
execlp(ls,ls,-l,NULL);
execvp(ls,ls -l);
descriptor[1]: descriptor para escribir datos en la tubera. (al cerrar descriptor[1] se introduce un EOF) descriptor[0]: descriptor para leer datos de la tubera (en orden llegada)
Devuelve el nmero del nuevo descriptor duplicado (tendremos dos descriptores apuntando al mismo sitio): Utilizara el descriptor de fichero de nmero ms bajo para la copia.
Ejemplo 11:
#include <stdio.h>
int main() {int fichero, duplicado, i dato, salir; fichero= creat(fprueba,0644); for (i=0;i<10;i++) write(fichero,&i,sizeof(int)); close(fichero); printf(Ya se ha creado el fichero\n); fichero=open(fprueba,O_RDONLY); printf(Abierto el fichero sobre descriptor: %d\n,fichero); duplicado= dup(fichero); printf(Duplicado sobre descriptor: %d\n,duplicado); salir= FALSE; while (!salir) {salir= (read(fichero,&dato,sizeof(int))==0); if (!salir) {printf(dato leido mediante fichero = %d\n,dato); salir= (read(duplicado,&dato,sizeof(dato))==0); if (!salir) printf(dato leido mediante duplicado = %d\n,dato); else printf(Final de fichero encontrado en duplicado\n); } else printf(Final de fichero encontrado en fichero\n); } close(fichero); close(duplicado); exit(0); }
Gestin de ficheros y directorios: remove, rename, lseek, stat, mkdir, rmdir y chdir.
Borrar un fichero: remove. Sintaxis: #include <stdio.h>
int remove (Filename); const char *Filename;
Borra el fichero llamado Filename El fichero no se borrar si est abierto cuando se utiliza la llamada remove. Si el fichero tiene varios links (enlaces duros) la cuenta de estos desciende en uno. Devuelve: cero en caso de que se haya podido borrar el fichero.
un valor no nulo en caso contrario.
rename.
int rename (FromPath, ToPath); const char * FromPath, ToPath; FromPath identifica el fichero o directorio cuyo nombre se cambia. ToPath identifica el nuevo path. FromPath, ToPath deben ser ambos del mismo tipo (fich, o direc). Si ToPath es fichero o directorio vaco se reemplaza por FromPath. Si es directorio no vaco no cambia el nombre y da error.
-1 en caso de error. 0 en caso contrario.
Devuelve: Errores:
Por falta de permisos de ejecucin o de escritura en los directorios o ficheros oportunos.. etc Si algn parmetro est siendo usado al mismo tiempo por el sistema. Si ToPath es un directorio no vaco, FromPath es directorio y ToPath no FromPath es fichero y ToPath no.
lseek.
off_t lseek ( FileDescriptor, Offset, Whence) int FileDescriptor, Whence; off_t Offset; Posiciona el puntero de un fichero abierto cuyo descriptor sea FileDescriptor FileDescriptor. especifica el descriptor de un fichero abierto con la llamada open. Offset especifica el valor en bytes que se desplazar el puntero. Un valor negativo mueve en direccin inversa. El valor de offset est limitado por OFF_MAX. Whence especifica como unterpretar Offset para mover el puntero del fichero especificado por FileDescriptor. Ser uno de los valores q estn definidos en el fichero /usr/include/unistd.h:
SEEK_SET ( 0) Mueve el puntero a la posicion indicada por Offset. SEEK_CUR ( 1) El Offset se usa como desplazamiento relativo desde la posicin actual del puntero. La posicion final del puntero ser (actual + Offset). SEEK_END ( 2) El Offset se usa como desplazamiento relativo desde el final del fichero. La posicin final del puntero ser (final de fichero + Offset).
Devuelve: Errores:
- Devuelve la localizacion final del puntero en bytes medida desde el inicio del fichero. - Devuelve -1 en caso de error. .
Si FileDescriptor no corresponde a un fichero abierto. Si FileDescriptor corresponde a una tubera abierta. Si el offset sobrepasa el lmite permitido definido en OFF_MAX. En el fichero /usr/include/unistd.h estn definidos los macros, tipos y subrutinas.
Obtiene informacin referente a un fichero: stat. /* Path especifica el nombre del fichero */ Sintaxis: #include <sys/stat.h>
int stat ( Path, Buffer ) const char *Path; struct stat *Buffer; /* Buffer es un puntero a la estructura stat en el q se devuelve la informacin */ /* No son necesarios permisos de lectura, escritura o ejecucin para el fichero */
En la ruta del Path todos los directorios deben tener permisos de ejecucin. Detallamos aqu slo los campos de la estructura stat ms importantes. struct stat { dev_t st_dev; /* Dispositivo de ubicacin del i_nodo */ ino_t st_ino; /* Nmero de i_nodo */ mode_t st_mode; /* Bits que indican tipo de fichero y permisos, en octal */ nlink_t st_nlink; /* Nmero de enlaces al fichero */ uid_t st_uid; /* UID del propietario */ gid_t st_gid; /* GID del propietario */ off_t st_size; /* Tamao del archivo en caracteres o bytes */ time_t st_atime; /* Tiempo de ltimo acceso */ time_t st_mtime; /* Tiempo de ltima modificacin */ time_t st_ctime; /* Tiempo de ltimo cambio en el i_nodo */ } La estructura stat definida en ---> fichero /usr/include/sys/stat.h (mode.h en abubis) man 2 stat Los tipos de datos estn definidos en el fichero /usr/include/sys/types.h. El campo st_mode viene representado por un nmero en octal de 6 dgitos Digto1) nmero octal que representa los permisos de otros sobre el fichero. Digto2) nmero octal que representa los permisos de grupo sobre el fichero. Digto3) nmero octal que representa permisos de usuario sobre el fichero. Para averiguar los permisos se pueden utilizar las siguientes mscaras de bits (valores en octal) que se encuentran definidas en los diferentes ficheros que se incluyen al usar la llamada stat.
#define #define #define #define #define #define #define #define #define #define #define #define S_IRWXU S_IRUSR S_IWUSR S_IXUSR S_IRWXG S_IRGRP S_IWGRP S_IXGRP S_IRWXO S_IROTH S_IWOTH S_IXOTH 0000700 0000400 0000200 0000100 0000070 0000040 0000020 0000010 0000007 0000004 0000002 0000001 /* /* /* /* /* /* /* /* /* /* /* /* read,write,execute perm: owner */ read permission: owner */ write permission: owner */ execute/search permission: owner */ read,write,execute perm: group */ read permission: group */ write permission: group */ execute/search permission: group */ read,write,execute perm: other */ read permission: other */ write permission: other */ execute/search permission: other */
Digto 4) No lo usaremos. Digto5 y 6) Contiene el tipo de fichero. usaremos las mascaras de bits (valores en octal) que se encuentran definidas en los diferentes ficheros que se incluyen al usar la llamada stat.
#define #define #define #define #define #define S_IFMT S_IFREG S_IFDIR S_IFBLK S_IFCHR S_IFIFO 0170000 0100000 0040000 0060000 0020000 0010000 /* type of file */ /* regular */ /* directory */ /* block special */ /* character special */ /* fifo */
Para conocer un campo de la estructura stat se pueden utilizar mscaras junto con la operacion & (se trata de un AND bit a bit) o usar macros. para ver si un nombre q pasamos como primer argumento al programa es un fichero regular, tendramos que poner almenos las siguientes lneas de programa { struct stat campo; ..... stat(argv[1], &campo); if ( ( ( 0100000)&(campo.st_mode) ) = = (0100000) ) printf(%s es un fichero regular \n, argv[1] ); else printf(%s no es un fichero regular \n, argv[1] ); }
la linea if anteior = utilizar nombre dado para la mascara 0100000 en el fichero /usr/include/sys/stat.h if ( ( (S_IFREG)&(campo.st_mode) ) = = (S_IFREG) ) printf(%s es un fichero regular \n, argv[1] ); else printf(%s no es un fichero regular \n, argv[1] ); o utilizando la macro denominada S_ISREG(m) del fichero /usr/include/sys/stat.h (mode.h en anubis) if ( S_ISREG ( campo.st_mode ) ) printf(%s es un fichero regular \n, argv[1] ); else printf(%s no es un fichero regular \n, argv[1] ); Las macros definidas son: S_ISFIFO(m) tipo de fichero fifo S_ISDIR(m) tipo de fichero directorio S_ISCHR(m) tipo de fichero de caracteres especiales S_ISBLK(m) tipo de fichero de bloques especiales S_ISREG(m) tipo de fichero regular
Crea un directorio:
mkdir.
/* Path = nombre del nuevo directorio */ /* Mode = permisos del nuevo directorio (valores en octal) */
#include <stdio.h> int mkdir (Path, Mode); const char * Path; mode_t Mode;
rmdir.
/* Path = nombre del directorio a borrar, requiere permiso de escritura) */
Errores: El directorio no est vaco. El directorio se refiere a un punto en el que hay montado un dispositivo. Cambiar el directorio de trabajo:
#include <stdio.h> int chdir (Path); const char * Path;
chdir.
Errores:
Ejercicio 12.-En una base de datos (fichero llamado base) tenemos el formato q se describe a continuacin. Los registros (de 2 campos) son de longitud fija, 64 bytes. El primer campo tiene formato de numero entero (4 bytes) y almacena un entero q da la longitud del nombre acumulado en el segundo campo. El segundo campo contiene el nombre asociado (caracteres) seguido por caracteres basura hasta un total de 60 bytes. 8 Mercedes 6 Carlos 7 Julieta leer fichero base (base de datos) anterior e imprimir en pantalla 1 nombre en cada linea
#include <stdio.h> #include <unistd.h> #include <fcntl.h> main() { int fd, n, i, mueve, n_read, pos; dato, leidos; char dato[60]; fd= open(base, 0); /*abrir base para leer*/ n= lseek(fd, 0, 0); /*posicionar en primer dato*/ for (i=1;i<4;i++) /* recorrer cada registros { n_read=read(fd,&pos,sizeof(int)); /*leer primer entero*/ n_read=read(fd, dato, pos); /*leer nombre de tamao pos*/ dato[pos]= \0; /*fin de nombre leido*/ printf(%s\n, dato); /*imprimir nombre*/ mueve=64*i; /*puntero al siguiente registro*/ n=lseek(fd, mueve,0); } close(fd); /*cerrar fichero*/ }
Ejercicio 13.-Realizar un programa en C que usando la llamada al sistema stat, nos imprima en pantalla si el nombre que se pasa como argumento es un fichero o es un directorio. En caso de ser fichero debe tambin imprimir la siguiente informacin: -tamao del mismo -permisos que tenga habilitados -tiempo de la ultima modificacin (usar ctime) Ejemplo de ejecucin: pepe es fichero de tamao 512 bytes permiso de lectura para propietario permiso de escritura para propietario permiso de ejecucin para el grupo se modific en Tue Nov 9 18:26:38 2001
#include <stdio.h> #include <unistd.h> #include <time.h> main(argc, argv) int argc; char * argv[]; { struct stat campo; stat(argv[1], &campo); if (S_ISDIR(campo.st_mode)) printf(%s es un directorio\n, argv[1]); else if (S_ISREG(campo.st_mode)) { printf(%s es un fichero\n, argv[1]); printf(de tamao %d \n, campo.st_size);
/*PERMISOS PROPIETARIO*/
if (((S_IRUSR)&(campo.st_mode))= =(S_IRUSR)) printf(De lectura para el propietario\n); if (((S_IWUSR)&(campo.st_mode))= =(S_IWUSR)) printf(De escritura para el propietario\n); if (((S_IXUSR)&(campo.st_mode))= =(S_IXUSR)) printf(De ejecucin para el propietario\n);
/*PERMISOS GRUPO*/
if (((S_IRGRP)&(campo.st_mode))= =(S_IRGRP)) printf(De lectura para el grupo\n); if (((S_IWGRP)&(campo.st_mode))= =(S_IWGRP)) printf(De escritura para el grupo \n); if (((S_IXGRP)&(campo.st_mode))= =(S_IXGRP)) printf(De ejecucin para el grupo \n);
/*PERMISOS OTROS*/
if (((S_IROTH)&(campo.st_mode))= =(S_IROTH)) printf(De lectura para otros\n); if (((S_IWOTH)&(campo.st_mode))= =(S_IWOTH)) printf(De escritura para otros \n); if (((S_IXOTH)&(campo.st_mode))= =(S_IXOTH)) printf(De ejecucin para otros \n);