C/Daemonize

From Attie's Wiki
(Difference between revisions)
Jump to: navigation, search
m
m (Attie moved page Daemonize to C/Daemonize)
 
(4 intermediate revisions by one user not shown)
Line 1: Line 1:
 
<source lang="c">
 
<source lang="c">
int pipefd[2];
+
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <sys/types.h>
 +
#include <sys/stat.h>
 +
#include <fcntl.h>
  
 +
int pipefd;
 +
 +
/* call this function to deamonize */
 
int daemonize(void) {
 
int daemonize(void) {
 +
  int pipefds[2];
 
   int i;
 
   int i;
 +
  unsigned char c;
  
   if (pipe(pipefd) == -1) {
+
   if (pipe(pipefds) == -1) {
 
     perror("pipe()");
 
     perror("pipe()");
 
     return 1;
 
     return 1;
Line 16: Line 25:
 
   }
 
   }
 
   if (i > 0) {
 
   if (i > 0) {
    char c;
+
     close(pipefds[1]);
     close(pipefd[1]);
+
     if (read(pipefds[0],&c,1) <= 0) {
    close(fileno(stdin)); /* prevent the parent from stealing the input */
+
     if (read(pipefd[0],&c,1) <= 0) {
+
 
       printf("An error occured, unable to determine if started successfully...\n");
 
       printf("An error occured, unable to determine if started successfully...\n");
 
       exit(1);
 
       exit(1);
 
     }
 
     }
     if (c) {
+
     if (c == 1) {
 
       printf("An error occured while starting...\n");
 
       printf("An error occured while starting...\n");
 +
      exit(1);
 +
    } else if (c == 2) {
 +
      printf("An error occured while deamonizing...\n");
 +
      return 2;
 +
    } else if (c != 0) {
 +
      printf("An unknown return status was given (%d)...\n", c);
 
       exit(1);
 
       exit(1);
 
     }
 
     }
Line 31: Line 44:
 
   }
 
   }
  
   close(pipefd[0]);
+
   close(pipefds[0]);
 +
  pipefd = pipefds[1];
 
    
 
    
 
   if (setsid() < 0) {
 
   if (setsid() < 0) {
 
     perror("setsid()");
 
     perror("setsid()");
     return 1;
+
     goto killChild;
 
   }
 
   }
 
    
 
    
Line 42: Line 56:
 
   if ((chdir("/")) < 0) {
 
   if ((chdir("/")) < 0) {
 
     perror("chdir()");
 
     perror("chdir()");
     return 1;
+
     goto killChild;
 
   }
 
   }
 
    
 
    
 
   return 0;
 
   return 0;
 +
 +
killChild:
 +
  c = 2;
 +
  write(pipefds[1],&c,2);
 +
  close(pipefds[1]);
 +
  exit(1);
 
}
 
}
  
 +
/* call this to indicate success, and detach from the terminal */
 
void daemonize_success(void) {
 
void daemonize_success(void) {
 
   int i;
 
   int i;
 +
  unsigned char c;
  
 
   i = open("/dev/null",O_RDWR);
 
   i = open("/dev/null",O_RDWR);
Line 63: Line 85:
 
   }
 
   }
  
   i = 0;
+
   c = 0;
   write(pipefd[1],&i,1);
+
   write(pipefd,&c,1);
   close(pipefd[1]);
+
   close(pipefd);
 
}
 
}
  
 +
/* call this to indicate failure in the parent... you must still kill yourself - try exit(1) */
 
void daemonize_failure(void) {
 
void daemonize_failure(void) {
   int i;
+
   unsigned char c;
   i = 1;
+
   c = 1;
   write(pipefd[1],&i,1);
+
   write(pipefd,&c,1);
   close(pipefd[1]);
+
   close(pipefd);
 
}
 
}
 
</source>
 
</source>

Latest revision as of 17:07, 14 February 2013

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
 
int pipefd;
 
/* call this function to deamonize */
int daemonize(void) {
  int pipefds[2];
  int i;
  unsigned char c;
 
  if (pipe(pipefds) == -1) {
    perror("pipe()");
    return 1;
  }
 
  i = fork();
  if (i < 0) {
    perror("fork()");
    return 1;
  }
  if (i > 0) {
    close(pipefds[1]);
    if (read(pipefds[0],&c,1) <= 0) {
      printf("An error occured, unable to determine if started successfully...\n");
      exit(1);
    }
    if (c == 1) {
      printf("An error occured while starting...\n");
      exit(1);
    } else if (c == 2) {
      printf("An error occured while deamonizing...\n");
      return 2;
    } else if (c != 0) {
      printf("An unknown return status was given (%d)...\n", c);
      exit(1);
    }
    printf("Started successfully!\n");
    exit(0);
  }
 
  close(pipefds[0]);
  pipefd = pipefds[1];
 
  if (setsid() < 0) {
    perror("setsid()");
    goto killChild;
  }
 
  umask(0);
 
  if ((chdir("/")) < 0) {
    perror("chdir()");
    goto killChild;
  }
 
  return 0;
 
killChild:
  c = 2;
  write(pipefds[1],&c,2);
  close(pipefds[1]);
  exit(1);
}
 
/* call this to indicate success, and detach from the terminal */
void daemonize_success(void) {
  int i;
  unsigned char c;
 
  i = open("/dev/null",O_RDWR);
  if (i < 0) {
    close(fileno(stderr));
    close(fileno(stdout));
    close(fileno(stdin));
  } else {
    dup2(i,fileno(stderr)); /* 2 = stderr */
    dup2(i,fileno(stdout)); /* 1 = stdout */
    dup2(i,fileno(stdin));  /* 0 = stdin */
    close(i);
  }
 
  c = 0;
  write(pipefd,&c,1);
  close(pipefd);
}
 
/* call this to indicate failure in the parent... you must still kill yourself - try exit(1) */
void daemonize_failure(void) {
  unsigned char c;
  c = 1;
  write(pipefd,&c,1);
  close(pipefd);
}
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox