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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
#include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <signal.h> #include <errno.h> #include <string.h> #include <stdio.h> #include <sys/stat.h> #include <limits.h> #include <sys/resource.h> #include <syslog.h>
volatile int init = 0;
void restart(int sig) { if(init) { closelog(); printf("restart\n"); } openlog("meow", LOG_CONS|LOG_NDELAY|LOG_PID, LOG_USER); init = 1; }
#define min(x, y) ((x) < (y) ? (x) : (y))
#define CHECK_WITH_RET(x, ret, format, ...) \ do { \ if(!(x)) { \ fprintf(stderr, format, __VA_ARGS__); \ ret \ } \ } while(0)
#define CHECK(x) CHECK_WITH_RET(x, return -1;, "%s:%d\nerror: %s\nunmet condition:\"%s\"\n", __FILE__, __LINE__,strerror(errno), #x) #define CONDITION(x) CHECK_WITH_RET(x, exit(2);, "%s:%d\nunmet condition:\"%s\"\n", __FILE__, __LINE__, #x) #define CHECKMAIN(x) CHECK_WITH_RET(x, exit(1);, "%s:%d\nerror: %s\nunmet condition:\"%s\"\n", __FILE__, __LINE__,strerror(errno), #x)
int makeDaemon() { pid_t pid; switch ((pid = fork())) { case -1: CHECK(0); case 0: break; default: printf("pid:%ld\n", (long)pid); _exit(0); } CHECK(setsid() != -1); CHECK(umask(0) != -1); CHECK(chroot("/") != -1); int nullfd = open("/dev/null", O_RDWR); CHECK(nullfd != -1); CHECK(dup2(nullfd, STDIN_FILENO) != -1); CHECK(dup2(nullfd, STDOUT_FILENO) != -1); CHECK(dup2(nullfd, STDERR_FILENO) != -1); CHECK(close(nullfd) != -1); long fdmax = sysconf(_SC_OPEN_MAX); struct rlimit rlimit; CHECK(getrlimit(RLIMIT_NOFILE, &rlimit) != -1); for(int fdi = 0; fdi < min(fdmax, rlimit.rlim_cur); fdi++) { close(fdi); } CHECK(signal(SIGHUP, restart) != SIG_ERR); return 0; }
struct logmesg { int level; char *str; };
int main(int argc, char **argv) { printf("pid:%ld\n", (long)getpid()); CHECKMAIN(makeDaemon() != -1); printf("pid:%ld\n", (long)getpid()); restart(SIGHUP); CHECKMAIN(signal(SIGHUP, restart) != SIG_ERR); CONDITION(argc >= 3); struct logmesg *data = malloc(sizeof(struct logmesg)); data->level = atoi(argv[1]); CONDITION(data->level >= 0 && data->level <= 7); int strlen = 0; for(char **argvi = &argv[2]; *argvi; argvi++) { strlen += snprintf(NULL, 0, "%s %s", (char *)NULL, *argvi); } char *str = malloc(strlen + 1);
for(char **argvi = &argv[2]; *argvi; argvi++) { strlen += sprintf(str, "%s %s",str, *argvi); } data->str = str+1; syslog(data->level, "%s", data->str); printf("syslog: %s\n", data->str); closelog(); }
|