Ergebnis 1 bis 9 von 9

Thema: Daemon programmieren (C)

  1. #1
    Benutzer
    Registriert seit
    19.05.2005
    Beiträge
    32

    Daemon programmieren (C)

    Hi,
    Ich kenne mich leider noch nicht so gut mit C aus, vor allem bei "systemnahen" Sachen, also wie man z.B. eine PID grabbt und damit was anfängt oder was weiß ich - jedenfalls wollte ich wissen, wie man einen kleinen Daemon erstellen kann, also ein kleines Programm, das ständig im Hintergrund läuft.
    Ich habe schon einen Beispielcode irgendwo aus dem Internet hergekriegt, allerdings klappt dieser beim Kompilieren nicht, da für die Funktion setpgrp zu wenig Argumente vorhanden seien (im Quellcode stand allerdings nur "setpgrp()", also ohne Argumente). Ich selbst weiß natürlich nicht genau, was die diese Funktion bewirkt, deshalb würde ich gerne noch wissen - neben dem Quellcode - was diese Funktion macht. Zudem stand über darüber das Kommentar "vom tty loesen" - was ist dieses "tty"?
    Wäre sehr nett, wenn mir auch jemand die "neuen" Funktionen, die man für einen Daemon braucht, erklären könnte, damit ich weiß, was sie genau machen.

    Falls es jemanden interessiert: Hier ist der Beispielcode, den ich aus dem Internet hatte

    Code:
    /* 
       Beispiel Code zum erstellen eines Daemons 
       By Bastian Ballmann
       09.08.2003
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
    
    int main(void)
    {
      printf("Becoming a daemon...\n");
      
      // Dateihandles schliessen
      close(STDIN_FILENO);
      close(STDOUT_FILENO);
      close(STDERR_FILENO);
    
      // INT Signal ignorieren
      signal(SIGINT,SIG_IGN);
    
      // Fork in den Background und exit() Vaterprozess
      if(fork() != 0)
        {
          exit(0);
        }
    
      // Change working directory
      chdir("/");
    
      // Vom tty los loesen
      setpgrp();
    
      // Mach was oder auch nichts...
      while(1){}
    
      return 1;
    }

  2. #2
    Erfahrener Benutzer
    Registriert seit
    20.06.2003
    Beiträge
    689
    In unistd.h gibt es schon eine kleine Funktion, die diese komplette Aufgabe für dich übernimmt, und den Prozess in den Hintergrund schickt, dass er als Daemon weiterläuft.
    Code:
    int daemon(int nochdir, int noclose)
    Wenn nochdir 0 ist, dann setzt er das CWD auf / und wenn noclose 0 ist, dann leiter er stdout, stdin und stderr nach /dev/null um.
    Bei erfolgreichem "Daemonisieren" liefert die Funktion 0 zurück, andernfalls -1 (und setzt die errno Variable).
    Siehe auch daemon(3)

    MfG deki

  3. #3
    Benutzer
    Registriert seit
    19.05.2005
    Beiträge
    32
    Ähm, sorry, wenn ich so dumm frag: Braucht die Funktion noch irgendwelche Argumente o.Ä.? Und muss man noch irgendeine PID angeben oder setzt die Funktion das Programm, in dem die Funktion aufgerufen wird, in den Hintergrund?

    Aber schon mal danke, scheint wohl doch nicht so schwierig zu sein.

    EDIT
    Und muss ich eigentlich noch was machen? Im obigen Quellcode werden ja noch die Handles geschlossen und das Interrupt-Signal ignoiert (soweit ich das richtig verstehe...), muss ich das bei der daemon-Funktion auch machen, bzw. ist es nötig oder kann's auch weggelassen werden?

  4. #4
    Erfahrener Benutzer
    Registriert seit
    20.06.2003
    Beiträge
    689
    Original von Leye
    Ähm, sorry, wenn ich so dumm frag: Braucht die Funktion noch irgendwelche Argumente o.Ä.?
    Die Argumente für die Funktion hab ich doch beschrieben, das sind die beiden Integer in der Klammer.
    Und muss man noch irgendeine PID angeben oder setzt die Funktion das Programm, in dem die Funktion aufgerufen wird, in den Hintergrund?
    Richtig, der Prozess der die Funktion aufruft wird in den Hintergrund geschickt.

    Und muss ich eigentlich noch was machen? Im obigen Quellcode werden ja noch die Handles geschlossen und das Interrupt-Signal ignoiert (soweit ich das richtig verstehe...), muss ich das bei der daemon-Funktion auch machen, bzw. ist es nötig oder kann's auch weggelassen werden?
    STDIN, STDOUT und STDERR werden laut manpage nach /dev/null umgeleitet, also praktisch geschlossen.
    Das brauchst du also nicht mehr zu erledigen.
    SIGINT ignorieren könntest du noch machen, aber das bringt auch nicht so viel, da der Prozess ja im Hintergrund läuft und du über Strg-C kein SIGINT mehr schicken kannst.
    Und manuell sendet man normalerweise kein SIGINT (afaik).

  5. #5
    Benutzer
    Registriert seit
    19.05.2005
    Beiträge
    32
    Okay, vielen dank. :]
    (Dass die beiden von dir geschriebenen Argumente zwei Argumente für die Funktion ist, weiß ich, nur wollte ich eben fragen, ob es noch zusätzliche braucht. Nur so zur Info. )

    EDIT
    Achja, wie ist das denn jetzt mit dieser setpgrp-Funktion? Weißt du das eventuell auch?

  6. #6
    Benutzer
    Registriert seit
    19.05.2005
    Beiträge
    32
    Hi, ich hab leider noch ein Problem: Immer, wenn der Prozess dann im Hintergrund ist, verbraucht er sehr viel Resourcen. Gibt es eine Möglichkeit, den Prozess irgendwie ruhig zu stellen oder so? Ist nicht so passend, wenn ein Prozess die ganze Zeit viel Resourcen braucht.

  7. #7
    Erfahrener Benutzer
    Registriert seit
    20.06.2003
    Beiträge
    689
    Original von Leye
    Hi, ich hab leider noch ein Problem: Immer, wenn der Prozess dann im Hintergrund ist, verbraucht er sehr viel Resourcen. Gibt es eine Möglichkeit, den Prozess irgendwie ruhig zu stellen oder so? Ist nicht so passend, wenn ein Prozess die ganze Zeit viel Resourcen braucht.
    Liegts evtl. daran:
    // Mach was oder auch nichts...
    while(1){}
    SCNR 8)

    Also falls du in dem Prozess wirklich noch irgendeine Endlosschleife hast, dein Daemon aber nicht die ganze Zeit arbeitet kannst du ihn mit sleep/usleep/nanosleep für eine bestimmte Zeit lang schlafen legen.
    Das spart sehr viele Prozessor-Ressourcen
    Oder meinst du mit Ressourcenverbrauch den Arbeitsspeicher?
    Falls ja solltest du mal überprüfen, ob du reservierten Speicher auch wieder freigibst, wenn du ihn nicht mehr verwendest.

    MfG deki

  8. #8
    Benutzer
    Registriert seit
    19.05.2005
    Beiträge
    32
    Original von deki

    Liegts evtl. daran:
    // Mach was oder auch nichts...
    while(1){}
    SCNR 8)
    Arrgh, hast' mich erwischt.
    Naja, manchmal ist man etwas zerstreut, bzw. rechnet nicht mit den Folgen.

    Original von deki
    Falls ja solltest du mal überprüfen, ob du reservierten Speicher auch wieder freigibst, wenn du ihn nicht mehr verwendest.

    MfG deki
    Ja, das ist klar, wenigstens das vergess ich nicht.

  9. #9
    Erfahrener Benutzer Avatar von V10lator
    Registriert seit
    14.06.2004
    Beiträge
    124
    huhu,
    auch wenn das Thema schon ein wenig älter ist dachte ich mir ich schreib mal hier rein bevor ich ein neues thema aufmache, mein problem hat schliesslich grösstenteils auch mit der daemon funktion zu tun

    und zwar hab ich ein Programm geschrieben das als daemon arbeitet, und via fork() einen Sohn erstellt. Dieses Sohn kommuniziert nun über eine Pipe mit dem Vaterprozess.
    Da der Sohn sich nach einiger zeit via execlp mit einem anderen Programm überschreibt dachte ich mir zur besseren fehlererkennung könnte ich doch die Pipe als stdout / stderr benutzen, also 2 zeilen vor dem execlp befehl eingefügt:
    Code:
     dup2(pipeid[1],fileno(stdout));
    dup2(pipeid[1],fileno(stderr));
    Das ganze hat nicht funktioniert, nach einigem testen habe ich auch herausgefunden wieso nicht:
    wegem dem daemon befehl, ist der Prozess kein daemon kann ich stdout und stderr auf die pipe umlenken, ist er ein daemon nicht, nun meine frage: wie kann ich die 2 ausgaben umlenken wenn der prozess ein daemon ist?
    [align=center]Back to the roots
    http://counter.li.org/cgi-bin/certificate.cgi/506718[/align]

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •