PDA

View Full Version : Daemonizing a Qt application



topquarck
31st December 2009, 15:10
Greetings;

I am trying to create a background application (starts with system startup, and keeps running in the background ) under linux. the only solution i found is to make it as daemon.
searching the internet about how to create a daemon (http://www.enderunix.org/docs/eng/daemon.php) , I built a small app around my findings.



#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include "globaldefs.h"

void log_message(char *filename,char *message)
{
FILE *logfile;
logfile=fopen(filename,"a");
if(!logfile) return;
fprintf(logfile,"%s\n",message);
fclose(logfile);
}


/**
a signal handler for the Linux signals sent to daemon process,
for more signals, refer to http://www.comptechdoc.org/os/linux/programming/linux_pgsignals.html
*/
void signal_handler(int sig)
{
switch(sig) {
case SIGHUP:
log_message(LOG_FILE,"hangup signal catched");
break;
case SIGTERM:
log_message(LOG_FILE,"terminate signal catched");
break;
}
}

/**
create background process out of the application, source code taken from: http://www.enderunix.org/docs/eng/daemon.php
with some minor modifications
*/
void init_daemon()
{
int i,lfp;
char str[10];
if(getppid()==1)
return; /* already a daemon */
i=fork();
if (i<0)
exit(1); /* fork error */
if (i>0)
exit(0); /* parent exits */

/* child (daemon) continues */
setsid(); /* obtain a new process group */

for (i=getdtablesize();i>=0;--i)
close(i); /* close all descriptors */
i=open("/dev/null",O_RDWR); dup(i); dup(i); /* handle standart I/O */

umask(027); /* set newly created file permissions */

chdir(RUNNING_DIR); /* change running directory */
lfp=open(LOCK_FILE,O_RDWR|O_CREAT,0640);
if (lfp<0)
exit(1); /* can not open */
if (lockf(lfp,F_TLOCK,0)<0)
exit(0); /* can not lock */
/* first instance continues */
sprintf(str,"%d\n",getpid());
write(lfp,str,strlen(str)); /* record pid to lockfile */
signal(SIGCHLD,SIG_IGN); /* ignore child */
signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
signal(SIGHUP,signal_handler); /* catch hangup signal */
signal(SIGTERM,signal_handler); /* catch kill signal */
}
int main(int argc, char *argv[])
{
// first, create the daemon
init_daemon();
QCoreApplication a(argc, argv);

return a.exec();
}

the code doesn't handle signals (for example, a termination signal). So, when I run it from the command line, and try to kill it, it refuses to get killed!!! the only way to kill the process is to restart my machine!!
I really suspect that creating a QCoreApplication instance in the main method forks a new process other than the one i forked in the init_daemom() method.
When I try to debug the application. it fails tp fork a new process thus exit() is issued and the debugging session terminates.

I am using Qt 4.5 under ubuntu 9.04
What am I missing? can there be anything done to make my Qt application run as a daemon process ?? Am i using a wrong way to do so?

thanks in advance;

ecanela
1st January 2010, 00:36
try to use the follow Qt add-on
http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Utilities/qtservice/

use for create daemon in windows and linux,

hope that find this useful

squidge
1st January 2010, 02:38
Just run your normal executable with &

./yourexe &

or, if you don't process SIGHUP

nohup ./yourexe &

thats it. Nothing special needs to be done (So you don't need 'inidaemon' function)

To kill, even if you trap signals like in your app above, just use kill:

kill -9 <pid>

You can't ignore or protect against kill -9

nateriver
1st January 2010, 04:47
Just run your normal executable with &

./yourexe &

You should also add a command line switch to your application to suppress console output in this case, since '&' just starts executable in background and still connects current tty device to its stdout and stderr. Thus if you run your application this way you will still see it's log messages output (unless you log out).
Or you can manually redirect output with '>'.

ChrisW67
1st January 2010, 07:28
I'm not a guru UNIX programmer by any stretch but it seems that your setup routine connects the HUP and TERM signals (line 72-3) to a signal handler that does nothing with them except output a message and return. Consequently, the program does not exit for either signal.

namus
14th October 2010, 11:17
How to add the QtService add-on ?

namus
14th October 2010, 11:31
How to communicate from qt to this daemon in the above code?