浏览代码

Let the initial process linger until the daemon is initialized.

This enables us to report errors in the btpd init sequence to the
shell by non zero exit code.
Changed from flock to lockf because of solaris troubles. I may
be confused though.
master
Richard Nyberg 16 年前
父节点
当前提交
5a6ac5189f
共有 2 个文件被更改,包括 81 次插入38 次删除
  1. +69
    -35
      btpd/main.c
  2. +12
    -3
      btpd/util.c

+ 69
- 35
btpd/main.c 查看文件

@@ -1,73 +1,93 @@
#include "btpd.h"

#include <sys/file.h>
#include <err.h>
#include <getopt.h>
#include <time.h>

int btpd_daemon_phase = 2;
int first_btpd_comm[2];

void
first_btpd_exit(char code)
{
write(first_btpd_comm[1], &code, 1);
close(first_btpd_comm[0]);
close(first_btpd_comm[1]);
}

static void
writepid(int pidfd)
{
FILE *fp = fdopen(dup(pidfd), "w");
fprintf(fp, "%ld", (long)getpid());
fclose(fp);
int nw;
char pidtxt[100];
nw = snprintf(pidtxt, sizeof(pidtxt), "%ld", (long)getpid);
ftruncate(pidfd, 0);
write(pidfd, pidtxt, nw);
}

static void
setup_daemon(int daemonize, const char *dir, const char *log)
setup_daemon(int daemonize, const char *dir)
{
char c;
int pidfd;
pid_t pid;
struct timespec ts;

if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
errx(1, "clock_gettime(CLOCK_MONOTONIC, ...) error (%s).",
btpd_err("clock_gettime(CLOCK_MONOTONIC, ...) failed (%s).\n",
strerror(errno));

if (log == NULL)
log = "log";

if (dir == NULL) {
if ((dir = find_btpd_dir()) == NULL)
errx(1, "Cannot find the btpd directory");
else if (dir[0] != '/')
errx(1, "got non absolute path '%s' from system environment.",
btpd_err("Cannot find the btpd directory.\n");
if (dir[0] != '/')
btpd_err("Got non absolute path '%s' from system environment.\n",
dir);
btpd_dir = dir;
}

if (mkdir(dir, 0777) == -1 && errno != EEXIST)
err(1, "Couldn't create home '%s'", dir);
btpd_err("Couldn't create home '%s' (%s).\n", dir, strerror(errno));

if (chdir(dir) != 0)
err(1, "Couldn't change working directory to '%s'", dir);
btpd_err("Couldn't change working directory to '%s' (%s).\n", dir,
strerror(errno));

if (mkdir("torrents", 0777) == -1 && errno != EEXIST)
err(1, "Couldn't create torrents subdir");

if ((pidfd = open("pid", O_CREAT|O_TRUNC|O_WRONLY, 0666)) == -1)
err(1, "Couldn't open 'pid'");

if (flock(pidfd, LOCK_NB|LOCK_EX) == -1)
errx(1, "Another instance of btpd is probably running in %s.", dir);
btpd_err("Couldn't create torrents subdir (%s).\n", strerror(errno));

if (btpd_dir == NULL) {
char wd[PATH_MAX];
if (getcwd(wd, PATH_MAX) == NULL)
err(1, "couldn't get working directory");
btpd_dir = strdup(wd);
btpd_err("Couldn't get working directory (%s).\n",
strerror(errno));
if ((btpd_dir = strdup(wd)) == NULL)
btpd_err("Out of memory.\n");
}

if (daemonize) {
if (daemon(1, 1) != 0)
err(1, "Failed to daemonize");
freopen("/dev/null", "r", stdin);
if (freopen(log, "a", stdout) == NULL)
err(1, "Couldn't open '%s'", log);
dup2(fileno(stdout), fileno(stderr));
setlinebuf(stdout);
setlinebuf(stderr);
if (pipe(first_btpd_comm) < 0)
btpd_err("Failed to create pipe (%s).\n", strerror(errno));
if ((pid = fork()) < 0)
btpd_err("fork() failed (%s).\n", strerror(errno));
if (pid != 0) {
read(first_btpd_comm[0], &c, 1);
exit(c);
}
btpd_daemon_phase--;
if (setsid() < 0)
btpd_err("setsid() failed (%s).\n", strerror(errno));
if ((pid = fork()) < 0)
btpd_err("fork() failed (%s).\n", strerror(errno));
if (pid != 0)
exit(0);
}

if ((pidfd = open("pid", O_CREAT|O_WRONLY, 0666)) == -1)
btpd_err("Couldn't open 'pid' (%s).\n", strerror(errno));

if (lockf(pidfd, F_TLOCK, 0) == -1)
btpd_err("Another instance of btpd is probably running in %s.\n", dir);

writepid(pidfd);
}

@@ -203,10 +223,11 @@ main(int argc, char **argv)
case 1:
break;
case 0:
errx(1, "You must specify a dotted IPv4 address.\n");
btpd_err("You must specify a dotted IPv4 address.\n");
break;
default:
err(1, "inet_ntop %s", optarg);
btpd_err("inet_ntop for '%s' failed (%s).\n", optarg,
strerror(errno));
}
break;
default:
@@ -225,13 +246,26 @@ args_done:
if (argc > 0)
usage();

setup_daemon(daemonize, dir, log);
setup_daemon(daemonize, dir);

if (evloop_init() != 0)
btpd_err("Failed to initialize evloop (%s).\n", strerror(errno));

btpd_init();

if (daemonize) {
if (freopen("/dev/null", "r", stdin) == NULL)
btpd_err("freopen of stdin failed (%s).\n", strerror(errno));
if (freopen(log == NULL ? "log" : log, "a", stderr) == NULL)
btpd_err("Couldn't open '%s' (%s).\n", log, strerror(errno));
if (dup2(fileno(stderr), fileno(stdout)) < 0)
btpd_err("dup2 failed (%s).\n", strerror(errno));
first_btpd_exit(0);
}
setlinebuf(stdout);
setlinebuf(stderr);

btpd_daemon_phase = 0;
evloop();

btpd_err("Exit from evloop with error (%s).\n", strerror(errno));


+ 12
- 3
btpd/util.c 查看文件

@@ -91,14 +91,23 @@ log_common(uint32_t type, const char *fmt, va_list ap)
}
}

extern int btpd_daemon_phase;
extern void first_btpd_exit(char);

void
btpd_err(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
log_common(BTPD_L_ERROR, fmt, ap);
va_end(ap);
exit(1);
if (btpd_daemon_phase > 0) {
vprintf(fmt, ap);
if (btpd_daemon_phase == 1)
first_btpd_exit(1);
exit(1);
} else {
log_common(BTPD_L_ERROR, fmt, ap);
abort();
}
}

void


正在加载...
取消
保存