UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » C++
  • » Deaamonizzing problem

#1 2008-05-01 05:38 PM

reggler
Member
Registered: 2008-05-01
Posts: 3

Re: Deaamonizzing problem

Hi,

I have an application featuring a verbose mode and a daemon mode.
It's working just fine in verbose mode but in daemon mode it doesn't quite
seem to be functioning properly (doesn't send off signalss over TCP/IP or
write anything to the GPIOs - that's why i belive exit() is
terminating "too much"),
I get into Daemon mode with a fork command followed by exit() to be
specific, it looks like:
[C++]
pid = fork();
if (pid < 0)
{
exit(EXIT_FAILURE);
}
else if (pid > 0)
{
exit(EXIT_SUCCESS);
}

umask(0);

sid = setsid();
[/C++]
Is there a problem with this? Do I miss anything?
Someone already pointed out that an exit call would call any atexit() functions located in my app. I thought this may be the problem in my app  but a "grep atexit *" didn't return anything :( Does anyone of you guys have any idea?

Thanks you very much!
Ron

Offline

#2 2008-05-01 06:29 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,198

Re: Deaamonizzing problem

What exactly is your problem? Could you be more specific?
What happens after startup, is the daemon running or did
all processes quit? Or is the child process "stuck"?

You mention GPIO, are you working on an embedded OS,
if so which one? It might not be POSIX compliant or have
other strange quirks.

Offline

#3 2008-05-01 07:16 PM

reggler
Member
Registered: 2008-05-01
Posts: 3

Re: Deaamonizzing problem

i3839;24386 wrote:

What exactly is your problem? Could you be more specific?
What happens after startup, is the daemon running or did
all processes quit? Or is the child process "stuck"?


Well, the application just seems to be sitting there and not doing anything. I would have multiple threads going that would control the GPIOs and send off messages to a server over TCP/IP. But it's all quite, the GPIO thread seems to start and be terminated right after that. When i start up the app i get one message from the thread couted to the screen but nothing else, if i go ps x i still see the processes there tho but they're not doing anything :o.

i3839;24386 wrote:


You mention GPIO, are you working on an embedded OS,
if so which one? It might not be POSIX compliant or have
other strange quirks.


I'm using a PC 104 with an AMD Geode processor and we're using a standard gentoo linux distribution. This should all work fine and again: it works just fine if i don't deamonize it, my whole deamonize method looks like:
[C++]
void TDaemon::initDaemon()
{
    pid = fork();
    if (pid < 0)
    {
        exit(EXIT_FAILURE);
    }
    else if (pid > 0)
    {
        exit(EXIT_SUCCESS);
    }
   
    umask(0);

    sid = setsid();
   
    if (sid < 0)
    {
        std::cerr << "Failed to create a new SID for child process, exiting!\n";
        exit(EXIT_FAILURE);
    }
   
    if ((chdir("/")) < 0)
    {
        std::cerr << "Failed to change to root directory, exiting!\n";
        exit(EXIT_FAILURE);
    }

    int fdLockFile = open(lockFile.c_str(),O_RDWR | O_CREAT, 0600);
    if (fdLockFile < 0)
    {
        std::cerr << "Failed to open lockfile, exiting!\n";
        exit(EXIT_FAILURE);
    }
    if (lockf(fdLockFile,F_TLOCK,0) < 0)
    {
        std::cerr << "Failed to lock lockfile, exiting!\n";
        exit(EXIT_FAILURE);
    }
    char str[20];
    sprintf(str,"%d\n",getpid());
    write(fdLockFile,str,strlen(str));

    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
    int i=open("/dev/null",O_RDWR);
    dup(i);
    dup(i);
    //signal(SIGCHLD,SIG_IGN);
    //signal(SIGTSTP,SIG_IGN);
    //signal(SIGTTOU,SIG_IGN);
    //signal(SIGTTIN,SIG_IGN);
    //signal(SIGHUP,signal_handler);
    //signal(SIGTERM,signal_handler);
}
//***********************and this gets called by:
void TDaemon::startWork()
{
    sleep(3);
    initDaemon();
    sleep(2);
    work();// this starts the main thread
}
[C++]

Offline

#4 2008-05-01 07:49 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,753
Website

Re: Deaamonizzing problem

You should probably use _exit() instead of exit()...  Also, you probably should fork()
one more time after doing setsid(), to lose your session-leader status and ensure you
can't accidentally regain a controlling tty...  (And, you'll want to ignore SIGHUP while
doing so, to make sure your child process doesn't get hit with SIGHUP when the
session-leader parent exits...)

However, I don't know if any of that is related to your particular problem...

(Also, there is no "C++" tag here; use the "code" tag instead...)

Offline

#5 2008-05-01 08:56 PM

reggler
Member
Registered: 2008-05-01
Posts: 3

Re: Deaamonizzing problem

RobSeace;24391 wrote:

You should probably use _exit() instead of exit()...  Also, you probably should fork()
one more time after doing setsid(), to lose your session-leader status and ensure you
can't accidentally regain a controlling tty...  (And, you'll want to ignore SIGHUP while
doing so, to make sure your child process doesn't get hit with SIGHUP when the
session-leader parent exits...)

However, I don't know if any of that is related to your particular problem...

(Also, there is no "C++" tag here; use the "code" tag instead...)

We,, you know this application got written by someone else (actually a couple of guys prior to me) and I'm just here to extend the function and fix its bugs. So what i don't quite understand is this:

pid = fork();
	if (pid < 0)
	{
		_exit(EXIT_FAILURE);
	}
	else if (pid > 0)
	{
		_exit(EXIT_SUCCESS);
	}
	
	umask(0);

	sid = setsid();


Why do we call exit() in case the pid is greater 0 (success)? Doesn't this terminate the application? We sssstill cclose the STDIN and STDOUT on the bottom... :o
And why do we set umask(0);? Does it make any sense to take away all read/write rights? :o
Thanks for help!

Offline

#6 2008-05-01 10:22 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,753
Website

Re: Deaamonizzing problem

Why do we call exit() in case the pid is greater 0 (success)? Doesn't this terminate the application?

Yes, but only the parent...  fork() returns 0 to the new child process, while it returns
a positive value (the PID of the new child) to the parent (or negative on failure)...
So, this is standard daemonizing technique: the parent is always exiting, and the
child will keep running (if the fork() succeeded)...

However, it's still a good idea to repeat that same process once again after the
setsid(), or else you'll remain a session leader, which often isn't desirable for a
daemon...

We sssstill cclose the STDIN and STDOUT on the bottom... :o

That's the child (now the daemon) doing that...  And, it reopens them all to refer to
"/dev/null", which is also standard and recommended daemon procedure...

And why do we set umask(0);? Does it make any sense to take away all read/write rights?

It's not taking away any rights; it's fully opening up the umask...  This is something
usually done by apps which want to fully control the perms on any files they create,
without worrying about the umask messing with them at all...  Ie: whatever they pass
to open() as the mode will be used exactly...

Offline

#7 2008-05-01 10:53 PM

Nope
Administrator
From: Germany
Registered: 2004-01-24
Posts: 384
Website

Re: Deaamonizzing problem

I there.

Why don't you just use the

daemon(1,1);

command? That does exactly that, getting your program into deamon mode. The two values are flags telling if you still need to keep a connection to the starting terminal (for printing some stats on startup for example).

Offline

  • Index
  • » C++
  • » Deaamonizzing problem

Board footer

Powered by FluxBB