[linux] Daemonizen van een programma

Pagina: 1
Acties:

  • thrax
  • Registratie: Maart 2000
  • Laatst online: 18-06-2025
Ik ben voor linux/openbsd/netbsd een traffic monitoring tooltje aan het maken in c.

Dit bestaat uit twee delen: Een client die een aantal interfaces op een computer in de gaten houdt en de traffic logt naar een server programma en een server programma die de ontvangen data logt in een database.

Ik wil dat deze programma's op de achtergrond draaien. Nu werkt dat op zich wel, maar nog niet echt lekker.

Als ik het programma opstart, dan gaat ie naar de achtergrond toe en alles lijkt goed te gaan. In ps kan ik zien dat het process geen terminals meer heeft.

Maar als ik dan het terminal scherm afsluit dan blijft deze hangen om de een of andere reden. (ik gebruik putty vanuit windows om op een linux computer te editten) Ik moet putty echt afsluiten door hem te killen. Als ik mijn programma niet opstart dan is er niets aan de hand en sluit putty normaal af.

Dus het 'daemonizen' gaat niet goed.

Ik gebruik er nu de volgende code voor:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  if(!fork())
  {
   if(setsid() == -1)
   {
    LOG("Error: setsid() failed");
   }
   else
   {
    if(!fork())
    {
     chdir("/");
     umask(0);

     fclose(stdin);
     fclose(stdout);

     setvbuf(stdout, (char *)NULL, _IOLBF, 0);

     LOG("Becoming daemon");
    }
    else
    {
     LOG("Getting to background (1)");
     return 0;
    }
   }
  }
  else
  {
   LOG("Getting to background (2)");
   return 0;
  }

// Vanaf hier is het programma een daemon geworden


Dit komt vrijwel rechtstreeks uit een faq. Iemand een idee waarom dit niet goed gaat??

[ Voor 3% gewijzigd door thrax op 15-10-2003 22:41 ]

"Ore wa bakemono? Che, ore wa akuma da!"


  • Suepahfly
  • Registratie: Juni 2001
  • Laatst online: 13-08 14:09
Het lijkt er op dat je een stuk code mist.

Ik zie namelijk nergen een fopen() die verwacht ik wel aangezien er ook een fclose in je script staat.

Verder mist fork() denk ik ook een argument. Wat moet er geforked worden?
(forken is toch het 'daemonizen')

Ik ben verder geen linux, unix expert (eerder noob)
Ik kan wel een beetje programmeren, en denk dat dit script niet compleet is.

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 10-08 15:15
Ik zie twee forks() staan, is dit wel de bedoeling?
Wat bovendien vaak gedaan wordt is het heropenen van stdin, stdout naar /dev/null, omdat je de stdin en stdout van je parent mee krijgt en daar wil je denk ik niet meer naar schrijven.

(ik denk niet dat fclose stdin en stdout sluit? daarvoor heb je iets als close[2])

[ Voor 16% gewijzigd door Infinitive op 15-10-2003 23:06 ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • thrax
  • Registratie: Maart 2000
  • Laatst online: 18-06-2025
Infinitive schreef op 15 oktober 2003 @ 23:05:
Ik zie twee forks() staan, is dit wel de bedoeling?
Wat bovendien vaak gedaan wordt is het heropenen van stdin, stdout naar /dev/null, omdat je de stdin en stdout van je parent mee krijgt en daar wil je denk ik niet meer naar schrijven.

(ik denk niet dat fclose stdin en stdout sluit? daarvoor heb je iets als close[2])
Die twee forks zijn nodig volgens de unix programming faq die ik gelezen hebt. Als het geen functie heeft (de daemonize code van samba en ntop die ik bekeken heb doet ook maar een enkele fork) kan ie weg, maar het schaadt niet lijkt mij.

Die close ga ik ff proberen vanavond. :)

"Ore wa bakemono? Che, ore wa akuma da!"


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-08 00:10
Als het noodzakelijk is om output streams te sluiten, dan moet je waarschijnlijk ook stderr afsluiten. De traditionele demonization code zoals ik 'm ken gaat als volgt:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
    int i;

    /* Close file descriptors */
    for(i = 0; i < NOFILE; ++i)
        close(i);

    switch(fork())
    {
    case -1:            /* error! */
        break;

    default:            /* exit 1st parent */
        exit(0);

    case 0:            /* first child spawned */
        if(setsid() == -1)
             ;             /* error! */
        
        switch(fork())
        {
        case -1:            /* error! */
            break;

        default:            /* exit 2nd parent */
            exit(0);

        case 0:            /* second child spawned */
        }
    }

    /* demon process spawned succesfully! */
    umask(0);
}

Waarom de filedescriptors al van te voren geclosed worden weet ik niet meer, eigenlijk. Misschien is het idee dat ze dan niet meer gedupliceert hoeven te worden, maar dat lijkt me niet ontzettend nuttig. Ik denk dus dat het closen van de file descriptors prima op het eind kan. Verder lijkt me dan je in plaats van NOFILE gewoon 3 zou moeten kunnen gebruiken, om alleen stdin, stdout en stderr af te sluiten.

Het nut van de dubbele fork call zou ik desgevraagd nog wel op kunnen zoeken...

[ Voor 7% gewijzigd door Soultaker op 16-10-2003 10:22 ]


  • GarBaGe
  • Registratie: December 1999
  • Laatst online: 10:54
Je kan ook "screen" gebruiken om een virtuele venster aan een applicatie te hangen. Die kan je loskoppelen en later weer aankoppelen...
Hoef je dus niet perse een daemon te bakken, en dit werkt ook met tools die je NIET zelf geschreven hebt :-)

Ryzen9 5900X; 16GB DDR4-3200 ; RTX-4080S ; 7TB SSD


  • igmar
  • Registratie: April 2000
  • Laatst online: 29-06 18:56

igmar

ISO20022

thrax schreef op 15 October 2003 @ 22:38:

Ik wil dat deze programma's op de achtergrond draaien. Nu werkt dat op zich wel, maar nog niet echt lekker.
Ik gebruik er nu de volgende code voor:

code:
1
<snip>
Euh.. Hier hebben we de functie daemon() voor :)

[ Voor 5% gewijzigd door igmar op 16-10-2003 10:40 ]


  • igmar
  • Registratie: April 2000
  • Laatst online: 29-06 18:56

igmar

ISO20022

Infinitive schreef op 15 oktober 2003 @ 23:05:
Ik zie twee forks() staan, is dit wel de bedoeling?
Die tweede fork() wordt gedaan om zeker te weten dat je geen session leader bent, anders is de kans aanwezig dat je weer een controlling terminal krijgt, en da's nou net niet de bedoeling.

  • thrax
  • Registratie: Maart 2000
  • Laatst online: 18-06-2025
igmar schreef op 16 October 2003 @ 10:39:
[...]


Euh.. Hier hebben we de functie daemon() voor :)
:P

Maar is deze call portable? In de ntop en samba source gebruiken ze andere manieren. (Daemon code van andere projecten heb ik nog niet bekeken)

"Ore wa bakemono? Che, ore wa akuma da!"


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-08 00:10
Uit de daemon() man-page:
code:
1
2
HISTORY
       The daemon() function first appeared in BSD4.4.

Ik heb 'm op Linux en FreeBSD systemen gezien. Hoe portable 'ie is naar andere Unix'en weet ik niet; Windows is sowieso een probleem (maar de code op basis van forks is toch niet portable naar Windows).

[ Voor 5% gewijzigd door Soultaker op 16-10-2003 15:06 ]


  • igmar
  • Registratie: April 2000
  • Laatst online: 29-06 18:56

igmar

ISO20022

thrax schreef op 16 October 2003 @ 12:52:
Maar is deze call portable? In de ntop en samba source gebruiken ze andere manieren. (Daemon code van andere projecten heb ik nog niet bekeken)
Behoorlijk. Ik heb de daemon.c uit OpenBSD geleend, via een define kan ik die versie includen voor het geval de libc geen daemon() heeft.

  • thrax
  • Registratie: Maart 2000
  • Laatst online: 18-06-2025
Cool het werkt nu :)

Nadat ik close() had gebruikt om de stdin, stdout en stdout af te sluiten deed ie het ineens een stuk beter :)

De code die ik nu gebruik:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  close(STDIN_FILENO);
  close(STDOUT_FILENO);
  close(STDERR_FILENO); 
  if(!fork())
  {
   if(setsid() == -1)
   {
    LOG("setsid() failed");
   }
   else
   {
    if(!fork())
    {
     chdir("/");
     umask(0);

     LOG("Becoming daemon");
    }
    else
    {
     LOG("Getting to background 1");
    }
   }
  }
  else
  {
   LOG("Getting to background 2");
  }

[ Voor 11% gewijzigd door thrax op 16-10-2003 19:30 ]

"Ore wa bakemono? Che, ore wa akuma da!"

Pagina: 1