LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 01-15-2008, 04:02 PM   #1
GigaRoc
LQ Newbie
 
Registered: Dec 2006
Posts: 7

Rep: Reputation: 0
Daemonizing in C Help


Code:
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <inotifytools/inotifytools.h>
#include <inotifytools/inotify.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <syslog.h>
#include <errno.h>
#include <pwd.h>
#include <signal.h>


#define DAEMON_NAME "gnotify"

/* Change this to the user under which to run */
#define RUN_AS_USER "gigaroc"

#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1

FILE *oFile;

static void child_handler(int signum)
{
    switch(signum) {
    case SIGALRM: exit(EXIT_FAILURE); break;
    case SIGUSR1: exit(EXIT_SUCCESS); break;
    case SIGCHLD: exit(EXIT_FAILURE); break;
    }
}

static void daemonize( const char *lockfile )
{
    pid_t pid, sid, parent;
    int lfp = -1;

    /* already a daemon */
    if ( getppid() == 1 ) return;
    /* Create the lock file as the current user */
    if ( lockfile && lockfile[0] ) {
        lfp = open(lockfile,O_RDWR|O_CREAT,0640);
        if ( lfp < 0 ) {
            syslog( LOG_ERR, "unable to create lock file %s, code=%d (%s)",
                    lockfile, errno, strerror(errno) );
            exit(EXIT_FAILURE);
		}
    }
    /* Drop user if there is one, and we were run as root */
    if ( getuid() == 0 || geteuid() == 0 ) {
        struct passwd *pw = getpwnam(RUN_AS_USER);
        if ( pw ) {
            syslog( LOG_NOTICE, "setting user to " RUN_AS_USER );
            setuid( pw->pw_uid );
        }
    }
    /* Trap signals that we expect to recieve */
    signal(SIGCHLD,child_handler);
    signal(SIGUSR1,child_handler);
    signal(SIGALRM,child_handler);
    /* Fork off the parent process */
    pid = fork();
    if (pid < 0) {
        syslog( LOG_ERR, "unable to fork daemon, code=%d (%s)",
                errno, strerror(errno) );
        exit(EXIT_FAILURE);
    }
    /* If we got a good PID, then we can exit the parent process. */
    if (pid > 0) {

        /* Wait for confirmation from the child via SIGTERM or SIGCHLD, or
           for two seconds to elapse (SIGALRM).  pause() should not return. */
        alarm(2);
        pause();

        exit(EXIT_FAILURE);
    }
    /* At this point we are executing as the child process */
    parent = getppid();

    /* Cancel certain signals */
    signal(SIGCHLD,SIG_DFL); /* A child process dies */
    signal(SIGTSTP,SIG_IGN); /* Various TTY signals */
    signal(SIGTTOU,SIG_IGN);
    signal(SIGTTIN,SIG_IGN);
    signal(SIGHUP, SIG_IGN); /* Ignore hangup signal */
    signal(SIGTERM,SIG_DFL); /* Die on SIGTERM */

    /* Change the file mode mask */
    umask(0);
    /* Create a new SID for the child process */
    sid = setsid();
    if (sid < 0) {
        syslog( LOG_ERR, "unable to create a new session, code %d (%s)",
                errno, strerror(errno) );
        exit(EXIT_FAILURE);
    }
    /* Change the current working directory.  This prevents the current
       directory from being locked; hence not being able to remove it. */
    if ((chdir("/")) < 0) {
        syslog( LOG_ERR, "unable to change directory to %s, code %d (%s)",
                "/", errno, strerror(errno) );
        exit(EXIT_FAILURE);
    }
    /* Redirect standard files to /dev\null */
   /* taken out for now
   freopen( "/dev\null", "r", stdin);
   freopen( "/dev\null", "w", stdout);
   freopen( "/dev\null", "w", stderr);
   */

    /* Tell the parent process that we are A-okay */
    kill( parent, SIGUSR1 );
}
int main() {
        /* Initialize the logging interface */
		openlog( DAEMON_NAME, LOG_PID, LOG_LOCAL5 );
		syslog( LOG_INFO, "starting" );

		 /* One may wish to process command line arguments here */

		/* Daemonize */
		daemonize( "/var/lock/subsys/" DAEMON_NAME );

		/* Main program */

		/* open outfile */

	    oFile = fopen ("/etc/gnotify/events.log", "wt");
		fprintf (oFile, "File Initialized\n");

		/*Set events we are watching */
	    int eventnum = IN_MODIFY | IN_MOVED_FROM | IN_MOVED_TO | IN_CREATE | IN_DELETE ;

		/* initialize and watch the entire directory tree from the current working
           directory downwards for all events */
        if ( !inotifytools_initialize()
          || !inotifytools_watch_recursively( "/mnt/", eventnum ) ) {
                fprintf(stderr, "%s\n", strerror( inotifytools_error() ) );
                return -1;
        }
		/*set time format to 24 hour time, HH:MM:SS*/
        inotifytools_set_printf_timefmt( "%T" );
        /*Output all events as "<timestamp> <path> <events>"*/
        struct inotify_event * event = inotifytools_next_event( -1 );
        while ( event ) {
			/*Gets time from the time.h and cuts it up for output later*/
				char* gTime="";
				char gDay[3]="";
				char gMonth[4]="";
				char gYear[5]="";
				char gTime1[26];
				time_t timer;
				timer=time(NULL);
				gTime = asctime(localtime(&timer));
				strcpy(gTime1,gTime);
				gMonth[0] = gTime1[4];
				gMonth[1] = gTime1[5];
				gMonth[2] = gTime1[6];
				gDay[0] = gTime1[8];
				gDay[1] = gTime1[9];
				gYear[0] = gTime1[20];
				gYear[1] = gTime1[21];
				gYear[2] = gTime1[22];
				gYear[3] = gTime1[23];

				/*output handled in two steps */
			    fprintf(oFile,"%s %s %s ",gDay,gMonth,gYear);
                inotifytools_fprintf(oFile,event, "%T %w%f %e\n" );
                event = inotifytools_next_event( -1 );
				/*because the file is always running we need to update the log file at all times*/
				fflush( oFile );
        }
		printf("Program Exiting\n");
		fclose(oFile);
		syslog( LOG_NOTICE, "terminated" );
		closelog();
		return 0;
}
ok, here's the problem: the program doesn't output anything
At first i noticed that i was re-directing std output to NULL so i commented that out
And i can still output to the command prompt, but i can not out put to a file

Also the program seems to terminate after the first fprintf

i know because i had a lot of printf("here *description*\n"); that i took out

it's been a while since i have programmed so it's possible that it's a logic error on my part

Thank you for your help ^_^

Kevin
 
Old 01-17-2008, 05:21 AM   #2
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,287

Rep: Reputation: 173Reputation: 173
here's a bare bones daemonizer if you're interested

(based on the Stevens book)
Code:
#include <unistd.h>
#include <libgen.h>
#include        <sys/types.h>
#include        <sys/stat.h>
#include        <fcntl.h>

int usage(char * progname)
{
    char * fmt = "\n\
\n\
daemon\n\
~~~~~~\n\
put a command like, into the background\n\
like, with no controlling terminal\n\
so as it like, won't log off when you do\n\
\n\
\n\
    usage %s: command [args]\n\
                        \n\
\n";

    
    printf( fmt, basename(progname));
    exit(1);

}
int main(int argc, char **argv)
{
        pid_t   pid;


        if(argc < 2) usage(*argv);

        if ( (pid = fork()) < 0)
                return(-1);
        else if (pid != 0) {
            printf("%d\n", pid);
                exit(0);}       /* parent goes bye-bye */

        /* child continues */
        setsid();       /* become session leader */

        chdir("/");     /* change working directory */

        umask(0);       /* clear our file mode creation mask */

        argv++;
        execvp(*argv, argv);
        perror(*argv);
        return(0);
}
 
  


Reply

Tags
daemon


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
A general question on daemonizing a process Sathya Programming 2 01-04-2008 02:15 PM


All times are GMT -5. The time now is 01:32 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration