status.c (2130B) download
1#include "service.h"
2#include "util.h"
3
4#include <errno.h>
5#include <fcntl.h>
6#include <signal.h>
7#include <stdio.h>
8#include <string.h>
9#include <sys/file.h>
10#include <sys/stat.h>
11#include <unistd.h>
12
13
14void service_update_state(struct service* s, int state) {
15 if (state != -1)
16 s->state = state;
17
18 s->state_change = time(NULL);
19
20 service_write(s);
21}
22
23void service_write(struct service* s) {
24 int fd;
25 const char* stat_human;
26 struct service_serial stat_runit;
27
28 if ((fd = openat(s->dir, "supervise/status.new", O_CREAT | O_WRONLY | O_TRUNC, 0644)) == -1) {
29 fprint(1, "cannot open supervise/status: %r\n");
30 return;
31 }
32
33 service_encode(s, &stat_runit);
34
35 if (write(fd, &stat_runit, sizeof(stat_runit)) == -1) {
36 fprint(1, "cannot write to supervise/status: %r\n");
37 return;
38 }
39
40 close(fd);
41
42 if ((fd = openat(s->dir, "supervise/stat.new", O_CREAT | O_WRONLY | O_TRUNC, 0644)) == -1) {
43 fprint(1, "cannot create supervise/stat: %r\n");
44 return;
45 }
46
47 stat_human = service_status_name(s);
48 if (write(fd, stat_human, strlen(stat_human)) == -1) {
49 fprint(1, "cannot write to supervise/stat: %r\n");
50 return;
51 }
52
53 close(fd);
54
55 if ((fd = openat(s->dir, "supervise/pid.new", O_CREAT | O_WRONLY | O_TRUNC, 0644)) == -1) {
56 fprint(1, "cannot create supervise/stat: %r\n");
57 return;
58 }
59
60 dprintf(fd, "%d", s->pid);
61
62 close(fd);
63
64 renameat(s->dir, "supervise/status.new", s->dir, "supervise/status");
65 renameat(s->dir, "supervise/stat.new", s->dir, "supervise/stat");
66 renameat(s->dir, "supervise/pid.new", s->dir, "supervise/pid");
67}
68
69const char* service_status_name(struct service* s) {
70 switch (s->state) {
71 case STATE_SETUP:
72 return "setup";
73 case STATE_STARTING:
74 return "starting";
75 case STATE_ACTIVE_FOREGROUND:
76 return "run";
77 case STATE_ACTIVE_BACKGROUND:
78 return "run-background";
79 case STATE_ACTIVE_DUMMY:
80 return "run-dummy";
81 case STATE_FINISHING:
82 return "finishing";
83 case STATE_STOPPING:
84 return "stopping";
85 case STATE_INACTIVE:
86 return "down";
87 case STATE_DONE:
88 return "done";
89 case STATE_ERROR:
90 return "dead (error)";
91 default:
92 return NULL;
93 }
94}