Die Funktion main

Willemers Informatik-Ecke

Zunächst soll der Rahmen betrachtet werden, in dem sich ein Programm bewegt. Das ist zwar eigentlich nicht Bestandteil der Systemaufrufe, gibt aber einen ersten Einblick, in welcher Umgebung sich ein Programm unter UNIX bewegt. Ein C-Programm wird immer mit der Funktion main() gestartet. Diese hat drei Parameter, von denen normalerweise nur die ersten beiden verwendet werden. Der dritte Parameter hält das Environment, das aber auch per getenv() gelesen werden kann.

int main(int argc, char **argv)
{
    return 0;
}

Aufrufparameter

argv enthält die Aufrufparameter

In der Variablen argc steht nach dem Start, wieviele Parameter bei Aufruf des Programmes übergeben wurden. Dieser Wert ist immer mindestens 1, da auch der Name, unter dem das Programm aufgerufen wurde, als Parameter zählt. Die Variable argv ist ein Array von Strings. Die Programmparameter werden von der Shell an den Leerzeichen zerlegt und dann einzeln an das Programm weitergereicht. Beispiel:

tudochwas -f huhu lol*

Wenn im aktuellen Verzeichnis die Dateien lolita}, lolli und lonzo stehen, sind die Parameter von main folgendermaßen belegt: In argc steht eine 5. Im Element argv[0] findet sich der Name des Programmes inklusive Pfad, in diesem Fall >>./tudochwas<<. Da tudochwas aus dem aktuellen Verzeichnis gestartet wurde und kein Pfad angegeben wurde, bemühte die Shell die Variable PATH. Darin fand sie dann den Pfad . und setzte ihn vor den Programmnamen. argv[1] enthält die Option -f und argv[2] den Parameter >>huhu<<. Die weiteren Elemente von argv hängen von den Dateien im aktuellen Verzeichnis ab. Da auf lol* sowohl lolita als auch lolli passen, füllen diese die nächsten zwei argv-Elemente.

argv[0] ist der Programmname

Da das erste Element in argv immer der Name ist, mit dem das Programm aufgerufen wurde, kann man dem Programm Optionen durch den Befehlsnamen mitgeben. So entspricht beispielsweise der Befehl uncompress dem Aufruf compress -d. Das erreicht man, indem ein Link namens uncompress auf compress erzeugt wird. So ein Link kostet unter UNIX nur einen Verzeichniseintrag mehr. Das Programm prüft beim Start, ob es unter dem Namen uncompress aufgerufen wurde und fügt in diesem Fall die Option -d hinzu.

Wildcards überlässt man der Shell

An den letzten Argumenten erkennt man, dass der Stern unter UNIX von der Shell aufgelöst wird. Dadurch ist erreicht, dass alle Programme von Haus aus die Wildcards der Shell gleichermaßen interpretieren, da sie sie selbst nicht auswerten. Das folgende kleine Programm zeigt die Aufrufparameter an:

int main(int argc, char **argv)
{
int i;
  for (i=0; i<argc; i++) {
    puts(argv[i]);
  }
  return 0;
}

Rückgabewert ist der Fehlercode

Auch der Rückgabewert der Funktion main ist von Bedeutung. Gibt sie 0 zurück, wird dies als fehlerfreier Ablauf gewertet. Alle anderen Werte sin Hinweis auf einen Fehler bei der Ausführung. Gerade wenn Fehler entstehen, ist es oft sehr umständlich, wieder zur Funktion main zurückzukehren. Hier hilft die Funktion exit. Sie beendet das Programm und der Übergabeparameter wird als Rückgabewert an den Aufrufer des Programms weitergereicht.

Zugriff auf die Umgebungsvariablen

Der bislang nicht erwähnte dritte Parameter von main zeigt auf die Umgebungsvariablenliste. Schon wie bei argv handelt es sich um ein Array von Zeichenketten. Da hier allerdings die Anzahl in einem separaten Parameter mitgeteilt wird, muss es eine andere Form der Endekennung geben. Der Zeiger nach dem letzten Eintrag hat den Wert 0. Mit dem Beispielprogramm wird die komplette Liste der Umgebungsvariablen angezeigt.

main(int argc, char **argv, char **env)
{
int i;
char *str;

    if (env) {
        i=0;
        while(str = env[i]) {
            puts(env[i++]);
        }
    }
}

Wer das Programm startet bekommt eine riesige Liste, von der hier nur ein kurzer Ausschnitt angezeigt wird:

WINDOWMANAGER=/usr/X11R6/bin/kde
HOME=/home/arnold
TERM=xterm
XNLSPATH=/usr/X11R6/lib/X11/nls
no_proxy=localhost

Umgebung über globale Variable

Dieser dritte Parameter ist relativ unbekannt, da man auch über die externe, globale Variable environ auf die gleiche Liste zugreifen kann. Aus diesem Grund hat sich POSIX auch auf die Variante mit zwei Parametern festgelegt.

Einzelne Umgebungsvariablen setzen und lesen

Im Normalfall wird man allerdings mit der kompletten Liste wenig anfangen wollen, sondern man braucht eine spezielle Umgebungsvariable. Dazu verwendet man die Funktion getenv().

#include <stdlib.h>

    char *getenv(const char *name);
    int putenv(const char *string);

Sofern die als Parameter angegebene Variable gesetzt ist, bekommt man einen Zeiger auf den Wert zurückgeliefert. Da dieser Zeiger beim nächsten Aufruf von getenv verloren gehen kann, sollte man das Ergebnis in eine lokale Variable kopieren, wenn man ihn später noch braucht. Es ist auch möglich, vom Programm aus Umgebungsvariablen zu setzen. Dazu dient die Funktion setenv(). Als Parameter erwartet sie einen vollständigen Variableneintrag der Form var=wert. Beispiel:

putenv("TERM=vt100");

Diese Seite basiert auf Inhalten aus dem Buch Arnold Willemer: Wie werde ich UNIX-Guru
Verlagsrechte bei galileo computing


Homepage (C) Copyright 2002 Arnold Willemer