LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Daemonizing in C Help (https://www.linuxquestions.org/questions/programming-9/daemonizing-in-c-help-613802/)

GigaRoc 01-15-2008 04:02 PM

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

bigearsbilly 01-17-2008 05:21 AM

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);
}



All times are GMT -5. The time now is 04:12 PM.