update ct
[beanstalkd.git] / main.c
blob63c8d747f4b6f18a633d109f2d0fa3da3bb5c2a4
1 #include <stdint.h>
2 #include <signal.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #include <sys/stat.h>
7 #include <unistd.h>
8 #include <pwd.h>
9 #include <fcntl.h>
10 #include "dat.h"
12 static void
13 su(const char *user) {
14 int r;
15 struct passwd *pwent;
17 errno = 0;
18 pwent = getpwnam(user);
19 if (errno) twarn("getpwnam(\"%s\")", user), exit(32);
20 if (!pwent) twarnx("getpwnam(\"%s\"): no such user", user), exit(33);
22 r = setgid(pwent->pw_gid);
23 if (r == -1) twarn("setgid(%d \"%s\")", pwent->pw_gid, user), exit(34);
25 r = setuid(pwent->pw_uid);
26 if (r == -1) twarn("setuid(%d \"%s\")", pwent->pw_uid, user), exit(34);
30 static void
31 set_sig_handlers()
33 int r;
34 struct sigaction sa;
36 sa.sa_handler = SIG_IGN;
37 sa.sa_flags = 0;
38 r = sigemptyset(&sa.sa_mask);
39 if (r == -1) twarn("sigemptyset()"), exit(111);
41 r = sigaction(SIGPIPE, &sa, 0);
42 if (r == -1) twarn("sigaction(SIGPIPE)"), exit(111);
44 sa.sa_handler = enter_drain_mode;
45 r = sigaction(SIGUSR1, &sa, 0);
46 if (r == -1) twarn("sigaction(SIGUSR1)"), exit(111);
49 int
50 main(int argc, char **argv)
52 int r;
53 struct job list = {};
55 progname = argv[0];
56 setlinebuf(stdout);
57 optparse(&srv, argv+1);
59 if (verbose) {
60 printf("pid %d\n", getpid());
63 r = make_server_socket(srv.addr, srv.port);
64 if (r == -1) twarnx("make_server_socket()"), exit(111);
65 srv.sock.fd = r;
67 prot_init();
69 if (srv.user) su(srv.user);
70 set_sig_handlers();
72 if (srv.wal.use) {
73 // We want to make sure that only one beanstalkd tries
74 // to use the wal directory at a time. So acquire a lock
75 // now and never release it.
76 if (!waldirlock(&srv.wal)) {
77 twarnx("failed to lock wal dir %s", srv.wal.dir);
78 exit(10);
81 list.prev = list.next = &list;
82 walinit(&srv.wal, &list);
83 r = prot_replay(&srv, &list);
84 if (!r) {
85 twarnx("failed to replay log");
86 return 1;
90 srvserve(&srv);
91 return 0;