Skip to content

Instantly share code, notes, and snippets.

@WangYihang
Created November 11, 2021 07:24
Show Gist options
  • Save WangYihang/271817cda05e961e5d24d33ec25b1245 to your computer and use it in GitHub Desktop.
Save WangYihang/271817cda05e961e5d24d33ec25b1245 to your computer and use it in GitHub Desktop.
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>
// from: https://stackoverflow.com/a/21419213/7368776
// compile: gcc -o daemonize daemonize.c
extern char *__progname;
int daemonize(char* cwd, char* stdin_path, char* stdout_path, char* stderr_path) {
// Step 0: set default value
if(!cwd) { cwd = "/"; }
if(!stdin_path) { stdin_path = "/dev/null"; }
if(!stdout_path) { stdout_path = "/dev/null"; }
if(!stderr_path) { stderr_path = "/dev/null"; }
pid_t child;
// Step 1: fork, then detach from process group leader
if ((child=fork()) < 0) {
fprintf(stderr, "error: failed fork\n");
exit(EXIT_FAILURE);
}
if (child > 0) {
exit(EXIT_SUCCESS);
}
if (setsid() < 0) {
fprintf(stderr, "error: failed setsid\n");
exit(EXIT_FAILURE);
}
// Step 2: catch / ignore signals
signal(SIGCHLD,SIG_IGN);
signal(SIGHUP,SIG_IGN);
// Step 3: fork second time
if ((child=fork()) < 0) {
fprintf(stderr,"error: failed fork\n");
exit(EXIT_FAILURE);
}
if (child > 0) { //parent
exit(EXIT_SUCCESS);
}
// Step 4: new file permissions, change the current working directory
umask(0);
chdir(cwd);
// Step 5: Close all open file descriptors
for(int fd = 0; fd > sysconf(_SC_OPEN_MAX) ; fd++ ) {
close(fd);
}
// Step 6: reopen stdin, stdout, stderr
stdin = fopen(stdin_path, "r");
stdout = fopen(stdout_path, "w+");
stderr = fopen(stderr_path, "w+");
// Step 7: open syslog
openlog(__progname, LOG_CONS | LOG_PID, LOG_DAEMON);
return(0);
}
int main(int argc, char *argv[], char* envp[]) {
int ttl = 0x80;
int delay = 0x02;
// Step 1: daemonize
if (daemonize("/", NULL, NULL, NULL) != 0 ) {
fprintf(stderr, "error: daemonize failed\n");
exit(EXIT_FAILURE);
}
// Step 2: do something
while (ttl > 0) {
// put your code here
// ...
syslog(LOG_NOTICE, "%s will be terminated after %d seconds\n", __progname, ttl);
sleep(delay);
ttl -= delay;
}
syslog(LOG_NOTICE, "%s terminated\n", __progname);
closelog();
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment