Ejemplo: funciones del sistema de archivos integrado C
Este sencillo programa de lenguaje C ilustra la utilización de varias funciones del sistema de archivos integrado.
El programa ejecuta las operaciones siguientes:
- 1
- Utiliza la función getuid() para determinar el ID de usuario (uid) real.
- 2
- Utiliza la función getcwd() para determinar el directorio actual.
- 3
- Utiliza la función open() para crear un archivo. Establece que el propietario (la persona que ha creado el archivo) tenga autorización de lectura, escritura y ejecución sobre el archivo.
- 4
- Utiliza la función write() para escribir una serie de bytes en el archivo. El descriptor de archivo proporcionado en la operación de apertura (3) identifica el archivo.
- 5
- Utiliza la función close() para cerrar el archivo.
- 6
- Utiliza la función mkdir() para crear un nuevo subdirectorio en el directorio actual. El propietario obtiene acceso de lectura, escritura y ejecución en el subdirectorio.
- 7
- Utiliza la función chdir() para pasar del subdirectorio nuevo al directorio actual.
- 8
- Utiliza la función link() para crear un enlace con el archivo creado anteriormente (3).
- 9
- Utiliza la función open() para abrir el archivo solo para lectura. El enlace creado en (8) posibilita el acceso al archivo.
- 10
- Utiliza la función read() para leer una serie de bytes del archivo. El descriptor de archivo proporcionado en la operación de apertura (9) identifica el archivo.
- 11
- Utiliza la función close() para cerrar el archivo.
- 12
- Utiliza la función unlink() para eliminar el enlace con el archivo.
- 13
- Utiliza la función chdir() para pasar del directorio actual al directorio padre en el que se ha creado el nuevo subdirectorio.
- 14
- Utiliza la función rmdir() para eliminar el subdirectorio creado anteriormente (6).
- 15
- Utiliza la función unlink() para eliminar el archivo creado anteriormente (3).
Nota: este programa de ejemplo funcionará
correctamente en aquellos sistemas en los que el CCSID del trabajo
en el que se ejecuta sea 37. Los nombres de vía de acceso y de
objeto de las API del sistema de archivos integrado deben codificarse
en el CCSID del trabajo; sin embargo, el compilador C almacena las
constantes de tipo carácter en el CCSID 37. Para que la
compatibilidad sea total, convierta las constantes de tipo
carácter, como, por ejemplo, los nombres de vía de acceso y de
objeto, antes de pasar las API al CCSID del trabajo.
Nota: al utilizar los ejemplos de código, acepta los
términos de la Información sobre licencia de código y exención de responsabilidad.
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#define BUFFER_SIZE 2048
#define NEW_DIRECTORY "testdir"
#define TEST_FILE "test.file"
#define TEST_DATA "Hello World!"
#define USER_ID "user_id_"
#define PARENT_DIRECTORY ".."
char InitialFile[BUFFER_SIZE];
char LinkName[BUFFER_SIZE];
char InitialDirectory[BUFFER_SIZE] = ".";
char Buffer[32];
int FilDes = -1;
int BytesRead;
int BytesWritten;
uid_t UserID;
void CleanUpOnError(int level)
{
printf("Encontrado error, borrando.\n");
switch ( level )
{
case 1:
printf("No se pudo obtener directorio de trabajo actual.\n");
break;
case 2:
printf("No se pudo crear el archivo %s.\n",TEST_FILE);
break;
case 3:
printf("No se pudo escribir en archivo %s.\n",TEST_FILE);
close(FilDes);
unlink(TEST_FILE);
break;
case 4:
printf("No se pudo cerrar el archivo %s.\n",TEST_FILE);
close(FilDes);
unlink(TEST_FILE);
break;
case 5:
printf("No se pudo crear el directorio %s.\n",NEW_DIRECTORY);
unlink(TEST_FILE);
break;
case 6:
printf("No se pudo cambiar de directorio para ir a %s.\n",NEW_DIRECTORY);
rmdir(NEW_DIRECTORY);
unlink(TEST_FILE);
break;
case 7:
printf("No se pudo crear enlace %s con %s.\n",LinkName,InitialFile);
chdir(PARENT_DIRECTORY);
rmdir(NEW_DIRECTORY);
unlink(TEST_FILE);
break;
case 8:
printf("No se pudo abrir el enlace %s.\n",LinkName);
unlink(LinkName);
chdir(PARENT_DIRECTORY);
rmdir(NEW_DIRECTORY);
unlink(TEST_FILE);
break;
case 9:
printf("No se pudo leer el enlace %s.\n",LinkName);
close(FilDes);
unlink(LinkName);
chdir(PARENT_DIRECTORY);
rmdir(NEW_DIRECTORY);
unlink(TEST_FILE);
break;
case 10:
printf("No se pudo cerrar el enlace %s.\n",LinkName);
close(FilDes);
unlink(LinkName);
chdir(PARENT_DIRECTORY);
rmdir(NEW_DIRECTORY);
unlink(TEST_FILE);
break;
case 11:
printf("No se pudo deshacer el enlace %s.\n",LinkName);
unlink(LinkName);
chdir(PARENT_DIRECTORY);
rmdir(NEW_DIRECTORY);
unlink(TEST_FILE);
break;
case 12:
printf("No se pudo cambiar de directorio para ir a %s.\n",PARENT_DIRECTORY);
chdir(PARENT_DIRECTORY);
rmdir(NEW_DIRECTORY);
unlink(TEST_FILE);
break;
case 13:
printf("No se pudo eliminar el directorio %s.\n",NEW_DIRECTORY);
rmdir(NEW_DIRECTORY);
unlink(TEST_FILE);
break;
case 14:
printf("No se pudo desenlazar el archivo %s.\n",TEST_FILE);
unlink(TEST_FILE);
break;
default:
break;
}
printf("El programa finalizó con error.\n"\
"Pueden no haberse eliminado todos los archivos y directorios de prueba.\n");
}
int main ()
{
1
/* Obtener e imprimir el ID de usuario real con la función getuid(). */
UserID = getuid();
printf("El ID de usuario real es %u. \n",UserID);
2
/* Obtener el directorio de trabajo actual y almacenarlo en InitialDirectory. */
if ( NULL == getcwd(InitialDirectory,BUFFER_SIZE) )
{
perror("Error getcwd");
CleanUpOnError(1);
return 0;
}
printf("El directorio de trabajo actual es %s. \n",InitialDirectory);
3
/* Crear el archivo TEST_FILE para escribir, si no existe.
Otorgar al propietario autorización de lectura, escritura y ejecución. */
FilDes = open(TEST_FILE, O_WRONLY | O_CREAT | O_EXCL, S_IRWXU);
if ( -1 == FilDes )
{
perror("Error open");
CleanUpOnError(2);
return 0;
}
printf("Creado %s en directorio %s.\n",TEST_FILE,InitialDirectory);
4
/* Escribir TEST_DATA en TEST_FILE por medio de FilDes */
BytesWritten = write(FilDes,TEST_DATA,strlen(TEST_DATA));
if ( -1 == BytesWritten )
{
perror("Error de escritura");
CleanUpOnError(3);
return 0;
}
printf("Escrito %s en archivo %s.\n",TEST_DATA,TEST_FILE);
5
/* Cerrar TEST_FILE por medio de FilDes */
if ( -1 == close(FilDes) )
{
perror("Error de cierre");
CleanUpOnError(4);
return 0;
}
FilDes = -1;
printf("Archivo %s cerrado.\n",TEST_FILE);
6
/* Crear un nuevo directorio en el directorio de trabajo actual y
otorgar al propietario autorización de lectura, escritura y ejecución */
if ( -1 == mkdir(NEW_DIRECTORY, S_IRWXU) )
{
perror("Error de mkdir");
CleanUpOnError(5);
return 0;
}
printf("Directorio %s creado en directorio %s.\n",NEW_DIRECTORY,InitialDirectory);
7
/* Cambiar el directorio de trabajo actual por el
directorio NEW_DIRECTORY recién creado. */
if ( -1 == chdir(NEW_DIRECTORY) )
{
perror("Error de chdir");
CleanUpOnError(6);
return 0;
}
printf("Se ha pasado al directorio %s/%s.\n",InitialDirectory,NEW_DIRECTORY);
/* Copiar PARENT_DIRECTORY en InitialFile y
añadir "/" y TEST_FILE a InitialFile. */
strcpy(InitialFile,PARENT_DIRECTORY);
strcat(InitialFile,"/");
strcat(InitialFile,TEST_FILE);
/* Copiar USER_ID en LinkName después añadir el
ID usuario como una serie a LinkName. */
strcpy(LinkName, USER_ID);
sprintf(Buffer, "%d\0", (int)UserID);
strcat(LinkName, Buffer);
8
/* Crear un enlace con el nombre de InitialFile con LinkName. */
if ( -1 == link(InitialFile,LinkName) )
{
perror("Error de enlace");
CleanUpOnError(7);
return 0;
}
printf("Creado un enlace %s con %s.\n",LinkName,InitialFile);
9
/* Abrir el archivo LinkName solo para lectura. */
if ( -1 == (FilDes = open(LinkName,O_RDONLY)) )
{
perror("Error open");
CleanUpOnError(8);
return 0;
}
printf("Abierto %s para lectura.\n",LinkName);
10
/* Leer en archivo LinkName, por medio de FilDes, en Buffer. */
BytesRead = read(FilDes,Buffer,sizeof(Buffer));
if ( -1 == BytesRead )
{
perror("Error de lectura");
CleanUpOnError(9);
return 0;
}
printf("%s leído en %s.\n",Buffer,LinkName);
if ( BytesRead != BytesWritten )
{
printf("AVISO: el número de bytes leídos "\
"no es igual al número de bytes escritos.\n");
}
11
/* Cerrar el archivo LinkName por medio de FilDes. */
if ( -1 == close(FilDes) )
{
perror("Error de cierre");
CleanUpOnError(10);
return 0;
}
FilDes = -1;
printf("Cerrado %s.\n",LinkName);
12
/* Desenlazar el enlace LinkName con InitialFile. */
if ( -1 == unlink(LinkName) )
{
perror("Error de desenlazar");
CleanUpOnError(11);
return 0;
}
printf("%s está desenlazado.\n",LinkName);
13
/* Cambiar el directorio de trabajo actual
de nuevo por el directorio inicial. */
if ( -1 == chdir(PARENT_DIRECTORY) )
{
perror("Error de chdir");
CleanUpOnError(12);
return 0;
}
printf("pasando del directorio al %s.\n",InitialDirectory);
14
/* Eliminar el directorio NEW_DIRECTORY */
if ( -1 == rmdir(NEW_DIRECTORY) )
{
perror("Error de rmdir");
CleanUpOnError(13);
return 0;
}
printf("Eliminando directorio %s.\n",NEW_DIRECTORY);
15
/* Desenlazar el archivo TEST_FILE */
if ( -1 == unlink(TEST_FILE) )
{
perror("Error de desenlazar");
CleanUpOnError(14);
return 0;
}
printf("Desenlazando archivo %s.\n",TEST_FILE);
printf("Programa terminado satisfactoriamente.\n");
return 0;
}