Quellcode durchsuchen

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 vor 16 Jahren
Ursprung
Commit
5a6ac5189f
2 geänderte Dateien mit 81 neuen und 38 gelöschten Zeilen
  1. +69
    -35
      btpd/main.c
  2. +12
    -3
      btpd/util.c

+ 69
- 35
btpd/main.c Datei anzeigen

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


#include <sys/file.h>
#include <err.h>
#include <getopt.h> #include <getopt.h>
#include <time.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 static void
writepid(int pidfd) writepid(int pidfd)
{ {
FILE *fp = fdopen(dup(pidfd), "w"); int nw;
fprintf(fp, "%ld", (long)getpid()); char pidtxt[100];
fclose(fp); nw = snprintf(pidtxt, sizeof(pidtxt), "%ld", (long)getpid);
ftruncate(pidfd, 0);
write(pidfd, pidtxt, nw);
} }


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


if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) 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)); strerror(errno));


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

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


if (mkdir(dir, 0777) == -1 && errno != EEXIST) 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) 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) if (mkdir("torrents", 0777) == -1 && errno != EEXIST)
err(1, "Couldn't create torrents subdir"); btpd_err("Couldn't create torrents subdir (%s).\n", strerror(errno));

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);


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


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


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


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


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


btpd_init(); 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(); evloop();


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


+ 12
- 3
btpd/util.c Datei anzeigen

@@ -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 void
btpd_err(const char *fmt, ...) btpd_err(const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
log_common(BTPD_L_ERROR, fmt, ap); if (btpd_daemon_phase > 0) {
va_end(ap); vprintf(fmt, ap);
exit(1); if (btpd_daemon_phase == 1)
first_btpd_exit(1);
exit(1);
} else {
log_common(BTPD_L_ERROR, fmt, ap);
abort();
}
} }


void void


||||||
x
 
000:0
Laden…
Abbrechen
Speichern