static double accept_proportion;
static int nocheck, nocheck_reported, in_child;
-/* for simulation, debugging, etc. */
+/* for logging, simulation, debugging, etc. */
int simulate_flush= -1;
+int logv_use_syslog;
+static char *logv_prefix="";
/*========== logging ==========*/
static void logcore(int sysloglevel, const char *fmt, ...) PRINTF(2,3);
static void logcore(int sysloglevel, const char *fmt, ...) {
VA;
- if (interactive < 2) {
+ if (logv_use_syslog) {
vsyslog(sysloglevel,fmt,al);
} else {
if (self_pid) fprintf(stderr,"[%lu] ",(unsigned long)self_pid);
const char *fmt, va_list al) PRINTF(5,0);
static void logv(int sysloglevel, const char *pfx, int errnoval,
const char *fmt, va_list al) {
- char msgbuf[1024]; /* NB do not call mvasprintf here or you'll recurse */
+ char msgbuf[1024]; /* NB do not call xvasprintf here or you'll recurse */
vsnprintf(msgbuf,sizeof(msgbuf), fmt,al);
msgbuf[sizeof(msgbuf)-1]= 0;
if (sysloglevel >= LOG_ERR && (errnoval==EACCES || errnoval==EPERM))
sysloglevel= LOG_ERR; /* run by wrong user, probably */
- logcore(sysloglevel, "<%s>%s: %s%s%s",
- sitename, pfx, msgbuf,
- errnoval>=0 ? ": " : "",
- errnoval>=0 ? strerror(errnoval) : "");
+ logcore(sysloglevel, "%s%s: %s%s%s",
+ logv_prefix, pfx, msgbuf,
+ errnoval>=0 ? ": " : "",
+ errnoval>=0 ? strerror(errnoval) : "");
}
-#define DIEWRAP(fn, pfx, sysloglevel, err, estatus) \
+#define DEFFATAL(fn, pfx, sysloglevel, err, estatus) \
static void fn(const char *fmt, ...) NORET_PRINTF(1,2); \
static void fn(const char *fmt, ...) { \
preterminate(); \
exit(estatus); \
}
-#define LOGWRAP(fn, pfx, sysloglevel, err) \
+#define DEFLOG(fn, pfx, sysloglevel, err) \
static void fn(const char *fmt, ...) PRINTF(1,2); \
static void fn(const char *fmt, ...) { \
VA; \
va_end(al); \
}
-#define INNLOGWRAP_DECLARE(fn, pfx, sysloglevel) \
- static void duct_log_##fn(int errval, const char *fmt, va_list al, int l) { \
+#define INNLOGSET_DECLARE(fn, pfx, sysloglevel) \
+ static void duct_log_##fn(int l, const char *fmt, va_list al, int errval) { \
logv(sysloglevel, pfx, errval ? errval : -1, fmt, al); \
}
-#define INNLOGWRAP_CALL(fn, pfx, sysloglevel) \
+#define INNLOGSET_CALL(fn, pfx, sysloglevel) \
message_handlers_##fn(1, duct_log_##fn);
/* We want to extend the set of logging functions from inn, and we
* want to prepend the site name to all our messages. */
-DIEWRAP(syscrash, " critical", LOG_CRIT, errno, 16);
-DIEWRAP(crash, " critical", LOG_CRIT, -1, 16);
+DEFFATAL(syscrash, "critical", LOG_CRIT, errno, 16);
+DEFFATAL(crash, "critical", LOG_CRIT, -1, 16);
-#define INNLOGWRAPS(INNLOGWRAP) \
- INNLOGWRAP(die, " fatal", LOG_ERR) \
- INNLOGWRAP(warn, " warning", LOG_WARNING) \
- INNLOGWRAP(notice, " notice", LOG_NOTICE)
-INNLOGWRAPS(INNLOGWRAP_DECLARE)
+#define INNLOGSETS(INNLOGSET) \
+ INNLOGSET(die, "fatal", LOG_ERR) \
+ INNLOGSET(warn, "warning", LOG_WARNING) \
+ INNLOGSET(notice, "notice", LOG_NOTICE) \
+ INNLOGSET(trace, "trace", LOG_NOTICE)
+INNLOGSETS(INNLOGSET_DECLARE)
-LOGWRAP(info, " info", LOG_INFO, -1)
-LOGWRAP(dbg, " debug", LOG_DEBUG, -1)
+DEFLOG(info, "info", LOG_INFO, -1)
+DEFLOG(dbg, "debug", LOG_DEBUG, -1)
/*========== utility functions etc. ==========*/
-/* error trapping wrappers are called mfoo rather than the more
- * conventional xfoo because we don't want to clash with the existing
- * xfoo functions in INN libs which use different error handlers
- */
-
-static char *mvasprintf(const char *fmt, va_list al) PRINTF(1,0);
-static char *mvasprintf(const char *fmt, va_list al) {
+static char *xvasprintf(const char *fmt, va_list al) PRINTF(1,0);
+static char *xvasprintf(const char *fmt, va_list al) {
char *str;
int rc= vasprintf(&str,fmt,al);
if (rc<0) sysdie("vasprintf(\"%s\",...) failed", fmt);
return str;
}
-static char *masprintf(const char *fmt, ...) PRINTF(1,2);
-static char *masprintf(const char *fmt, ...) {
+static char *xasprintf(const char *fmt, ...) PRINTF(1,2);
+static char *xasprintf(const char *fmt, ...) {
VA;
- char *str= mvasprintf(fmt,al);
+ char *str= xvasprintf(fmt,al);
va_end(al);
return str;
}
*fd=0;
return r;
}
-static void mclose(int fd, const char *what, const char *what2) {
+static void xclose(int fd, const char *what, const char *what2) {
int r= close(fd);
if (r) syscrash("close %s%s",what,what2?what2:"");
}
-static void mclose_perhaps(int *fd, const char *what, const char *what2) {
+static void xclose_perhaps(int *fd, const char *what, const char *what2) {
if (*fd <= 0) return;
- mclose(*fd,what,what2);
+ xclose(*fd,what,what2);
*fd=0;
}
-static pid_t mfork(const char *what) {
+static pid_t xfork(const char *what) {
pid_t child;
child= fork();
}
}
-static int mwaitpid(pid_t *pid, const char *what) {
+static int xwaitpid(pid_t *pid, const char *what) {
int status;
int r= kill(*pid, SIGKILL);
return p;
}
-static void munlink(const char *path, const char *what) {
+static void xunlink(const char *path, const char *what) {
int r= unlink(path);
if (r) syscrash("can't unlink %s %s", path, what);
}
-static time_t mtime(void) {
+static time_t xtime(void) {
time_t now= time(0);
if (now==-1) syscrash("time(2) failed");
return now;
}
-static void msigaction(int signo, const struct sigaction *sa) {
+static void xsigaction(int signo, const struct sigaction *sa) {
int r= sigaction(signo,sa,0);
if (r) syscrash("sigaction failed for \"%s\"", strsignal(signo));
}
-static void msigsetdefault(int signo) {
+static void xsigsetdefault(int signo) {
struct sigaction sa;
memset(&sa,0,sizeof(sa));
sa.sa_handler= SIG_DFL;
- msigaction(signo,&sa);
+ xsigaction(signo,&sa);
}
-static void mgettimeofday(struct timeval *tv_r) {
+static void xgettimeofday(struct timeval *tv_r) {
int r= gettimeofday(tv_r,0);
if (r) syscrash("gettimeofday(2) failed");
}
-static void msetnonblock(int fd, int nonblocking) {
+static void xsetnonblock(int fd, int nonblocking) {
int errnoval= oop_fd_nonblock(fd, nonblocking);
if (errnoval) { errno= errnoval; syscrash("setnonblocking"); }
}
what, path, (unsigned long)stab->st_mode);
}
-static void mfstat(int fd, struct stat *stab_r, const char *what) {
+static void xfstat(int fd, struct stat *stab_r, const char *what) {
int r= fstat(fd, stab_r);
if (r) syscrash("could not fstat %s", what);
}
-static void mfstat_isreg(int fd, struct stat *stab_r,
+static void xfstat_isreg(int fd, struct stat *stab_r,
const char *path, const char *what) {
- mfstat(fd, stab_r, what);
+ xfstat(fd, stab_r, what);
check_isreg(stab_r, path, what);
}
-static void mlstat_isreg(const char *path, struct stat *stab,
+static void xlstat_isreg(const char *path, struct stat *stab,
int *enoent_r /* 0 means ENOENT is fatal */,
const char *what) {
int r= lstat(path, stab);
r= listen(cli_master, 5);
if (r) NOCLI("listen to cli master socket");
- msetnonblock(cli_master, 1);
+ xsetnonblock(cli_master, 1);
loop->on_fd(loop, cli_master, OOP_READ, cli_master_readable, 0);
info("cli ready, listening on %s", path_cli);
return;
nocli:
- mclose_perhaps(&cli_master, "cli master",0);
+ xclose_perhaps(&cli_master, "cli master",0);
return;
}
LIST_REMOVE(conns,conn);
- char *m= mvasprintf(fmt,al);
+ char *m= xvasprintf(fmt,al);
warn("C%d (now %d) connection failed requeueing " RCI_TRIPLE_FMT_BASE ": %s",
conn->fd, conns.count, RCI_TRIPLE_VALS_BASE(requeue, /*nothing*/), m);
free(m);
static void connect_attempt_discard(void) {
if (connecting_child) {
- int status= mwaitpid(&connecting_child, "connect");
+ int status= xwaitpid(&connecting_child, "connect");
if (!(WIFEXITED(status) ||
(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)))
report_child_status("connect", status);
}
if (connecting_fdpass_sock) {
cancel_fd_read_except(connecting_fdpass_sock);
- mclose_perhaps(&connecting_fdpass_sock, "connecting fdpass socket",0);
+ xclose_perhaps(&connecting_fdpass_sock, "connecting fdpass socket",0);
}
}
struct cmsghdr *h= 0;
if (rs >= 0) h= CMSG_FIRSTHDR(&msg);
if (!h) {
- int status= mwaitpid(&connecting_child, "connect child (broken)");
+ int status= xwaitpid(&connecting_child, "connect child (broken)");
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != 0 &&
int r= socketpair(AF_UNIX, SOCK_STREAM, 0, socks);
if (r) { syswarn("connect: cannot create socketpair for child"); return; }
- connecting_child= mfork("connection");
+ connecting_child= xfork("connection");
if (!connecting_child) {
FILE *cn_from, *cn_to;
char buf[NNTP_STRLEN+100];
int exitstatus= CONNCHILD_ESTATUS_NOSTREAM;
- mclose(socks[0], "(in child) parent's connection fdpass socket",0);
+ xclose(socks[0], "(in child) parent's connection fdpass socket",0);
alarm(connection_setup_timeout);
if (NNTPconnect((char*)remote_host, port, &cn_from, &cn_to, buf) < 0) {
_exit(exitstatus);
}
- mclose(socks[1], "connecting fdpass child's socket",0);
+ xclose(socks[1], "connecting fdpass child's socket",0);
connecting_fdpass_sock= socks[0];
- msetnonblock(connecting_fdpass_sock, 1);
+ xsetnonblock(connecting_fdpass_sock, 1);
on_fd_read_except(connecting_fdpass_sock, connchild_event);
if (!conns.count)
assert(!ipf->filemon); /* must have had inputfile_reading_stop */
assert(!ipf->rd); /* must have had inputfile_reading_stop */
assert(!ipf->inprogress); /* no dangling pointers pointing here */
- mclose_perhaps(&ipf->fd, "input file ", ipf->path);
+ xclose_perhaps(&ipf->fd, "input file ", ipf->path);
}
syswarn("filemon/inotify: inotify_init failed");
return 0;
}
- msetnonblock(filemon_inotify_fd, 1);
+ xsetnonblock(filemon_inotify_fd, 1);
loop->on_fd(loop, filemon_inotify_fd, OOP_READ, filemon_inotify_readable, 0);
dbg("filemon inotify init filemon_inotify_fd=%d", filemon_inotify_fd);
sysdie("fcntl F_SETLK lockfile %s", path_lock);
}
- mfstat_isreg(lockfd, &stabf, path_lock, "lockfile");
+ xfstat_isreg(lockfd, &stabf, path_lock, "lockfile");
int lock_noent;
- mlstat_isreg(path_lock, &stab, &lock_noent, "lockfile");
+ xlstat_isreg(path_lock, &stab, &lock_noent, "lockfile");
if (!lock_noent && samefile(&stab, &stabf))
break;
- mclose(lockfd, "stale lockfile ", path_lock);
+ xclose(lockfd, "stale lockfile ", path_lock);
}
FILE *lockfile= fdopen(lockfd, "w");
search_backlog_file();
int defer_noent;
- mlstat_isreg(path_defer, &stabdefer, &defer_noent, "defer file");
+ xlstat_isreg(path_defer, &stabdefer, &defer_noent, "defer file");
if (defer_noent) {
dbg("startup: ductdefer ENOENT");
} else {
open_defer(); /* so that we will later close it and rename it */
break;
case 2:
- munlink(path_defer, "stale defer file link"
+ xunlink(path_defer, "stale defer file link"
" (presumably hardlink to backlog file)");
break;
default:
int noent_f;
InputFile *file_d= open_input_file(path_flushing);
- if (file_d) mfstat_isreg(file_d->fd, &stab_d, path_flushing,"flushing file");
+ if (file_d) xfstat_isreg(file_d->fd, &stab_d, path_flushing,"flushing file");
- mlstat_isreg(feedfile, &stab_f, &noent_f, "feedfile");
+ xlstat_isreg(feedfile, &stab_f, &noent_f, "feedfile");
if (!noent_f && file_d && samefile(&stab_f, &stab_d)) {
dbg("startup: F==D => Hardlinked");
- munlink(feedfile, "feed file (during startup)"); /* => Moved */
+ xunlink(feedfile, "feed file (during startup)"); /* => Moved */
noent_f= 1;
}
feedfile, path_flushing);
/* => Hardlinked */
- munlink(feedfile, "old feedfile link");
+ xunlink(feedfile, "old feedfile link");
/* => Moved */
spawn_inndcomm_flush(why); /* => Flushing FLUSHING */
#define CNT(art,rc) (ipf->counts[art_##art][RC_##rc])
char *inprog= completed
- ? masprintf("%s","") /* GCC produces a stupid warning for printf("") ! */
- : masprintf(" inprogress=%ld", ipf->inprogress);
+ ? xasprintf("%s","") /* GCC produces a stupid warning for printf("") ! */
+ : xasprintf(" inprogress=%ld", ipf->inprogress);
char *autodefer= ipf->autodefer >= 0
- ? masprintf(" autodeferred=%ld", ipf->autodefer)
- : masprintf("%s","");
+ ? xasprintf(" autodeferred=%ld", ipf->autodefer)
+ : xasprintf("%s","");
info("%s %s%s read=%d (+bl=%d,+err=%d)%s%s"
" missing=%d offered=%d (ch=%d,nc=%d) accepted=%d (ch=%d,nc=%d)"
close_defer();
- munlink(path_flushing, "old flushing file");
+ xunlink(path_flushing, "old flushing file");
close_input_file(flushing_input_file);
free(flushing_input_file);
static void *statemc_check_input_done(oop_source *lp, struct timeval now,
void *u) {
- assert(!inputfile_is_done(main_input_file));
+ /* main input file may be idle but if so that's because
+ * we haven't got to it yet, but that doesn't mean it's really done */
statemc_check_flushing_done();
statemc_check_backlog_done();
return OOP_CONTINUE;
/* truncate away any half-written records */
- mfstat_isreg(fileno(defer), &stab, path_defer, "newly opened defer file");
+ xfstat_isreg(fileno(defer), &stab, path_defer, "newly opened defer file");
if (stab.st_size > LONG_MAX)
crash("defer file %s size is far too large", path_defer);
return;
struct stat stab;
- mfstat_isreg(fileno(defer), &stab, path_defer, "defer file");
+ xfstat_isreg(fileno(defer), &stab, path_defer, "defer file");
if (fclose(defer)) sysdie("could not close defer file %s", path_defer);
defer= 0;
- time_t now= mtime();
+ time_t now= xtime();
- char *backlog= masprintf("%s_backlog_%lu.%lu", feedfile,
+ char *backlog= xasprintf("%s_backlog_%lu.%lu", feedfile,
(unsigned long)now,
(unsigned long)stab.st_ino);
if (link(path_defer, backlog))
if (r && errno!=ENOENT)
syswarn("failed to unlink cli socket for old feed");
- munlink(path_lock, "lockfile for old feed");
+ xunlink(path_lock, "lockfile for old feed");
exit(4);
}
until_backlog_nextscan= backlog_spontrescan_periods;
goto xfree;
}
- now= mtime();
+ now= xtime();
double age= difftime(now, oldest_mtime);
long age_deficiency= (backlog_retry_minperiods * period_seconds) - age;
static sig_atomic_t terminate_sig_flag;
static void raise_default(int signo) {
- msigsetdefault(signo);
+ xsigsetdefault(signo);
raise(signo);
abort();
}
if (pipe(signal_self_pipe)) sysdie("create self-pipe for signals");
- msetnonblock(signal_self_pipe[0],1);
- msetnonblock(signal_self_pipe[1],1);
+ xsetnonblock(signal_self_pipe[0],1);
+ xsetnonblock(signal_self_pipe[1],1);
struct sigaction sa;
memset(&sa,0,sizeof(sa));
sa.sa_handler= sigarrived_handler;
sa.sa_flags= SA_RESTART;
- msigaction(SIGTERM,&sa);
- msigaction(SIGINT,&sa);
+ xsigaction(SIGTERM,&sa);
+ xsigaction(SIGINT,&sa);
on_fd_read_except(signal_self_pipe[0], sigarrived_event);
}
static void *inndcomm_event(oop_source *lp, int fd, oop_event e, void *u) {
assert(inndcomm_child);
assert(fd == inndcomm_sentinel_fd);
- int status= mwaitpid(&inndcomm_child, "inndcomm");
+ int status= xwaitpid(&inndcomm_child, "inndcomm");
inndcomm_child= 0;
cancel_fd_read_except(fd);
- mclose_perhaps(&fd, "inndcomm sentinel pipe",0);
+ xclose_perhaps(&fd, "inndcomm sentinel pipe",0);
inndcomm_sentinel_fd= 0;
assert(!flushing_input_file);
if (pipe(pipefds)) sysdie("create pipe for inndcomm child sentinel");
- inndcomm_child= mfork("inndcomm child");
+ inndcomm_child= xfork("inndcomm child");
if (!inndcomm_child) {
const char *flushargv[2]= { sitename, 0 };
char *reply;
int r;
- mclose(pipefds[0], "(in child) inndcomm sentinel parent's end",0);
+ xclose(pipefds[0], "(in child) inndcomm sentinel parent's end",0);
/* parent spots the autoclose of pipefds[1] when we die or exit */
if (simulate_flush>=0) {
simulate_flush= -1;
- mclose(pipefds[1], "inndcomm sentinel child's end",0);
+ xclose(pipefds[1], "inndcomm sentinel child's end",0);
inndcomm_sentinel_fd= pipefds[0];
assert(inndcomm_sentinel_fd);
on_fd_read_except(inndcomm_sentinel_fd, inndcomm_event);
static void postfork_inputfile(InputFile *ipf) {
if (!ipf) return;
- mclose(ipf->fd, "(in child) input file ", ipf->path);
+ xclose(ipf->fd, "(in child) input file ", ipf->path);
}
static void postfork_stdio(FILE *f, const char *what, const char *what2) {
static void postfork(void) {
in_child= 1;
- msigsetdefault(SIGTERM);
- msigsetdefault(SIGINT);
- msigsetdefault(SIGPIPE);
+ xsigsetdefault(SIGTERM);
+ xsigsetdefault(SIGINT);
+ xsigsetdefault(SIGPIPE);
if (terminate_sig_flag) raise(terminate_sig_flag);
postfork_inputfile(main_input_file);
static void *every_happens(oop_source *lp, struct timeval base, void *e_v) {
Every *e= e_v;
e->f();
- if (!e->fixed_rate) mgettimeofday(&base);
+ if (!e->fixed_rate) xgettimeofday(&base);
every_schedule(e, base);
return OOP_CONTINUE;
}
e->fixed_rate= fixed_rate;
e->f= f;
struct timeval now;
- mgettimeofday(&now);
+ xgettimeofday(&now);
every_schedule(e, now);
}
}
static char *dbg_report_ipf(InputFile *ipf) {
- if (!ipf) return masprintf("none");
+ if (!ipf) return xasprintf("none");
const char *slash= strrchr(ipf->path,'/');
const char *path= slash ? slash+1 : ipf->path;
- return masprintf("%p/%s:queue=%d,ip=%ld,autodef=%ld,off=%ld,fd=%d%s%s%s",
+ return xasprintf("%p/%s:queue=%d,ip=%ld,autodef=%ld,off=%ld,fd=%d%s%s%s",
ipf, path,
ipf->queue.count, ipf->inprogress, ipf->autodefer,
(long)ipf->offset, ipf->fd,
const XmitDetails *xd= &conn->xmitd[i];
char *dinfo;
switch (xd->kind) {
- case xk_Const: dinfo= masprintf("Const"); break;
- case xk_Artdata: dinfo= masprintf("A%p", xd->info.sm_art); break;
+ case xk_Const: dinfo= xasprintf("Const"); break;
+ case xk_Artdata: dinfo= xasprintf("A%p", xd->info.sm_art); break;
default:
abort();
}
static void vbadusage(const char *fmt, va_list al) NORET_PRINTF(1,0);
static void vbadusage(const char *fmt, va_list al) {
- char *m= mvasprintf(fmt,al);
+ char *m= xvasprintf(fmt,al);
fprintf(stderr, "bad usage: %s\n"
"say --help for help, or read the manpage\n",
m);
const Option *o;
for (o=options; o->shrt || o->lng; o++) {
char shrt[2] = { o->shrt, 0 };
- char *optspec= masprintf("%s%s%s%s%s",
+ char *optspec= xasprintf("%s%s%s%s%s",
o->shrt ? "-" : "", shrt,
o->shrt && o->lng ? "|" : "",
DELIMPERHAPS("--", o->lng));
/* set up libinn logging */
message_program_name= "innduct";
message_fatal_cleanup= innduct_fatal_cleanup;
- INNLOGWRAPS(INNLOGWRAP_CALL)
+ INNLOGSETS(INNLOGSET_CALL)
if (!argv[1]) {
printusage(stderr);
if (!feedfile) feedfile= sitename;
if (!feedfile[0]) badusage("feed filename, if specified, must be nonempty");
if (path_ends_slash(feedfile))
- feedfile= masprintf("%s%s", feedfile, sitename);
+ feedfile= xasprintf("%s%s", feedfile, sitename);
if (feedfile[0] != '/')
- feedfile= masprintf("%s/%s", innconf->pathoutgoing, feedfile);
+ feedfile= xasprintf("%s/%s", innconf->pathoutgoing, feedfile);
if (!path_cli) {
path_cli_dir= "innduct";
} else if (!path_cli[0] || !strcmp(path_cli,"none")) {
path_cli= 0; /* ok, don't then */
} else if (path_ends_slash(path_cli)) {
- path_cli_dir= masprintf("%.*s", strlen(path_cli)-1, path_cli);
+ path_cli_dir= xasprintf("%.*s", strlen(path_cli)-1, path_cli);
}
if (path_cli_dir)
- path_cli= masprintf("%s/%s", path_cli_dir, sitename);
+ path_cli= xasprintf("%s/%s", path_cli_dir, sitename);
if (max_queue_per_ipf<0)
max_queue_per_ipf= max_queue_per_conn * 2;
/* set things up */
- path_lock= masprintf("%s_lock", feedfile);
- path_flushing= masprintf("%s_flushing", feedfile);
- path_defer= masprintf("%s_defer", feedfile);
- path_dump= masprintf("%s_dump", feedfile);
- globpat_backlog= masprintf("%s_backlog*", feedfile);
+ path_lock= xasprintf("%s_lock", feedfile);
+ path_flushing= xasprintf("%s_flushing", feedfile);
+ path_defer= xasprintf("%s_defer", feedfile);
+ path_dump= xasprintf("%s_dump", feedfile);
+ globpat_backlog= xasprintf("%s_backlog*", feedfile);
oop_source_sys *sysloop= oop_sys_new();
if (!sysloop) syscrash("could not create liboop event loop");
close(i);
}
- if (interactive < 2)
+ logv_prefix= xasprintf("<%s> ", sitename);
+ if (interactive < 2) {
openlog("innduct",LOG_NDELAY|LOG_PID,LOG_NEWS);
+ logv_use_syslog= 1;
+ }
if (interactive < 1) {
int null= open("/dev/null",O_RDWR);
dup2(null,0);
dup2(null,1);
dup2(null,2);
- mclose(null, "/dev/null original fd",0);
+ xclose(null, "/dev/null original fd",0);
- pid_t child1= mfork("daemonise first fork");
+ pid_t child1= xfork("daemonise first fork");
if (child1) _exit(0);
pid_t sid= setsid();
if (sid == -1) sysdie("setsid failed");
- pid_t child2= mfork("daemonise second fork");
+ pid_t child2= xfork("daemonise second fork");
if (child2) _exit(0);
}