GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Howto:C-Programmierung mit Verzeichnissen unter Linux

Wenn gesagt wird, dass unter Linux alles eine Datei ist, dann ist das wirklich wahr. Die meisten Operationen, die wir mit Dateien durchführen können, können auch mit anderen Entitäten wie Sockets, Pipes, Verzeichnissen usw. durchgeführt werden.

Es gibt bestimmte Situationen, in denen ein Software-Dienstprogramm möglicherweise Verzeichnisse im Linux-System durchqueren muss um etwas zu finden oder zuzuordnen. Dies ist der Anwendungsfall, bei dem sich der Programmierer dieses Dienstprogramms mit der Verzeichnisprogrammierung befassen muss. Daher behandeln wir in diesem Artikel die folgenden Grundlagen der Verzeichnisprogrammierung anhand eines Beispiels.

  1.  Verzeichnisse erstellen.
  2.  Leseverzeichnisse.
  3.  Entfernen von Verzeichnissen.
  4.  Schließen des Verzeichnisses.
  5.  Das aktuelle Arbeitsverzeichnis abrufen.

Wir werden die Funktionen durchgehen, die für jeden obigen Schritt verwendet werden, und schließlich sehen wir ein Beispiel, das alle Verzeichnisoperationen zusammenfasst.

1. Verzeichnisse erstellen

Das Linux-System bietet den folgenden Systemaufruf zum Erstellen von Verzeichnissen:

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

Das Argument „Pfadname“ wird für den Namen des Verzeichnisses verwendet.

Aus der Manpage :

Das Argument mode gibt die zu verwendenden Berechtigungen an. Es wird auf die übliche Weise von der umask des Prozesses modifiziert:Die Berechtigungen des erstellten Verzeichnisses sind (mode &~umask &0777). Andere Modusbits des erstellten Verzeichnisses hängen vom Betriebssystem ab. Für Linux siehe unten.

Das neu erstellte Verzeichnis gehört der effektiven Benutzer-ID des Prozesses. Wenn das Verzeichnis, das die Datei enthält, das set-group-ID-Bit gesetzt hat oder wenn das Dateisystem mit BSD-Gruppensemantik gemountet ist (mount -o bsdgroups oder synonym mount -o grpid), erbt das neue Verzeichnis den Gruppenbesitz von sein Elternteil; andernfalls gehört es der effektiven Gruppen-ID des Prozesses. Wenn im übergeordneten Verzeichnis das set-group-ID-Bit gesetzt ist, wird dies auch im neu erstellten Verzeichnis der Fall sein.

2. Verzeichnisse lesen

Eine Familie von Funktionen wird verwendet, um den Inhalt des Verzeichnisses zu lesen.

1. Zuerst muss ein Verzeichnisstream geöffnet werden. Dies geschieht durch den folgenden Systemaufruf:

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

Aus der Manpage :

Die Funktion opendir() öffnet einen Verzeichnisstrom, der dem Verzeichnisnamen entspricht, und gibt einen Zeiger auf den Verzeichnisstrom zurück. Der Stream wird am ersten Eintrag im Verzeichnis positioniert.

2. Um als nächstes die Einträge im Verzeichnis zu lesen, wird der oben geöffnete Stream durch den folgenden Systemaufruf verwendet:

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

Aus der Manpage :

Die Funktion readdir() gibt einen Zeiger auf eine dirent-Struktur zurück, die den nächsten Verzeichniseintrag im Verzeichnisstrom darstellt, auf den dirp zeigt. Es gibt NULL zurück, wenn das Ende des Verzeichnisstroms erreicht wird oder wenn ein Fehler aufgetreten ist.

Unter Linux ist die dirent-Struktur wie folgt definiert:

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. Verzeichnisse entfernen

Das Linux-System bietet den folgenden Systemaufruf zum Entfernen von Verzeichnissen:

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

Aus der Manpage :

rmdir() entfernt das durch „Pfadname“ dargestellte Verzeichnis, wenn es leer ist. Wenn das Verzeichnis nicht leer ist, wird diese Funktion nicht erfolgreich sein.

4. Verzeichnisse schließen

Das Linux-System stellt den folgenden Systemaufruf bereit, um die Verzeichnisse zu schließen:

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

Aus der Manpage :

Die Funktion closedir() schließt den dirp zugeordneten Verzeichnisstrom. Ein erfolgreicher Aufruf von closedir() schließt auch den zugrunde liegenden Dateideskriptor, der dirp zugeordnet ist. Der Verzeichnis-Stream-Deskriptor dirp ist nach diesem Aufruf nicht verfügbar.

5. Abrufen des aktuellen Arbeitsverzeichnisses

Das Linux-System stellt den folgenden Systemaufruf bereit, um die CWD abzurufen:

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

Aus der Manpage :

Die Funktion getcwd() kopiert einen absoluten Pfadnamen des aktuellen Arbeitsverzeichnisses in das Array, auf das buf zeigt, das die Länge size hat. Diese Funktion gibt einen nullterminierten String zurück, der einen absoluten Pfadnamen enthält, der das aktuelle Arbeitsverzeichnis von ist Aufrufprozess. Der Pfadname wird als Funktionsergebnis und über das Argument buf, falls vorhanden, zurückgegeben. Wenn die Länge des absoluten Pfadnamens des aktuellen Arbeitsverzeichnisses einschließlich des abschließenden Nullbytes size bytes überschreitet, wird NULL zurückgegeben und errno auf ERANGE gesetzt; eine Anwendung sollte auf diesen Fehler prüfen und gegebenenfalls einen größeren Puffer zuweisen.

6. Ein Beispiel

#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;
}

Das obige Beispiel sollte nun selbsterklärend sein.

Die Ausgabe des obigen Beispiels ist:

# ./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. Überwachen Sie Ihr Linux-System in Ihrem Terminal mit procps-ng

  2. Verbessern Sie die Linux-Systemleistung mit noatime

  3. Systemaufrufe unter Linux mit strace verstehen

  4. Erstellen, Löschen und Verwalten von Verzeichnissen unter Linux

  5. Planen von Systemaufgaben mit Cron unter Linux

So entfernen (löschen) Sie das Verzeichnis in Linux

So vergleichen Sie Verzeichnisse mit Meld unter Linux

Linux-CD-Befehl mit Beispielen

Linux-Verfügbarkeitsbefehl mit Beispielen

Erste Schritte mit dem Linux-Betriebssystem

Grundlagen der Linux-Befehlszeile – Arbeiten mit Dateien und Verzeichnissen