GNU/Linux >> Tutoriales Linux >  >> Linux

Howto:programación en C con directorios en Linux

Cuando se dice que en Linux todo es archivo, entonces realmente es cierto. La mayoría de las operaciones que podemos hacer en los archivos se pueden hacer en otras entidades como socket, canalización, directorios, etc.

Hay ciertas situaciones en las que una utilidad de software puede tener que viajar a través de directorios en el sistema Linux para encontrar o emparejar algo. Este es el caso de uso donde el programador de esa utilidad tiene que lidiar con la programación de directorios. Entonces, en este artículo cubriremos los siguientes conceptos básicos de la programación de directorios con un ejemplo.

  1.  Creando directorios.
  2.  Lectura de directorios.
  3.  Eliminando directorios.
  4.  Cerrando el directorio.
  5.  Obteniendo el directorio de trabajo actual.

Revisaremos las funciones que se utilizan para cada paso anterior y, finalmente, veremos un ejemplo que resumirá todas las operaciones de directorio.

1. Creación de directorios

El sistema Linux proporciona la siguiente llamada al sistema para crear directorios:

#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode);

El argumento 'pathname' se usa para el nombre del directorio.

Desde la página del manual:

El modo de argumento especifica los permisos a utilizar. Se modifica por el umask del proceso de la forma habitual:los permisos del directorio creado son (mode &~umask &0777). Otros bits de modo del directorio creado dependen del sistema operativo. Para Linux, consulte a continuación.

El directorio recién creado será propiedad del ID de usuario efectivo del proceso. Si el directorio que contiene el archivo tiene establecido el bit set-group-ID, o si el sistema de archivos está montado con semántica de grupo BSD (mount -o bsdgroups o, como sinónimo, mount -o grpid), el nuevo directorio heredará la propiedad del grupo de su padre; de lo contrario, será propiedad del ID de grupo efectivo del proceso. Si el directorio principal tiene establecido el bit set-group-ID, también lo tendrá el directorio recién creado.

2. Directorios de lectura

Se utiliza una familia de funciones para leer el contenido del directorio.

1. Primero se debe abrir un flujo de directorio. Esto se hace mediante la siguiente llamada al sistema:

#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);

Desde la página del manual:

La función opendir() abre un flujo de directorio correspondiente al nombre del directorio y devuelve un puntero al flujo de directorio. El flujo se coloca en la primera entrada del directorio.

2. A continuación, para leer las entradas en el directorio, la siguiente llamada al sistema utiliza el flujo abierto anterior:

#include
struct dirent *readdir(DIR *dirp);

Desde la página del manual:

La función readdir() devuelve un puntero a una estructura directa que representa la siguiente entrada de directorio en el flujo de directorio al que apunta dirp. Devuelve NULL al llegar al final de la secuencia del directorio o si se produce un error.

En Linux, la estructura principal se define de la siguiente manera:

struct dirent
{
    ino_t          d_ino;       /* inode number */
    off_t          d_off;       /* offset to the next dirent */
    unsigned short d_reclen;    /* length of this record */
    unsigned char  d_type;      /* type of file; not supported
                                   by all file system types */
    char           d_name[256]; /* filename */
};

3. Eliminación de directorios

El sistema Linux proporciona la siguiente llamada al sistema para eliminar directorios:

#include <unistd.h>
int rmdir(const char *pathname);

Desde la página del manual:

rmdir() elimina el directorio representado por 'pathname' si está vacío. SI el directorio no está vacío, esta función no tendrá éxito.

4. Cerrar directorios

El sistema Linux proporciona la siguiente llamada al sistema para cerrar los directorios:

#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);

Desde la página del manual:

La función closedir() cierra el flujo de directorio asociado con dirp. Una llamada exitosa a closedir() también cierra el descriptor de archivo subyacente asociado con dirp. El descriptor de flujo de directorio dirp no está disponible después de esta llamada.

5. Obtener el directorio de trabajo actual

El sistema Linux proporciona la siguiente llamada al sistema para obtener el CWD:

#include <unistd.h>
char *getcwd(char *buf, size_t size);

Desde la página del manual:

La función getcwd() copia un nombre de ruta absoluto del directorio de trabajo actual a la matriz a la que apunta buf, que tiene un tamaño de longitud. Esta función devuelve una cadena terminada en nulo que contiene un nombre de ruta absoluto que es el directorio de trabajo actual del proceso de llamada. El nombre de la ruta se devuelve como el resultado de la función y mediante el argumento buf, si está presente. Si la longitud del nombre de la ruta absoluta del directorio de trabajo actual, incluido el byte nulo final, supera los bytes de tamaño, se devuelve NULL y errno se establece en ERANGE; una aplicación debe verificar este error y asignar un búfer más grande si es necesario.

6. Un ejemplo

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main (int argc, char *argv[])
{
    if(2 != argc)
    {
        printf("\n Please pass in the directory name \n");
        return 1;
    }

    DIR *dp = NULL;
    struct dirent *dptr = NULL;
    // Buffer for storing the directory path
    char buff[128];
    memset(buff,0,sizeof(buff));

    //copy the path set by the user
    strcpy(buff,argv[1]);

    // Open the directory stream
    if(NULL == (dp = opendir(argv[1])) )
    {
        printf("\n Cannot open Input directory [%s]\n",argv[1]);
        exit(1);
    }
    else
    {
        // Check if user supplied '/' at the end of directory name.
        // Based on it create a buffer containing path to new directory name 'newDir'
        if(buff[strlen(buff)-1]=='/')
        {
            strncpy(buff+strlen(buff),"newDir/",7);
        }
        else
        {
            strncpy(buff+strlen(buff),"/newDir/",8);
        }

        printf("\n Creating a new directory [%s]\n",buff);
        // create a new directory
        mkdir(buff,S_IRWXU|S_IRWXG|S_IRWXO);
        printf("\n The contents of directory [%s] are as follows \n",argv[1]);
        // Read the directory contents
        while(NULL != (dptr = readdir(dp)) )
        {
            printf(" [%s] ",dptr->d_name);
        }
        // Close the directory stream
        closedir(dp);
        // Remove the new directory created by us
        rmdir(buff);
        printf("\n");
    }

    return 0;
}

El ejemplo anterior ahora debería explicarse por sí mismo.

La salida del ejemplo anterior es:

# ./direntry /home/himanshu/practice/linux

 Creating a new directory [/home/himanshu/practice/linux/newDir/]

 The contents of directory [/home/himanshu/practice/linux] are as follows
 [redhat]  [newDir]  [linuxKernel]  [..]  [ubuntu]  [.]

Linux
  1. Supervise su sistema Linux en su terminal con procps-ng

  2. Mejore el rendimiento del sistema Linux con noatime

  3. Comprender las llamadas al sistema en Linux con strace

  4. Crear, eliminar y administrar directorios en Linux

  5. ¿Número máximo de archivos/directorios en Linux?

Cómo quitar (eliminar) directorio en Linux

Cómo comparar directorios con Meld en Linux

Comando de CD de Linux con ejemplos

Comando Uptime de Linux con ejemplos

Primeros pasos con el sistema operativo Linux

Conceptos básicos de la línea de comandos de Linux:trabajar con archivos y directorios