3.1 TeoriaLos Archivos son una de las caracteristicas mas importantes de UNIX, ya que se pueden realizar llamadas de E/S por medio de los
"
Descriptores de Archivos", estos abarcan:
- -Terminales
- -Discos
- -Cintas
- -Audio
- -Comunicacion por Red
- -etc....
Esto hace un enfasis a lo que dicen por ahi: "
Unix es un Archivo".
Otra caracteristica es su independiencia de los Dispositivos, ya que utilizando las llamadas a Archivos se logra un control de una
Interfaze de Dispositivo.
Un Dispositivo Periferico es una pieza de hardware conectada a un ordenador.
Una Pequena lista de
Dispositivos Perifericos son:
- -Discos (CD-ROMs )
- -Cintas
- -Pantallas
- -Teclados
- -Impresoras
- -Ratones
- -Interfaces de Red
- -etc....
Estos Dispositivos son manejados por los Programas de los Usuarios, estos programas realizan el Control de E/S, estos mismo programas
hacen llamadas a ciertos programas del Sistema Operativos, denominados:
Controladores de Dispositivo ( Device Driver ).
En base a esto, cada Programador debe aprender un conjunto de llamadas para el control de Dispositivo, Unix a simplificado del mismo modo la Interfaze de Dispositivo, al proporcionar un acceso uniforme a muchos Dispositivos a traves de 5 llamadas que son:
- -open
- -close
- -read
- -write
- -ioctl
Todos los Dispositivos en Unix estan representados por Archivos denominados "
Archivos Especiales", los cuales estan localizados en:
/dev
3.2 Directorios y Rutas de AccesoUnix Organiza los Archivos y Programas en directorios dentro del Disco Duro ( HDD ), estos
arcvhios/programas/directorios, tiene una ruta de acceso a ellos, y estos los Organiza mediante una Organizacion de Arbol, el cual se relacionan con el Archivo a Buscar.
La forma de Arbol que adopta la
Organizacion de Archivos es Unix es:
/ <-- raiz
|
-[dir_A]
|--[dir_B] <-- carpeta
|--archivo_01.txt
|--archivo_02.txt
|--archivo_03.txt
-[dir_C] <-- carpeta
|-- archivo_04.txt
/Es el nodo principal o raiz del S.O. en la Organizacion de Archivos.
Apartir de aqui podremos formar una ruta de acceso para llegar a un archivo.
Por ejemplo:
Si queremos llegar al archivo: "archivo_01.txt" su ruta es:
"/dir_A/dir_B/" y su sintaxis en la shell ( linea de comandos ) es:
*---------------------------------------*
| shell# cd /dir_A/dir_B |
*---------------------------------------*
Recordemos que una "
Ruta de Acceso" es la direccion para llegar a un dato o archivo. Esta direccion puede ser corta o larga, no ahi atajos sino un acceso rapido siempre y cuando sepas su ruta exacta.
Los comandos "
cd", "
ls" y "
pwd" nos seran de utilidad, ya que sus funciones son:
cdAccesa o Sale de/a un directorio.
lsLista los archivos de un directorio o de donde estes posicionado.
pwdNos dice la hubicacion que tenemos o donde estamos posicionados.
La funcion
getcwd(); nos devuelve la ruta de acceso del directorio de trabajo activo.
*---------------------------------------------------------------*
| #include <unistd.h> |
| extern char *getcwd( char *buf, size_t size ); |
*---------------------------------------------------------------*
size_t sizeEspecifica la longitud maxima del nombre de la ruta de acceso que puede emplear quien la llama.
char *bufSi "
buf" no es NULL, getcwd(); copia el nombre en "
buf".
Si el nombre es mayor que "size"
getcwd(); devuelve -1.
Si
getcwd(); tiene exito, devuelve el apuntador al nombre de la ruta de acceso.
Codigo:
ps_016.cImprime la ruta de acceso del directorio de trabajo activo#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX 250
int main()
{
char ruta[MAX];
system( "clear" );
if( getcwd( ruta, MAX ) == NULL ) )
{
perror( "Error al Buscar la Ruta de: \"%s\"." );
exit(0);
}
printf( "Directorio Actual es: %s", ruta );
getchar();
return 0;
}
*-------------------------------------------------------*
| En Ejecucion |
*-------------------------------------------------------*
| shell# cd /home/mi_user/bin |
| shell# ./ps_016 |
| Directorio Actual es: /home/mi_user/bin |
*-------------------------------------------------------*
==
Explicacion ==
Bueno la explicacion de codigo es.
Declaramos una Array de Cadena: "
char ruta[MAX];", donde MAX esta definido con una dimension de 250. Despues sigue el codigo
y llega el primero codificional, donde realiza la Resolucion de la Ruta de Acceso, que como vemos, antes de correr el programa, accesamos a
"
/home/mi_user/bin", y despues ejecutamos el archivo:
./ps_016, donde como resultado nos devuelve la Ruta de Acceso o posiciona donde estamos en la shell.

. Los parametro que pasamos a
getcwd(); fueron, "ruta", que es la variable ( array cadena ) donde se almacenara la direccion y MAX que es la dimension maxima del buffer ( ruta ).
A continuacion veremos algunas funciones relacionadas con el manejo de Directorios, son:
*-------------------------------------------------------*
| #include <stdio.h> |
| #include <dirent.h> |
| |
| DIR *opendir( const char *filename ); |
| struct dirent *readdir( DIR *dirp ); |
| void rewinddir( DIR *dirp ); |
| int closedir( DIR *dirp ); |
| long telldir( DIR *dirp ); |
| void seekdir( DIR *dirp, long loc ); |
*-------------------------------------------------------*
*-------------------------------------------------------*
| DIR *opendir( const char *filename ); |
*-------------------------------------------------------*
Proporciona un
identificador de bloque al directorio para las funciones de Directorio. Null en caso de error.
*-------------------------------------------------------*
| struct dirent *readdir( DIR *dirp ); |
*-------------------------------------------------------*
Devuelve un
apuntador a una estructura que contiene la informacion sobre la siguiente entrada del Directorio. Devuelve NULL al llegar al final del Directorio.
*-------------------------------------------------------*
| void rewinddir( DIR *dirp ); |
*-------------------------------------------------------*
Para posicionar el apuntador al Inicio del Directorio.
*-------------------------------------------------------*
| int closedir( DIR *dirp ); |
*-------------------------------------------------------*
Cerrar el identificador.
*-------------------------------------------------------*
| long telldir( DIR *dirp ); |
*-------------------------------------------------------*
Devuelva el desplazamiento dentro del Directorio de la Entrada en Uso.
*-------------------------------------------------------*
| void seekdir( DIR *dirp, long loc ); |
*-------------------------------------------------------*
Reposiciona las entradas en uso del Directorio, a la posicion especifica por "
loc".
NOTA: las funciones
telldir(); y
seekdir(); no son parte de POSIX.
Ahora veremos unos ejemplos

.
Codigo:
ps_017.cPrograma que imprime la lista de Archivos contenidos en un Directorio#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
int main()
{
DIR *dirp;
char dir[80];
struct dirent *direntp;
system( "clear" );
scanf( "%s", dir );
if( (dirp= opendir( dir ) )==NULL )
{
fprintf( stderr, "\n\nNo se pudo abrir \"%s\", Error: %s\n", argv[1], stderr( errno ) );
exit(1);
}
while( (direntp= readdir( dirp ) ) !== NULL )
printf( "\n%s", direntp->d_name );
printf( "\nFin del Programa..." );
closedir( dirp );
exit(0);
*---------------------------------------*
| En Ejecucion |
*---------------------------------------*
| shell# ./ps_017 |
| Directorio: / |
| . |
| .. |
| bin |
| dev |
| etc |
| lib |
| mnt |
| opt |
| tmp |
| sys |
| var.... etc.. |
| Fin del Programa... |
*---------------------------------------*
==
Explicacion ==
Este programa imprime la lista de los directorios/archivos contenidos en un DIRECTORIO xD. Describiremos las partes importabtes del codigo, empezando por el "DIR *dirp;", esta variable es de tipo DIR para usarla junto con la funcion "
opendir();", despues se declara una variable para la estrcutura "struct dirent *direntp;" que la obtenemos de "dirent.h", llegamos a la linea donde nos pide el nombre dle directorio, y es guardada en la variable "
char dir[80];", despues se le pasa el contenido a la funcion
opendir(), "
dirp= opendir(dir);", y esta misma devuelve un identificador que sera utilizado en las funciones de Manejo de Directorios. En seguida lee el directorio llamando a "
direntp= readdir(dirp);", esta funcion devuelve un puntero a la estructura que contiene el apuntador y es imprimida su informacion llamando al miembro: "
direntp->d_name". Y listo, finaliza el programa cerrando el identificador "
closedir(dirp);".
3.3 Busquedas de Rutas de Acceso y Variable de AmbienteBueno antes de empezar

, les adelanto que este tema no tiene codigo

xD, es mas teorico y de conocimiento de tu sistema unix, de cierta forma puede ser un buen tip o solo un buen conocimiento sobre como busca unix los comandos y lo llama, aqui mismo entra la variable de ambiente que es: "PATH". Asi que si desiden brincarlo, pues perfecto

, no ahi problema

.
Como todos sabemos, Unix es un sistema que se basa en comandos ( por lo general, aunque cuenta con modo grafico ), y por lo general los usuarios que utilizan UNIX, lo utilizan mas el modo consola ( shell ), y cuando llamamos a programas en la linea de comandos, como por ejemplo:"ls" ( lista archivos ), nosotros llamamos directamente desde la shell a "
ls", mas NO lo llamamos desde su ubicacion exacta, que seria( "/usr/bin/ls" ). Aqui es donde entra las Busquedas de Rutas de Acceso de manera sistematica, el sistema unix busca el programa en las rutas contenidas en la variable de ambiente "
PATH", utilizando cada uno de ellos. "
PATH" contiene los nomrbes completos de las rutas de acceso de los directorios mas importantes, separados por dos puntos.
*-----------------------------------------------------------------------*
| /usr/bin:/etc:/usr/local/bin:/usr/ccs/bin:/home/username/bin: |
*-----------------------------------------------------------------------*
Segu nuestra el contenido de la variable de ambiente "PATH", cuando ejecutemos por ejemplo: "ls", va ir a buscar primero al directorio: "
/usr/bin", en caso que NO se encuentre ahi, entonces pasa al siguiente directorio: "
/etc" y asi sucesivamente. Si tienes cursiosidad por saber la ubicacion de algun programa, solo escribe en la shell: "
which programa".
Ejemplo:*-------------------------------*
| shell# which ls |
| /usr/bin/ls |
*-------------------------------*
Ahora sabemos que la mayoria de los programas de unix estan contenidos en: "
/usr/bin", osea que, si por ejemplo hacemos un programa cualquiera y le ponemos: "mi_programa", despues este ejecutable lo pasamos a: /usr/bin.... Con esto nos evitariamos la molesta de llamar a nuestro programa desde su direccion exacta que era ( "
./home/user/carpeta/mi_programa" ), asi solamente en la shell escribimos: mi_programa y neustro programa correra de inmediato

. Cada ves que actuelicemos nuestro codigo fuente del programa y lo compilemos, ese EJECUTABLE lo copiamos/sustituimos en "/usr/bin" y tendremos nuestro programita actualizado y funcional dentro de la SHELL como cualquier otro programa.
Ejecucion de Nuestro programa antiguamente:
*-------------------------------------------------------*
| shell[ /home/user/codigos/ ]# ./mi_programa |
*-------------------------------------------------------*
Ejecucion de Nuestro programa contenido originalmente en "
/usr/bin"
*-------------------------------------------------------*
| shell[ /cualquierdireccion ]# mi_programa |
*-------------------------------------------------------*
Si desean saber las rutas a las que accede su variable de ambiente
PATH, solo basta hacer esto:
*---------------------------------------------------------------*
| shell# echo $PATH |
| /usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin: |
| /usr/bin:/bin:/usr/X11R6/bin:/usr/games: |
| /opt/www/htdig/bin:/usr/lib/java/bin: |
| /usr/lib/java/jre/bin:/opt/kde/bin:/usr/lib/qt/bin: |
| /usr/share/texmf/bin |
*---------------------------------------------------------------*
Y de este modo ustedes desiden donde situar nuestro script o programa en C, para ocuparlo futuramente

.
3.4 Representacion de Archivos en UnixUnix maneja 2 tipo de archivos que son:
- Archivos Ordinarios
- Archivos Especiales
- Archivos Especiales por Caracter
- Archivos Especiales por Bloque
- Archivos Especiales FIFO
[/list]
*Archivos OrdinarioEstos son archivos comunes realizados por el usuario, archivos de trabajo, documentos, etc...
*Archivos EspecialesEstos archivos representan dispositivos, pero existen 3 derivados que son:
*Archivos Especiales por CaracterEstos archivos especiales representan dispositivos como terminales.
*Archivos Especiales por BloqueEstos archivos representando dispositivos de disco.
*Archivos Especiales FIFOEstos archivos se utilizan para la comunicacion entre procesos.
Unix representa y diferencia los archivos por medio de un inodo, un inodo es una estructura que contiene informacion acerca de un archivo, informacion como:
- tamano
- localizacion
- propietario
- fecha de creacion
- permisos
- fecha de modificacion
Dato importante

, tomemos en cuenta que tanto archivos como directorios tienen con ellos asociado un inodo, mas adelante veremos sus diferencias y como los reconoce
UNIX.
Para recuperar la informacion contenida en un inodo de un archivo, utilizaremos a sistema
stat();*---------------------------------------------------------------*
| #include <sys/types.h> |
| #include <sys/stat.h> |
| |
| int stat( const char *path, struct stat *buf ); |
| int fstat( int fildes, struct stat *buf ); |
| int lstat( const char *path, struct stat *buf ); |
*---------------------------------------------------------------*
La Estructura "
struct stat" contiene los mienbros siguientes:
*---------------------------------------------------------------------------------------*
| Nombre | Descripcion |
*---------------------------------------------------------------------------------------*
| mode_t st_mode | Modo del Archivo |
| ino_t st_ino | Numero de inodo |
| dev_t st_dev | ID del Dispositivo que contiene una entrada de directorio |
| | para este archivo |
| dev_t st_rdev | ID del dispositivo, solo para archivos especiales de carac- |
| | ter o de bloke |
| nlink_t st_nlink | Numero de Ligas |
| uid_t st_uid | ID de Usuario, del propietario del Archivo |
| gid_t st_gid | ID de Grupo, del Grupo del Archivo |
| off_t st_size | Tamano del Archivo en bytes |
| time_t st_atime | Fecha del Ultimo Acceso |
| time_t st_mtime | Fecha de la Ultima Modificacion |
| time_t st_ctime | Fecha del Ultimo Cambio al estado del Archivo, en segundos |
| long st_blksize | Tamano preferencial dle bloque de E/S |
| long st_blocks | Numero de Bloques. "st_blksize" asignado |
*---------------------------------------------------------------------------------------*
*---------------------------------------------------------------*
| int stat( const char *path, struct stat *buf ) |
*---------------------------------------------------------------*
Funcion para abrir directorio unicamente ( no archivos )
*---------------------------------------------------------------*
| int fstat( int fildes, struct stat *buf ) |
*---------------------------------------------------------------*
Funcion para abrir archivos y directorios.
*---------------------------------------------------------------*
| int lstat( const char *path, struct stat *buf ) |
*---------------------------------------------------------------*
Funcion para abrir ligas simbolicas, esta funcion NO es parte de POSIX
Codigo:
ps_018.cPrograma que realiza la apertura de un directorio#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <time.h>
#include <string.h>
int main( int argc, char *argv[] )
{
struct stat buf;
system( "clear" );
if( argc != 2 )
{
fprintf( stderr, "Uso: %s nombre_de_archivo\n", argv[0] );
exit(1);
}
if( stat( argv[1], &buf ) == -1 )
{
fprintf( stderr, "No Se Puede Tomar el Archivo %s.\nError: %s\n", argv[1], strerror(errno) );
exit(1);
}
if( buf.st_mode & S_IFDIR )
{
printf( "\"%s\" es un Directorio, y sus descripciones son:", argv[1] );
printf( "\n\n>Numero de Inodo: %i", buf.st_ino );
printf( "\n>Numero de Ligas que contiene: %i", buf.st_nlink );
printf( "\n>ID del Propietario que lo Creo: %i", buf.st_uid );
printf( "\n>Numero de Blockes Asignado: %i", buf.st_blocks );
printf( "\n>Tamano del Archivo: %i bytes", buf.st_size );
printf( "\n>Ultima Modificacion: %s", ctime( &buf.st_mtime ) );
}
else printf( "%s No es un Directorio...", argv[1] );
getchar();
return 0;
}
*-----------------------------------------------------------------------*
| En Ejecucion |
*-----------------------------------------------------------------------*
| shell# ./ps_018 /home/dir_creado |
| "dir_creado" es un directorio, y sus descripciones son: |
| |
| >Numero de Inodo: 12669294 |
| >Numero de Ligas que contiene: 2 |
| >ID de propietario que lo creo: 0 |
| >Numero de Blockes Asignados: 2 |
| >Tamano del Archivo: 4096 bytes |
| >Ultima Modificacion: Sat Oct 1 12:48:54 2005 |
*-----------------------------------------------------------------------*
===
Explicacion ===
La forma de utilizacion es: "
./pas_018 directorio".Segun el docido, "
struct stat *buf" es una variable a la estructura stat para tomar sus distintos miembros ( segun la tablita ya vista ). En caso de errores para el primer condicional o segundo. En el segundo condicional "
if( stat( arg[1], &buf ) == -1 )", si el nombre pasado como argumento NO existe entonces se cumple en este mismo condicional se le pasan dos parametros a
stat(), que son: "
nombre_del_directorio" y estructura que sera rellenada por medio de buf. en el Tercer condicional "
if( buf.st_mode & S_IFDIR )" es solo para comprobar si el modo del archivo a abrir es un fichero o directorio, en este caso "
S_IFDIR" comprueba que sea un directorio xD

. En caso de exito pues muetra los
printf()s

, y el ultimo condicional, pues cuando el archivo pasado como argumento NO cumplo con ningun otro condicional, ya que es ovio que NO es un directorio, sino un fichero xD.
Si deseas hacer un ejemplo, pero para abrir ficheros, entonces modifica las lineas siguientes:
if( stst( argv[1], &buf ) == -1 )
| por |
if( fstat( argc, &buf ) == -1 )
Y pues NO es necesari el:
if( buf.st_mode & S_IFDIR )Ni tampoco necesitas el ultimo condicional "
else()", ya que "
fstat()" abre tanto ficheros como directorios

.
3.5 Representacion de Directorios y Enlaces o LigasEn Unix un
directorio es un archivo que contiene una serie de nombres e inodos que se corresponden.
Un
Enlace o
Liga es una asociacion entre el nombre de un archivo y su inodo, UNIX tiene dos tipos de enlaces o ligas y son:
- Ligas Duras.
- -Ligas Simbolicas ( o suaves ).
Las
Ligas Duras, estas ligan directamente lso nombres de los archivos con inodos.
Las
Ligas simbolicas ( o
suaves ) utilizan el archivo como un apuntador a otro nombre de archivo.
Con el comando "
ln" o la llamada al sistema "
link", los usuarios pueden crear ligas duras adicionales para archivos.
3.6 Representacion de Archivos con IdentificadoresDentro de la Programacion en C, los archivos estan designados por
apuntadores de archivo o por
descriptores de archivo.
Los Designados por
Apuntadores de Archivo, utilizan la Biblioteca estandar de E/S para ANSI C, como son:
- fopen
- fclose
- fscanf
- fprintf
- fread
- fwrite
Y sus
Identificadores para los Apuntadores de Archivo de la entrada, salida y el errr estandares son:
Y estan definidos en
stdio.hLos Designados por
Descriptores de Archivo, utilizan la Biblioteca estandar de E/S de UNIX, somo son:
Los
Identificadores para los
Descriptores de Archivo de la entrada, salida y error estandar son:
- STDIN_FILENO
- STDOUT_FILENO
- STDERR_FILENO
Y estan definidos en
unistd.hPor lo tanto los
Apuntadores y
Descriptores proporcionan Nombres Logicos o Identificadores para llevar acabo la entrada y salida independiente del Dispositivo. Asi del mismo modo un
fopen() o un
open() proporcionan:
- Una asociacion entre un archivo o dispositivo fisico y
- El Identificador Logico utilizado en el Programa.
Y como es ovio, en
Archivos AVANZADOS, se trata el uso de
Descriptores de Archivos 
.
En
open() el identificador es un indice en una tabla de descriptores de archivo.
En
fopen() el identificado es un apuntador hacia una estructura de archivo.
3.7 Descriptores de ArchivoLa llamada al sistema
open(), asocia un descriptor de archivo con un archivo o dispositivo fisico.
*-------------------------------------------------------*
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| |
| int open( cont char *path, int oflag, ... ); |
*-------------------------------------------------------*
const char *pathEs el archivo o dispositivo fisico al que le asociaremos un descriptor de archivo.
int oflagLos valores POSIX.1 para oflag estan definidos en
fcntl.h, e incluyen:
*-----------------------------------------------*
| NOMBRE | DESCRIPCION |
*-----------------------------------------------*
| -O_RDONLY | Solo Lectura |
| -O_WRONLY | Solo Escritura |
| -O_RDWR | Solo Lectura y/o Escritura |
| -O_APPEND | |
| -O_CREAT | Crearlo |
| -O_EXCL | |
| -O_NOCTTY | |
| -O_NONBLOCK | |
| -O_TRUNC | |
*-----------------------------------------------*
Se tiene que especificar exactamente una de las banderas o tambien puede especificar varias banderas para obtener un efecto combinado, utilizando el
OR (
| ).
...Este tercer parametro extra, solo se peude activar cuando el campo "
oflag" tiene o es O_CREAT, de estemodo se incluira este tercer parametro extra que es de tipo "
mode_t" y es el que especifica los
Permisos para el Archivo como un valor
mode_t.
En Unix los
Privilegios posibles son:
- read (lectura), representado por una: r
- write (escritura), representado por una: w
- execution (ejecucion), representado por una: x
Y estos permisos, son aplicados a estos tres tipos:
- Usuario ( el propietario ).
- Grupo ( un grupo, qu esta constituido por un grupo de usuarios ).
- -Otros ( los dema usuarios que NO son miembros de algun grupo, o no son del sistema ).
Estos privilegios estan especificados por separado con la siguiente mascara que esta especificada en
POSIX.1:
<----- Usuario -----><------ Grupo ------><------- Otros ------>
*------*------*------*------*------*------*------*------*------*
| r | w | x | r | w | x | r | w | x |
*------*------*------*------*------*------*------*------*------*
Estos nombres estan definidos en
sys/stat.h y a coninuacion veremos una tabla de los nombres simbolicos y su significado:
*-----------------------------------------------------------------------------------------------*
| NOMBRE | DESCRIPCION |
*-----------------------------------------------------------------------------------------------*
| S_IRUSR | bit de permiso de lectura para el usuario ( propietario ) |
| S_IWUSR | bit de permiso de escritura para el usuario ( propietario ) |
| S_IXUSR | bit de permiso de ejecucion para el usuario ( propietario ) |
| S_IRWXU | bit de permiso de lectura, escritura y ejecucion para el usuario ( propietario ) |
*-----------------------------------------------------------------------------------------------*
| S_IRGRP | bit de permiso de lectura para el grupo |
| S_IWGRP | bit de permiso de escritura para el grupo |
| S_IXGRP | bit de permiso de ejecucion para el grupo |
| S_IRWXG | bit de permiso de lectura, escritura y ejecucion para el grupo |
*-----------------------------------------------------------------------------------------------*
| S_IROTH | bit de permiso de lectura para otros |
| S_IWOTH | bit de permiso de escritura para otros |
| S_IXOTH | bit de permiso de ejecucion para otros |
| S_IRWXO | bit de permiso de lectura, escritura y ejecucion para otros |
*-----------------------------------------------------------------------------------------------*
| S_ISUID | fijar el ID del usuario al momento de la ejecucion |
| S_IDGID | fijar el ID del grupo al momento de la ejecucion |
*-----------------------------------------------------------------------------------------------*
La llamada al sistema
close();, realiza el cierre de un
Descriptor de Fichero.
*---------------------------------------*
| #include <unistd.h> |
| |
| int close( fd ); |
*---------------------------------------*
Acontinuacion veremos un ejemplo sencillo, que ilustre
open() y
close().
Codigo:
ps_019.cPrograma que ilustra el uso de OPEN() y CLOSE(). Si existe se abre, sino solo se crea#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int mifd;
mode_t modo= S_IRUSR | S_IRGRP | S_IROTH;
if( mifd= open( "/root/datos.dat", O_RDONLY | O_CREATE, modo ) )
printf( "Archivo Abierto con exito.." );
else printf( "Problmas para abrir el archivo..." );
close( mifd );
getchar();
return 0;
}
==
Explicacion ==
Bueno pues no tiene mucha ciencia xD, simplemente
open() tiene 3 parametros que son: ubicacion del archivo *.dat, modo en que se tratara el archivo ( Lectura Solamente y/o Se Creara ), y como incluimos el modo
O_CREAT, por lo tanto se tiene que introducir un 3er parametro que define los privilegios que tendran los 3 tipos de usuarios para con el archivo, y por los cuales establecimos los modos de:
Lecutra Para Usuario Propietario,
Lectura para el Gurpo, Lectura para Otros Usuarios. En caso de error nos dira: "Problemas para abrir el archivo...". Se cierra el descriptor y finaliza el programa.
3.7.1 Lectura de FicherosLa llamada a la funcion
read(), devuelve la longitud de la cadena leida del descriptor en un valor entero, su sintaxis es la siguiente:
*---------------------------------------------------------------*
| #include <unistd.h> |
| |
| size_t read( int fd, void *buffer, size_t buffer ); |
*---------------------------------------------------------------*
- int fd
es el descriptor de archivo
- void *buffer
es un puntero al buffer donde contendremos la info leida del descriptor
- size_t buffer
es el tamano del buffer
Veremos un codigo......
Codigo:
ps_020.cPrograma que ilustra el uso de read()#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 100 /*tamano de nuestro buffer*/
/*Prototipos*/
void buf_destripado( char *buf );
void buf_destripado( char *buf )
{
while( *buf!='\0' )
{
if( *buf=='\n' )
{
printf( "\\n" );
printf( "\n" );
}
else printf( "%c", *buf );
*buf++;
}
}
int main()
{
int mifd, resaca;
char buf[N];
system( "clear" );
if( !(mifd=open( "/home/user/dato.dat", O_RDONLY ) ) )
{
printf( "Problemas para leer el fichero..." );
close( mifd );
getchar();
exit(1);
}
printf( "\n\nLeyendo Archivo...." );
printf( "\nTamano del Buffer: %i bytes.", sizeof( buf ) );
dato= read( mifd, &buf, N );
printf( "\nContenido:\n-------------------\n" );
buf[dato]='\0'; /*quito el resaque, acorto buffer y dejo el mensaje limpio*/
printf( "%s", buf );
printf( "\n-------------------\n\nBuffer Ocupado: %i bytes", dato );
printf( "\n\nDestripado del Buffer..." );
printf( "\n------------------\n" );
buf_destripado( buf );
printf( "\n------------------\n" );
close( mifd );
printf( "\n\nFin del Programa....\n" );
getchar();
return 0;
}
*-----------------------------------------------*
| En Ejecucion |
*-----------------------------------------------*
| shell#./ps_020 |
| |
| Leyendo Archivo.... |
| Tamano del Buffer: 100 bytes. |
| Contenido: |
| ------------------- |
| Hola Angel |
| Que Onda, esto va bien |
| ------------------- |
| |
| Buffer Ocupado: 33 bytes |
| |
| Destripado del Buffer... |
| ------------------ |
| Hola Angel\n |
| Que Onda, esto va bien |
| ------------------ |
| |
| Fin del Programa.... |
*-----------------------------------------------*
==
Explicacion ==
Se realiza la apertura del archivo en modo de Solo Lectura, se realiza la llamada a
read() la cual consigo lleva 3 parametros que son: el Descriptor, el Buffer, y el Tamano del Buffer que tenemos para guardar el archivo, recordemos que el archivo a leer NO debe sobrepasar el tamano que le destinamos al buffer ( el 3er parametro ), sino solo leera hasta el Tamano Especificado, del mismo modo
read() retorna el numero de bytes leidos ( pero lee hasta maximo el 3er parametro establecido ). Despues Realizo 2 operaciones que son: Imprimir el Contenido del Archivo y Mostrar el Salto o Saltos que tiene el fichero, y se cierra el fichero.
La llamada a la funcion
write() escribe al descriptor abierto con permiso de escritura y retorna el numero de bytes escritos en el fichero, del buffer donde tenemos contenidos los datos a escribir con
write(). Su sintaxis es:
*---------------------------------------------------------------*
| #include <unistd.h> |
| |
| size_t write( int fd, void *buf, size_t buf ); |
*---------------------------------------------------------------*
Para una mejor comprencion veremos un par de ejemplos.
Codigo:
ps_021Programa que permite leer y escribir en un fichero#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#define N 1024
int main()
{
char buf[N], buf2[N];
int bytesenv, bytesrecv, fd_in;
mode_t modo= S_IRWXU | S_IRGRP | S_IROTH;
system( "clear" );
if( !(fd_in=open( "/root/datos.dat", O_RDWR | O_CREAT, modo ) ) )
{
printf( "Problemas para Abrir Archivo.\nError: %s", strerror( errno ) );
getchar();
exit(1);
}
printf( "Estado del Buffer: %i bytes", sizeof( buf ) );
printf( "\nContenido del Fichero:\n---------------\n" );
bytesrecv= read( fd_in, &buf, N ); /*read() retornara el numero de bytes leidos*/
buf[bytesrecv]='\0';
printf( "%s", buf );
printf( "\n---------------\n" );
printf( "Buffer Utilizado Para Lectura: %i bytes", sizeof( bytesrecv ) );
printf( "\nBuffer de Lectura: %i bytes", strlen( buf ) );
printf( "\n\nTexto a Introducir: " );
fgets( buf2, N, stdin );
buf2[strlen(buf2)+1]='\n';
buf2[strlen(buf2)+1]='\0';
printf( "\n\nEstado de Buffer 2: %i bytes", sizeof( buf2 ) );
printf( "\nBuffer Utilizado para Escribir: %i bytes", strlen( buf2 ) );
bytesenv= write( fd_in, &buf2, strlen( buf2 ) ); /*write() retornara el numero de bytes escritor*/
printf( "\nSe Escribieron %i bytes con exito.", sizeof( bytesenv ) );
printf( "\n\nFin del Programa..." );
close( fd_in );
getchar();
return 0;
}
*-------------------------------------------------------*
| En Ejecucion |
*-------------------------------------------------------*
| shell# ./ps_021 |
| Estado del Buffer: 1024 bytes |
| Contenido del Fichero: |
| --------------- |
| hola como estas |
| |
| --------------- |
| Buffer Utilizado Para Lectura: 4 bytes |
| Buffer de Lectura: 16 bytes |
| |
| Texto a Introducir: muy bien |
| |
| |
| Estado de Buffer 2: 1024 bytes |
| Buffer Utilizado para Escribir: 9 bytes |
| Se Escribieron 4 bytes con exito. |
| |
| Fin del Programa... |
*-------------------------------------------------------*
==
Explicacion ==
Usaremos 2 buffers, BUF es donde almacenaremos los bytes del archivo y BUF2 es donde guardaremos los datos a escribir.
Primeramente realizamos la apertura dle fichero en modo de Lectura y Escritura (
O_RDWR ) y en el caso que NO exista se creara con
permisos de Lectura,
Escritura y
Ejecucion para Usuarios y de
Lectura para el Grupos y
Otros, se lee el fichero y se reciven los bytes leidos en "bytesrecv", despues se imprime el los bytes leidos.
NOTA: la sintaxis: "
buf[bytesrecv]='\0';" inserta el Fin de Linea a los datos del archivo, asi evitamos se impriman datos o residuos indeseados de la memoria.
Despues se pide la cadena nueva a introducir al fichero y, pues cabe mencionar que NO usamos:
gets( buf2 ); ya que no es recomendable, usaremos fgets( char *buf, int buf_size, FILE *stream ), en "
stream" incluimos la entrada estandart (stdin).
En seguida le realizamos una modificacion a nuestra cadena a introducir, le agregaremos un SALTO DE LINEA AL FINAL y el Fin de Linea

, asi al escribirse en el fichero nos brincaremos al proximo renglon con el fin de que en un futuro que se vulva a realizar la misma u otra operacion podamos interactuar con el siguiente renglon

y no tener que hacer llamdas especiales para agregar un salto de linea (\n) al fichero

. Y por ultimo escribirmos los datos y la funcion write() nos retornara los bytes escritos ( bytesenv ).
Ahora como veremos otro ejemplo bueno xD, este nos ensena la forma de abrir dos descriptores y leer un archivo y copiarlo a otra posicion... seraya con COPY & PASTE con descriptores

.
Codigo:
ps_022.c#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#define N 1048576
/*
buffer de 1MB( 1024kb -->1048576bytes )
Solo recuerda que se escrube en bytes ( asi como esta en el #define :D )
--------- Tabla de Dimensiones en Ficheros-------------
1024bytes == 1KB
1024kb == 1MB
1024mb == 1GB
1024gb == 1tb etc.....
*/
int main( int argc, char *argv[] )
{
int fd_in, fd_out, bytesenv, bytesrecv;
mode_t modo= S_IRWXU | S_IRGRP | S_IROTH;
char buf[N];
system( "clear" );
if( argc!=3 )
{
fprintf( stderr, "Uso: %s <archivo_origen> <archivo_destino>\n", argv[0] );
exit(1);
}
if( !( fd_in=open( argv[1], O_RDONLY ) ) )
{
fprintf( stderr, "No Se Puedo abrir el archivo \"%s\"\nError: %s", argv[1], strerror( errno ) );
exit(1);
}
if( !( fd_out=open( argv[2], O_WRONLY | O_CREAT | O_EXCL, modo ) ) )
{
fprintf( stderr, "\nNo Se Puede crear el fichero \"%s\"\nError: %s", argv[2], strerror( errno ) );
exit(1);
}
bytesrecv= read( fd_in, &buf, N );
printf( "\n---Tabla de Peso en Ficheros ---\n" );
printf( "1KB --> 1024 bytes\n" );
printf( "1024KB --> 1MB" );
printf( "\n\nEl Fichero \"%s\" Pesa: %.2fkb ( %i bytes )", argv[1], ((float)bytesrecv/1024), bytesrecv );
printf( "\nA Continuacion se copara el fichero la ubicacion deseada...." );
bytesenv= write( fd_out, &buf, bytesrecv );
printf( "\n\nSe Creo una copia del fichero \"%s\" de %.2fkb...", argv[2], ((float)bytesrecv/1024) );
printf( "\n\nFin del Programa....." );
close( fd_in );
close( fd_out );
getchar();
return 0;
}
*-----------------------------------------------------------------------------------------------*
| En Ejecucion |
*-----------------------------------------------------------------------------------------------*
| shell# ./ps_022 /home/miarchivo.tar /home/dir/miarchivo.tar |
| |
| ---Tabla de Peso en Ficheros --- |
| 1KB --> 1024 bytes |
| 1024KB --> 1MB |
| |
| El Fichero "/home/miarchivo.tar" Pesa: 64.90kb ( 66457 bytes ) |
| A Continuacion se copiara el fichero la ubicacion deseada.... |
| |
| Se Creo una copia del fichero "/home/dir/miarchivo.tar" de 64.90kb... |
| |
| Fin del Programa..... |
*-----------------------------------------------------------------------------------------------*
==
Explicacion ==
Creo que no es tan necesaria, pero bueno

....

Pues como ya sabemos el archivo a leer es pasado como Argumento 1 y el archivo de Escritura Destino es pasado como Argumento 2, en base a esto se lee el Argumento 1 y la funcion "
read()" al leer retorna el peso del archivo expresado en un valor de tipo ENTERO y que viene siendo en bytes

. Lo mismo "
write()", retorna el peso del archivo Escrito expresado en un valor de tipo ENTERO y que viene siendo en bytes

. Ahora, al momento de leer (
read() ), el peso lo guardamos en "
bytesrecv" y el contenido en "
buf", ahora al momento de escribir (
write() ) como 2do parametro ponemos lo datos ( buf ) y el peso de los datos o bien el tamano del fichero ( bytesrecv ) y write() nos retornara un valor que contendra "
bytesenv", con este valor podemos asegurar si la infomacion se escribio correctamente

( ya que debe retornar el mismo valor que contiene "
bytesrecv"

). Y al final ya tenemos nuestro archivo copiado en otro directorio. o_O
Veremos otro codigo que ilustra la forma de realizar: lectura, escritura e insercion de texto en el fichero, pero en esta ocacion solo utilizaremos 2 argumentos, el de la OPCION y el FICHERO de entrada

.
Codigo:
ps_023.cPrograma que realiza copia de ficheros con desciptores#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#define N 1024 /*Buffer de 1MB*/
int main( int argc, char *argv[] )
{
char buf[N], buf2[N]; //buffers
int fd, fd_out, bytesrecv, bytesenv; //descriptor y 2 varables para saber los bytes recividos y enviados
mode_t modo= S_IRWXU | S_IRGRP | S_IROTH;
system( "clear" );
if( argc!=3 )
{
printf( "\nUso: %s <opcion> <path/archivo>\n\n", argv[0] );
printf( "\n[OPCION]\n" );
printf( "-l\tLeer Fichero del Path." );
printf( "\n-c\tCopiar Fichero del <Path1> al <Path2>." );
printf( "\n-r\tEliminar Fichero Path." );
printf( "\n-e\tEscribir en el Fichero.\n\n" );
exit(1);
}
if( !(fd= open( argv[2], O_RDWR | O_CREAT, modo )) )
{
fprintf( stderr, "Problemas para abrir el fichero: %s", strerror(errno) );
exit(1);
}
if( !strcmp(argv[1], "-l") )
{
bytesrecv= read( fd, &buf, N );
buf[bytesrecv]='\0';
printf( "Fichero: %s", argv[2] );
printf( "\nTamano del Fichero: %.2fMB(%i bytes)", ((float)bytesrecv/1024), bytesrecv );
printf( "\nContenido\n" );
printf( "******************************\n" );
printf( "%s", buf );
printf( "******************************\n" );
}
if( !strcmp(argv[1], "-r") )
{
remove( argv[2] );
printf( "Fichero \"%s\" Eliminado.", argv[2] );
}
if( !strcmp(argv[1], "-e") )
{
bytesrecv= read( fd, &buf, N );
buf[bytesrecv]='\0';
printf( "\n----------------------- BUFFERS -----------------------\n" );
printf( "Buffer de Lectura Disponible: %.2fMB(%i bytes)", ((float)N/1024), N );
printf( "\nBuffer del Fichero Leido: %.2fMB(%i bytes)", ((float)bytesrecv/1024), bytesrecv );
printf( "\n--------------------------------------------------------\n" );
printf( "\n\nContenido:\n" );
printf( "******************************\n" );
printf( "%s", buf );
printf( "******************************\n" );
printf( "\n\n--------------- Datos a Insertar -----------------\n\n" );
fgets( buf2, N, stdin );
buf2[strlen(buf2)+1]='\n';
buf2[strlen(buf2)+1]='\0';
bytesenv= write( fd, &buf2, strlen(buf2) );
printf( "\n----------------------- BUFFERS -----------------------\n" );
printf( "Buffer de Escritura Disponible: %.2fMB(%i bytes)", ((float)N/1024), N );
printf( "\nBuffer del Fichero Escrito: %.2fMB(%i bytes)", ((float)bytesenv/1024), bytesenv );
printf( "\n--------------------------------------------------------\n" );
}
if( !strcmp( argv[1], "-c") )
{
if( !(bytesrecv= read( fd, &buf, N )) )
{
fprintf( stderr, "\nProblemas para Leer el Fichero: %s\n", strerror(errno) );
exit(1);
}
printf( "\n----------------------- BUFFERS -----------------------\n" );
printf( "Buffer de Lectura Disponible: %.2fMB(%i bytes)", ((float)N/1024), N );
printf( "\nBuffer del Fichero Leido: %.2fMB(%i bytes)", ((float)bytesrecv/1024), bytesrecv );
printf( "\n--------------------------------------------------------\n" );
printf( "Archivo \"%s\", sera copiado con el nombre de?: ", argv[2] );
fgets( buf2, N, stdin );
buf2[strlen(buf2)-1]='\0'; //elimina el salto de linea del buffer :D '\n', sino se guardaria: "nombre\n"
if( !(fd_out= open( buf2, O_CREAT | O_RDWR , modo )) )
{
fprintf( stderr, "\nProblema para crear el archivo: %s: %s", buf2, strerror(errno) );
exit(1);
}
if( !(bytesenv= write( fd_out, &buf, bytesrecv )) )
{
fprintf( stderr, "\nProblemas para Escribir el Archivo: %s\n", strerror(errno) );
exit(1);
}
printf( "Se Escribieron: %.2fMB(%i bytes)", ((float)bytesenv/1024), bytesenv );
close(fd_out);
}
close( fd );
getchar();
return 0;
}
==
Explicacion ==
Pues realiza casi lo mismo que el codigo anterior, solo que este utiliza argumentos

, y raliza:
- Lectura ( solo lee y muestra informacion/contenido del archivo
- Copia el fichero en otro con el nombre que quieras

- Elimina un fichero
- Escribe datos en un fichero existente ( vaya, Anida )
Lo unico relevante e interesante es que observen bien la forma en que se le pasa el NOMBRE del fichero a crear, al segundo Descriptor de Fichero (
fd_out ), lo que se realiza ANTES de la llamada a dicho OPEN(), de ese modo NO cometamos el error de guardar el nombre mal ( creyendo nosotros que hiria bien

). Por ultimo solo ver como se utiliza
READ(),
WRITE() y
REMOVE().
*--------------------------------------------------------------*
| #include <sys/ioctl.h> |
| |
| int ioctl( int fd, int request, /* args */ ); |
*--------------------------------------------------------------*
La funcion
ioctl() nos proporciona un medio para obtener informacion sobre el estado de un dispositivo o para establecer opciones de control para el mismo.
En caso de exito "
ioctl()" retorna un 0 y en caso de error un -1 y setea a "
errno" con un valor de los siguientes:
*-----------------------------------------------------------------------------------------------*
| Nombre | Descripcion |
*-----------------------------------------------------------------------------------------------*
| EBADF | fd no es un descriptor valido. |
| EFAULT | /*args*/ preferencia a una zona inaccesible. |
| ENOTTY | fd no esta asociado con un dispositivo especial de caracteres. |
| ENOTTY | La peticion especificada no se aplica a la clase de objeto que |
| | referencia el descriptor fd. |
| EINVAL | Peticion /*args*/ no es valido. |
*-----------------------------------------------------------------------------------------------*
Otras funciones interesantes a
ioctl() son:
*-----------------------------------------------------------------------------------------------*
| #include <sys/io.h> /*para glibc*/ |
| #include <unistd.h> /*para libc5*/ |
| |
| int ioperm( unsigned long desde, unsigned long num, int encender ); |
*-----------------------------------------------------------------------------------------------*
La funcion
ioperm() establece el bit de permiso de acceso a los Puertos para el proceso para "
num" bytes, empezando desde la direccion del puerto "
desde", al valor "
encender". Su utilizacion requiere permisos de "
root".
Devuelve 0 en caso de exito y un -1 en caso de error, y setea a "errno" con un valor.
Solo se pueden especificar los primeor puertos 0x3fff puertos de E/S, para utilizar mas puertos se debe utilizar
iopl(). Dato importante tambien es que los permisos se Hereda en un
fork(), pero si estan en un
exec().
*--------------------------------------------------*
| #include <sys/io.h> /*para glibc*/ |
| #include <unistd.h> /*para libc5*/ |
| |
| int iopl( int nivel ) |
*--------------------------------------------------*
La funcion
iopl() cambia el nivel del privilegio de E/S del Proceso en Curso, La funcion iopl() tiene que emplearse cuando se desea acceder a los puertos que estan mas haya del rango 0x3ff. Ademas los permisos son heredados por
fork() y
exec().
La funcion
iopl() devuelve 0 en caso de exito y devuelve -1 en caso de error, y setea a "
errno" con un valor apopiado:
*---------------------------------------------------------------------------*
| Nombre | Descripcion |
*---------------------------------------------------------------------------*
| EINVAL | nivel es mayor que 3 |
| EPERM | el usuario no es el super-usuario(root) |
*---------------------------------------------------------------------------*
3.7.2 Entradas y Salidas sin BloqueoAntes de empezar con el temita

. Quiero recalcar que es muy importante poner atencion y entender bien este tema ya que los siguientes temas se basaran mucho en este, por la razon de que empezaremosa ver codigos donde realizaremos aperturas de descriptores de archivos desde nuestros Procesos

. Asi que debemos dejar claras algunas cosillas en este tema

.
Cuando un procesos intenta leer de un bufferm este lo bloquea, hasta esperar a que la entreda de lectura este disponible para leer, osea, esperara en el "read()". Dicho de otro modo seria que, imaginemos que tenemos 2 Procesos, ene ste caso si intentamos leer un fichero ( abierto previamente ), dependiendo quien lo haga primero, uno de los dos Procesos tiene que esperar a que el Proceso que esta leyendo, termine, y asi continua a realizar la lectura el Procesos que sigue, asi continuamente deben ir Esperando a que se desocupe la entrada para poder realizar la lectura ( read() ).
El Bloque de E/S presneta un problema para un proceso, ya que peude darse el caso que un proceso este vigilando varias entradas para realizar una lectura. El Proceso no tiene la oportunidad de saber que Entrada es la que llega primero, ya que si al intentar leer de un buffer resulta que este esta ocupado, puede darse el caso en que el Proceso se vea Congelado Indefinidamente.
En este punto entra el Emple de E/S sin Bloqueo, que nos ayuda a resolver el Problema de que un Procesos espera para poder Leer, o bien evitar congelamientos Indeifinidos. Para resolver este problema solo es cuestion de configurar las Banderas de Control apropiadas, de esta forma el read() puede intentar realizar una lectura, y si se esta ocupada la entrada, el read() no se vera en la necesidad de bloquear ( esperar o congelarse ), solamente regresara de inmediato ya que NO se encontro disponible la entrada

.
Para llevar acabo la operacion de E/S sin Bloqueo se debe utilizar la bandera O_NONBLOCK asociada con el Descriptor de Archivo. Del mismo modo la llamada a
fcntl() realiza modificaciones a las Banderas al estar ya asociadas con un objeto que tiene un Descriptor de Archivo.

*-----------------------------------------------------------------------*
| #include <sys/types.h> |
| #include <unistd.h> |
| #include <fcntl.h> |
| |
| int fcntl( int fd, int comando, long arg|struct flock *lock ); |
*-----------------------------------------------------------------------*
La funcion
fcntl() realiza mucha soperaciones sobre los Descriptores de Archivos dependiendo el "comando" que se le introduzca

( pero recordemos que nosotros solo modificaremos banderas, para evitar Bloqueos

).
int fd[li]Es el Descriptor de Fichero asociado.[/li]
int comando[li]Es el comando a introducir para realizar una operacion sobre el Descriptor de Archivo, sus comandos son:[/li]
*------------*----------------------------------------------------------------------------------*
| COMANDO | DESCRIPCION |
*------------*----------------------------------------------------------------------------------*
| F_DUPFD | Busca el descriptor de fichero disponible de menor, mayor o igual que "arg" |
| | y lo convierte en una copia de "fd", al crearse los fd's, estos no comparten la |
| | bandera close-on-exec (cerrar-la-ejecutar), en la copia estara desactivada. |
| | En caso de exito se retorna el nuevo descriptor(fd). |
| | |
| F_GETFD | Lee la bandera close-on-exec. Si el bit FD_CLOEXEC es 0, el fichero permanece |
| | abierto durante exec, en caso contrario se cerrara. |
| | |
| F_SETFD | Asigna el valor de la bandera close-on-exec, al valor especificado por el bit |
| | FD_CLOEXEC de arg. |
| | |
| F_GETFL | Lee las Banderas del Descriptor de Archivo ( todas, segun hayan sido puestas |
| | open() ), |
| | |
| F_SETFL | Asignas las Banderas del Descriptor al Valor asignado en arg. Estas pueden ser |
| | O_APPEND, O_NONBLOCK o O_ASYNC. Recordar que las banderas ya puestas por open() |
| | no se veran afectadas :D. |
| | |
| F_GETLK | Devuelve la estructura flock que nos impide obtener el candado o establece el |
| | campo l_type del candado F_UNLCK sino hay obstruccion. |
| | |
| F_SETLK | El candado esta cerrado( cuando l_type es F_RDLCK o F_WRLCK ), o estara abierto |
| | ( cuando l_type es F_UNLCK ). Si el candado esta siendo utilizado por alguien |
| | mas entonces devolvera un -1 y setea a errno con el codigo: EACCES, EAGAIN. |
| | |
| F_SETLKW | Es como F_SETLK solo que en ves de devolver un error, este esperara hasta que |
| | el candado se abra.Si se recive una senal mientras fcnt() esta funcionando |
| | este se interrumpe. |
| | |
| F_GETOWN | Obtiene el Id del Proceso o el Grupo de Procesos que actualmente esta |
| | reciviendo las senales de SIGIO y SIGURG para los eventos sobre el Descriptor. |
| | |
| F_SETOWN | Establece el ID de Proceso o el Grupo de Procesos que estaran reciviendo las |
| | senales de SIGIO y SIGURG para los eventos sobre el Descriptor. |
| | |
| F_GETSIG | Obtiene la senal cuando la entrada o la salida son posibles. Un valor 0 |
| | significa que se envia SIGIO, cualquier otro valor es la senal enviada en su |
| | lugar y se dispone del manejador de senales si se instala con SA_SIGINFO. |
| | |
| F_SETSIG | Establece la senal enviada cuando la entrada o la salida son posibles. Para |
| | lso valores, pues igual como dije en F_GETSIG xD. |
*------------*----------------------------------------------------------------------------------*
long arg|struct flock *lock[li]Es el valor a enviar, puede ser del tipo ARGUMENTO o ESTRUCTURA, dependiendo la funcion a realizar

. Mas informacio en la tablita de arriba

.[/li][/list]
La funcion
fcntl() en caso de exito retornara un valor que cuyo exito dependera del COMANDO que se utiliza y el valor que se espera, ejemplo:
F_DUPFD[li]El valor del nuevo Descriptor.[/li]
F_GETFD[li]El valor de la Bandera.[/li]
F_GETFL[li]El valor de la Bandera.[/li]
F_GETOWN[li]El valor del Propietario del Descriptor.[/li]
F_GETSIG[li]Valor de la Senal Enviada, cuando la lectura o la escritura son posibles, o 0 para el comportamiento tradicional de SIGIO.[/li]
CUALQUIER OTRA ORDEN[li]Cero[/li][/list]
Y en caso de Error se devolvera un -1 y setara a errno con un valor: