1 diff --git a/start-stop-daemon.8 b/start-stop-daemon.8
2 index 2a083f3..bbeb0f6 100644
3 --- a/start-stop-daemon.8
4 +++ b/start-stop-daemon.8
5 @@ -20,7 +20,7 @@
6 .\" You should have received a copy of the GNU General Public License
7 .\" along with this program. If not, see <https://www.gnu.org/licenses/>.
8 .
9 -.TH start\-stop\-daemon 8 "%RELEASE_DATE%" "%VERSION%" "dpkg suite"
10 +.TH start\-stop\-daemon 8 "2020-08-11" "CRUX 3.6" "dpkg suite"
11 .nh
12 .SH NAME
13 start\-stop\-daemon \- start and stop system daemon programs
14 @@ -269,33 +269,6 @@ reason. This is a last resort, and is only meant for programs that either
15 make no sense forking on their own, or where it's not feasible to add the
16 code for them to do this themselves.
17 .TP
18 -.BR \-\-notify\-await
19 -Wait for the background process to send a readiness notification before
20 -considering the service started (since version 1.19.3).
21 -This implements parts of the systemd readiness procotol, as specified
22 -in the \fBsd_notify\fP(3) man page.
23 -The following variables are supported:
24 -.RS
25 -.TP
26 -.B READY=1
27 -The program is ready to give service, so we can exit safely.
28 -.TP
29 -.BI EXTEND_TIMEOUT_USEC= number
30 -The program requests to extend the timeout by \fInumber\fP microseconds.
31 -This will reset the current timeout to the specified value.
32 -.TP
33 -.BI ERRNO= number
34 -The program is exiting with an error.
35 -Do the same and print the user-friendly string for the \fBerrno\fP value.
36 -.RE
37 -.
38 -.TP
39 -.BI \-\-notify\-timeout timeout
40 -Set a timeout for the \fB\-\-notify\-await\fP option (since version 1.19.3).
41 -When the timeout is reached, \fBstart\-stop\-daemon\fP will exit with an
42 -error code, and no readiness notification will be awaited.
43 -The default is \fB60\fP seconds.
44 -.TP
45 .BR \-C ", " \-\-no\-close
46 Do not close any file descriptor when forcing the daemon into the background
47 (since version 1.16.5).
48 diff --git a/start-stop-daemon.c b/start-stop-daemon.c
49 index 3947cc0..1e0e163 100644
50 --- a/start-stop-daemon.c
51 +++ b/start-stop-daemon.c
52 @@ -20,10 +20,36 @@
53 * Changes by Ian Jackson: added --retry (and associated rearrangements).
54 */
55
56 +#if 0
57 #include <config.h>
58 #include <compat.h>
59
60 #include <dpkg/macros.h>
61 +#else
62 +# define VERSION "20200811"
63 +# define CRUX "CRUX-Linux"
64 +
65 +# define WANT_SYSTEMD_NOTIFY 0 /* 1=yes */
66 +
67 +# define HAVE_SYS_PARAM_H
68 +# define HAVE_SYS_SYSCALL_H
69 +# define HAVE_SYS_USER_H
70 +# define HAVE_STDDEF_H
71 +# define HAVE_ERROR_H
72 +# define HAVE_ERR_H
73 +
74 +# define HAVE_CLOCK_MONOTONIC
75 +# define HAVE_GETDTABLESIZE
76 +# define HAVE_IOPRIO_SET
77 +# define HAVE_SETSID
78 +
79 +# define DPKG_ATTR_NORET __attribute__((noreturn))
80 +# define DPKG_ATTR_PRINTF(X)
81 +# define DPKG_ATTR_VPRINTF(X)
82 +
83 +# define _GNU_SOURCE
84 +# include <unistd.h>
85 +#endif
86
87 #if defined(__linux__)
88 # define OS_Linux
89 @@ -160,6 +186,10 @@
90 #define HAVE_IOPRIO_SET
91 #endif
92
93 +#ifndef array_count
94 +# define array_count(x) (sizeof(x) / sizeof((x)[0]))
95 +#endif
96 +
97 #define IOPRIO_CLASS_SHIFT 13
98 #define IOPRIO_PRIO_VALUE(class, prio) (((class) << IOPRIO_CLASS_SHIFT) | (prio))
99 #define IO_SCHED_PRIO_MIN 0
100 @@ -212,10 +242,12 @@ static int quietmode = 0;
101 static int exitnodo = 1;
102 static bool background = false;
103 static bool close_io = true;
104 +#if WANT_SYSTEMD_NOTIFY
105 static bool notify_await = false;
106 static int notify_timeout = 60;
107 static char *notify_sockdir;
108 static char *notify_socket;
109 +#endif
110 static bool mpidfile = false;
111 static bool rpidfile = false;
112 static int signal_nr = SIGTERM;
113 @@ -405,8 +437,7 @@ xstrndup(const char *str, size_t n)
114 static void
115 timespec_gettime(struct timespec *ts)
116 {
117 -#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && \
118 - defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK > 0
119 +#ifdef HAVE_CLOCK_MONOTONIC
120 if (clock_gettime(CLOCK_MONOTONIC, ts) < 0)
121 fatale("clock_gettime failed");
122 #else
123 @@ -548,6 +579,7 @@ wait_for_child(pid_t pid)
124 }
125 }
126
127 +#if WANT_SYSTEMD_NOTIFY
128 static void
129 cleanup_socket_dir(void)
130 {
131 @@ -737,6 +769,7 @@ wait_for_notify(int fd)
132 }
133 }
134 }
135 +#endif /* WANT_SYSTEMD_NOTIFY */
136
137 static void
138 write_pidfile(const char *filename, pid_t pid)
139 @@ -769,7 +802,9 @@ remove_pidfile(const char *filename)
140 static void
141 daemonize(void)
142 {
143 +#if WANT_SYSTEMD_NOTIFY
144 int notify_fd = -1;
145 +#endif
146 pid_t pid;
147 sigset_t mask;
148 sigset_t oldmask;
149 @@ -783,8 +818,10 @@ daemonize(void)
150 if (sigprocmask(SIG_BLOCK, &mask, &oldmask) == -1)
151 fatale("cannot block SIGCHLD");
152
153 +#if WANT_SYSTEMD_NOTIFY
154 if (notify_await)
155 notify_fd = create_notify_socket();
156 +#endif
157
158 pid = fork();
159 if (pid < 0)
160 @@ -795,6 +832,7 @@ daemonize(void)
161 * not suffer from race conditions on return. */
162 wait_for_child(pid);
163
164 +#if WANT_SYSTEMD_NOTIFY
165 if (notify_await) {
166 /* Wait for a readiness notification from the second
167 * child, so that we can safely exit when the service
168 @@ -803,13 +841,16 @@ daemonize(void)
169 close(notify_fd);
170 cleanup_socket_dir();
171 }
172 +#endif
173
174 _exit(0);
175 }
176
177 /* Close the notification socket, even though it is close-on-exec. */
178 +#if WANT_SYSTEMD_NOTIFY
179 if (notify_await)
180 close(notify_fd);
181 +#endif
182
183 /* Create a new session. */
184 if (setsid() < 0)
185 @@ -905,8 +946,10 @@ usage(void)
186 " scheduler (default prio is 4)\n"
187 " -k, --umask <mask> change the umask to <mask> before starting\n"
188 " -b, --background force the process to detach\n"
189 +#if WANT_SYSTEMD_NOTIFY
190 " --notify-await wait for a readiness notification\n"
191 " --notify-timeout <int> timeout after <int> seconds of notify wait\n"
192 +#endif
193 " -C, --no-close do not close any file descriptor\n"
194 " -m, --make-pidfile create the pidfile before starting\n"
195 " --remove-pidfile delete the pidfile after stopping\n"
196 @@ -951,9 +994,9 @@ usage(void)
197 static void
198 do_version(void)
199 {
200 - printf("start-stop-daemon %s for Debian\n\n", VERSION);
201 -
202 - printf("Written by Marek Michalkiewicz, public domain.\n");
203 + printf("start-stop-daemon " VERSION " for " CRUX "\n\n"
204 + "Written by Marek Michalkiewicz, public domain.\n"
205 + "Adjusted for " CRUX ".\n");
206 }
207
208 static void DPKG_ATTR_NORET
209 @@ -1278,8 +1321,10 @@ parse_options(int argc, char * const *argv)
210 { "iosched", 1, NULL, 'I'},
211 { "umask", 1, NULL, 'k'},
212 { "background", 0, NULL, 'b'},
213 +#if WANT_SYSTEMD_NOTIFY
214 { "notify-await", 0, NULL, OPT_NOTIFY_AWAIT},
215 { "notify-timeout", 1, NULL, OPT_NOTIFY_TIMEOUT},
216 +#endif
217 { "no-close", 0, NULL, 'C'},
218 { "make-pidfile", 0, NULL, 'm'},
219 { "remove-pidfile", 0, NULL, OPT_RM_PIDFILE},
220 @@ -1294,7 +1339,9 @@ parse_options(int argc, char * const *argv)
221 const char *schedule_str = NULL;
222 const char *proc_schedule_str = NULL;
223 const char *io_schedule_str = NULL;
224 +#if WANT_SYSTEMD_NOTIFY
225 const char *notify_timeout_str = NULL;
226 +#endif
227 size_t changeuser_len;
228 int c;
229
230 @@ -1395,12 +1442,14 @@ parse_options(int argc, char * const *argv)
231 case 'b': /* --background */
232 background = true;
233 break;
234 +#if WANT_SYSTEMD_NOTIFY
235 case OPT_NOTIFY_AWAIT:
236 notify_await = true;
237 break;
238 case OPT_NOTIFY_TIMEOUT:
239 notify_timeout_str = optarg;
240 break;
241 +#endif
242 case 'C': /* --no-close */
243 close_io = false;
244 break;
245 @@ -1453,9 +1502,11 @@ parse_options(int argc, char * const *argv)
246 badusage("umask value must be a positive number");
247 }
248
249 +#if WANT_SYSTEMD_NOTIFY
250 if (notify_timeout_str != NULL)
251 if (parse_unsigned(notify_timeout_str, 10, ¬ify_timeout) != 0)
252 badusage("invalid notify timeout value");
253 +#endif
254
255 if (action == ACTION_NONE)
256 badusage("need one of --start or --stop or --status");
257 @@ -2303,7 +2354,8 @@ do_pidfile(const char *name)
258
259 if (match_mode == MATCH_PIDFILE &&
260 ((st.st_uid != getuid() && st.st_uid != 0) ||
261 - (st.st_gid != getgid() && st.st_gid != 0)))
262 + ((st.st_gid != getgid() && st.st_gid != 0) &&
263 + (st.st_mode & 0020))))
264 fatal("matching only on non-root pidfile %s is insecure", name);
265 if (st.st_mode & 0002)
266 fatal("matching on world-writable pidfile %s is insecure", name);
|