LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   damon programming....Why cant my daemon create files? (https://www.linuxquestions.org/questions/programming-9/damon-programming-why-cant-my-daemon-create-files-425317/)

vimes 03-16-2006 04:12 AM

damon programming....Why cant my daemon create files?
 
Hi all,

I am rather new to programming under the Linux environment and so far I am having lotsa fun, so I apologise if this question is really stupid. I am experimenting with daemon programming and have run into a snag. For some reason my daemon is not able to create files. I wanted to use a file to monitor the aplication but have so far been unable to achieve this. I also attempted to use syslog, but no log file was created. The code is below. The daemon runs, so it is not exiting at the file opening sequence, but no file is created.


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <string.h>

int main(void)
{
pid_t pid = -1;
pid_t sid = -1;
int fileDesc = -1;
FILE *pFilePointer;
struct rlimit resourceLimit = { 0 };

pid = fork();

if(pid < 0)
{
puts("incorrect PID, exiting");
exit(EXIT_FAILURE);
}

if(pid > 0)
{
puts("correct PID, starting daemon");
exit(EXIT_SUCCESS);
}

resourceLimit.rlim_max = 0;
status = getrlimit(RLIMIT_NOFILE, &resourceLimit);
int control = 1;
if (-1 == status)
{
perror(getrlimit());
exit(EXIT_FAILURE);
}

if (0 == resourceLimit.rlim_max)
{
puts("Max number of open file descriptors is 0!");
exit(EXIT_FAILURE);
}

for (i = 0; i < resourceLimit.rlim_max; i++)
close(i);


sid = setsid();

if(sid < 0)
exit(EXIT_FAILURE);

pid = fork();

if(pid < 0)
{
puts("incorrect PID, exiting");
exit(EXIT_FAILURE);
}

if(pid > 0)
{
puts("correct PID, starting daemon");
exit(EXIT_SUCCESS);
}

if((chdir("/")) < 0)
exit(EXIT_FAILURE);

umask(0);

close(STDIN_FINENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);

if((pFilePointer = fopen("output.log", "w")) == NULL)
exit(EXIT_FAILURE);

while(1)
{
fprintf(pFilePointer, "daemon running\n");
sleep(1000);
}

fclose(pFilePointer);

exit(EXIT_SUCCESS);
}

Hko 03-16-2006 04:29 AM

Compiling your code results in too many errors.
e.g. with you forgot:
#include <sys/time.h>
#include sys/resource.h>

But after that fixed I still get:
Code:

daemon.c:36: error: `status' undeclared (first use in this function)
daemon.c:36: error: (Each undeclared identifier is reported only once
daemon.c:36: error: for each function it appears in.)
daemon.c:40: error: too few arguments to function `getrlimit'
daemon.c:40: warning: passing arg 1 of `perror' makes pointer from integer without a cast
daemon.c:49: error: `i' undeclared (first use in this function)
daemon.c:75: error: `STDIN_FINENO' undeclared (first use in this function)


vimes 03-16-2006 04:34 AM

I just tried tested it again. I compile with g++ (my file extension is cpp)so maybe that is the differance? But it definately compiles on my system. I also renamed it to a .c extension and it sucessfully compiled with gcc ???????????? As i said i am rather new at this so i have no idea why it wont compile by you.

Hko 03-16-2006 05:32 AM

Hmm, I cannot compile it at all...
Anyways, here's a daemon similar to yours, but simpler.
Maybe the comments will help you to find the bug(s) in yours, or use this to start your own program.

Best compiled with:
Code:

gcc -Wall -pedantic -o demon demon.c
Code:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
    FILE *pFilePointer;

    /*
    * The function daemon() takes care of all the forking and stuff needed to
    * become a daemon. Just easier, and known to be correct.
    */
    if (daemon(0, 0) < 0) {
        perror("While trying to become daemon");
        return 1;
    }

    /*
    * If this is run as a non-priviledged user, the log file cannot be created
    * because the working directory now is / where we don't have write
    * permission. So we create the file in /tmp instead, where we will most
    * probably have write permission.
    *
    * At this point we don't have stdout anymore, so we cannot even
    * output an error (e.g. "persmission denied") except for syslog
    * of course, but we're not using syslog here (yet) for
    * simplicity.
    */
    if ((pFilePointer = fopen("/tmp/output.log", "w")) == NULL) {
        return 1;
    }

    /*
    * Loop until we get killed.
    */
    while (1) {
        fprintf(pFilePointer, "daemon running at PID: %d\n", getpid());
        fflush(pFilePointer);  /* Make sure the line is actually written */
        sleep(5);  /* Loop every 5 seconds. */
    }

    /*
    * We never get here because the daemon will eventually be killed.
    * So fclose() will never be called, hence the stdio buffer will
    * will not be flushed to disk. That's why we call fflush() above
    * after every line written to the log file.
    *
    * Another solution to this might be to catch the signals, and
    * call fclose() end exit excplicitly when a signal is received.
    * More complicated, but better.
    */

    fclose(pFilePointer);  /* Never called */
    return 0;
}


vimes 03-16-2006 05:38 AM

Thank you very much for your reply. This metod looks much cleaner and simpler.


All times are GMT -5. The time now is 06:13 PM.