return r;
}
+int reset_signal_mask(void) {
+ sigset_t ss;
+
+ if (sigemptyset(&ss) < 0)
+ return -errno;
+
+ if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0)
+ return -errno;
+
+ return 0;
+}
+
char *strstrip(char *s) {
char *e;
c++;
}
- if (fd < 0)
- return -errno;
-
r = isatty(fd);
if (r < 0) {
safe_close(fd);
* ended our handle will be dead. It's important that
* we do this after sleeping, so that we don't enter
* an endless loop. */
- safe_close(fd);
+ fd = safe_close(fd);
}
safe_close(notify);
return !isempty(u.nodename) && !streq(u.nodename, "(none)");
}
-static char *lookup_uid(uid_t uid) {
+char *lookup_uid(uid_t uid) {
long bufsize;
char *name;
_cleanup_free_ char *buf = NULL;
c = 0;
e = getenv("COLUMNS");
if (e)
- safe_atoi(e, &c);
+ (void) safe_atoi(e, &c);
if (c <= 0)
c = fd_columns(STDOUT_FILENO);
l = 0;
e = getenv("LINES");
if (e)
- safe_atou(e, &l);
+ (void) safe_atou(e, &l);
if (l <= 0)
l = fd_lines(STDOUT_FILENO);
_cleanup_hashmap_free_free_ Hashmap *pids = NULL;
_cleanup_closedir_ DIR *_d = NULL;
struct dirent *de;
- sigset_t ss;
/* We fork this all off from a child process so that
* we can somewhat cleanly make use of SIGALRM to set
* a time limit */
reset_all_signal_handlers();
-
- assert_se(sigemptyset(&ss) == 0);
- assert_se(sigprocmask(SIG_SETMASK, &ss, NULL) == 0);
+ reset_signal_mask();
assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
}
}
- pids = hashmap_new(NULL, NULL);
+ pids = hashmap_new(NULL);
if (!pids) {
log_oom();
_exit(EXIT_FAILURE);
return loaded;
}
-int strdup_or_null(const char *a, char **b) {
- char *c;
-
- assert(b);
-
- if (!a) {
- *b = NULL;
- return 0;
- }
-
- c = strdup(a);
- if (!c)
- return -ENOMEM;
-
- *b = c;
- return 0;
-}
-
int prot_from_flags(int flags) {
switch (flags & O_ACCMODE) {
}
int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
- pid_t parent_pid, agent_pid;
- int fd;
bool stdout_is_tty, stderr_is_tty;
+ pid_t parent_pid, agent_pid;
+ sigset_t ss, saved_ss;
unsigned n, i;
va_list ap;
char **l;
assert(pid);
assert(path);
- parent_pid = getpid();
-
/* Spawns a temporary TTY agent, making sure it goes away when
* we go away */
+ parent_pid = getpid();
+
+ /* First we temporarily block all signals, so that the new
+ * child has them blocked initially. This way, we can be sure
+ * that SIGTERMs are not lost we might send to the agent. */
+ assert_se(sigfillset(&ss) >= 0);
+ assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
+
agent_pid = fork();
- if (agent_pid < 0)
+ if (agent_pid < 0) {
+ assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
return -errno;
+ }
if (agent_pid != 0) {
+ assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
*pid = agent_pid;
return 0;
}
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
_exit(EXIT_FAILURE);
+ /* Make sure we actually can kill the agent, if we need to, in
+ * case somebody invoked us from a shell script that trapped
+ * SIGTERM or so... */
+ reset_all_signal_handlers();
+ reset_signal_mask();
+
/* Check whether our parent died before we were able
- * to set the death signal */
+ * to set the death signal and unblock the signals */
if (getppid() != parent_pid)
_exit(EXIT_SUCCESS);
stderr_is_tty = isatty(STDERR_FILENO);
if (!stdout_is_tty || !stderr_is_tty) {
+ int fd;
+
/* Detach from stdout/stderr. and reopen
* /dev/tty for them. This is important to
* ensure that when systemctl is started via
path_kill_slashes(cleaned);
- done = set_new(string_hash_func, string_compare_func);
+ done = set_new(&string_hash_ops);
if (!done)
return -ENOMEM;
bool top_autofs = false;
char *x;
- todo = set_new(string_hash_func, string_compare_func);
+ todo = set_new(&string_hash_ops);
if (!todo)
return -ENOMEM;