Let’s say you want to run a daemon. And, for some reasons, you want to launch it using Java. For example, you have lots of preinitialization steps already written and code itself is Java based). In that case, execution schema will look like picture below

What we need here, is C based daemon stub. Code that will “daemonize” Java process.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
#include <unistd.h> #include <sys/stat.h> #include <stdlib.h> #include "jni.h" #include "recipeNo022_Daemon.h" /* How to demonize your code propely, google a little bit. In this sample, we simply fork and don't care about anything. /tmp must be available to the process */ int demonize() { int pid = fork(); switch ( pid ) { case -1: return (-1); case 0: break; default: return pid; } return 0; } JNIEXPORT void JNICALL Java_recipeNo022_Daemon_demonize (JNIEnv *env, jclass obj) { /* JNI call will demonize the code and get back to Java */ int pid = demonize(); /* We want to make this long lasting loop inside daemon. That's why we check whether we are child or parent */ if( pid == 0 ) { /* Change the file mode mask */ umask(0); /* As we want to "see" the execution, there is a log file inside /tmp/daemon. Each second, word "daemon" will be appended to that file. */ FILE *fid = fopen( "/tmp/daemon", "w" ); /* Create a new SID for the child process */ int sid = setsid(); if (sid < 0) { /* Log the failure */ exit(EXIT_FAILURE); } /* Change the current working directory */ if ((chdir("/")) < 0) { /* Log the failure */ exit(EXIT_FAILURE); } /* Close out the standard file descriptors */ close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); /* Assign all files to /dev/null */ open ("/dev/null", O_RDWR); dup (0); dup (0); /* Daemon loop */ while(1) { sleep(1); fprintf(fid, "I am daemon ;)\n"); fflush( fid ); } } } |
Thanks to running code via JNI we can perform all daemon based setup:
- – setting custom SID for process,
- – changing dir to “/”,
- – closing standard streams: input, output, error – and attaching them to /dev/null,
- – executing endless loop.
Note that we will never get back to Java here. You can find another sample, where service part of daemon is executed in Java, here: recipe № 029. Full sample code for recipe recipe № 022 can be found at following location: recipe № 022 – sample code.
References:
– Robert Love, Linux System Programming – Daemons
– Devin Watson, Linux Daemon Writing HOWTO