Merge pull request #3818 from poettering/exit-status-env

beef up /var/tmp and /tmp handling; set $SERVICE_RESULT/$EXIT_CODE/$EXIT_STATUS on ExecStop= and make sure root/nobody are always resolvable
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2016-08-05 20:55:08 -04:00
committed by GitHub
24 changed files with 416 additions and 196 deletions
+13 -4
View File
@@ -1168,8 +1168,8 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) {
char *t, *x;
uint64_t u;
unsigned i;
int r;
assert(p);
assert(ret);
/* Turns this:
@@ -1178,6 +1178,12 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) {
* /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
*/
if (!p) {
r = tmp_dir(&p);
if (r < 0)
return r;
}
if (!extra)
extra = "";
@@ -1264,10 +1270,13 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space)
int open_tmpfile_unlinkable(const char *directory, int flags) {
char *p;
int fd;
int fd, r;
if (!directory)
directory = "/tmp";
if (!directory) {
r = tmp_dir(&directory);
if (r < 0)
return r;
}
/* Returns an unlinked temporary file that cannot be linked into the file system anymore */
+79 -19
View File
@@ -496,34 +496,94 @@ int get_files_in_directory(const char *path, char ***list) {
return n;
}
int var_tmp(char **ret) {
const char *tmp_dir = NULL;
const char *env_tmp_dir = NULL;
char *c = NULL;
int r;
static int getenv_tmp_dir(const char **ret_path) {
const char *n;
int r, ret = 0;
assert(ret);
assert(ret_path);
env_tmp_dir = getenv("TMPDIR");
if (env_tmp_dir != NULL) {
r = is_dir(env_tmp_dir, true);
if (r < 0 && r != -ENOENT)
return r;
if (r > 0)
tmp_dir = env_tmp_dir;
/* We use the same order of environment variables python uses in tempfile.gettempdir():
* https://docs.python.org/3/library/tempfile.html#tempfile.gettempdir */
FOREACH_STRING(n, "TMPDIR", "TEMP", "TMP") {
const char *e;
e = secure_getenv(n);
if (!e)
continue;
if (!path_is_absolute(e)) {
r = -ENOTDIR;
goto next;
}
if (!path_is_safe(e)) {
r = -EPERM;
goto next;
}
r = is_dir(e, true);
if (r < 0)
goto next;
if (r == 0) {
r = -ENOTDIR;
goto next;
}
*ret_path = e;
return 1;
next:
/* Remember first error, to make this more debuggable */
if (ret >= 0)
ret = r;
}
if (!tmp_dir)
tmp_dir = "/var/tmp";
if (ret < 0)
return ret;
c = strdup(tmp_dir);
if (!c)
return -ENOMEM;
*ret = c;
*ret_path = NULL;
return ret;
}
static int tmp_dir_internal(const char *def, const char **ret) {
const char *e;
int r, k;
assert(def);
assert(ret);
r = getenv_tmp_dir(&e);
if (r > 0) {
*ret = e;
return 0;
}
k = is_dir(def, true);
if (k == 0)
k = -ENOTDIR;
if (k < 0)
return r < 0 ? r : k;
*ret = def;
return 0;
}
int var_tmp_dir(const char **ret) {
/* Returns the location for "larger" temporary files, that is backed by physical storage if available, and thus
* even might survive a boot: /var/tmp. If $TMPDIR (or related environment variables) are set, its value is
* returned preferably however. Note that both this function and tmp_dir() below are affected by $TMPDIR,
* making it a variable that overrides all temporary file storage locations. */
return tmp_dir_internal("/var/tmp", ret);
}
int tmp_dir(const char **ret) {
/* Similar to var_tmp_dir() above, but returns the location for "smaller" temporary files, which is usually
* backed by an in-memory file system: /tmp. */
return tmp_dir_internal("/tmp", ret);
}
int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
char path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
int r;
+2 -1
View File
@@ -61,7 +61,8 @@ int mkfifo_atomic(const char *path, mode_t mode);
int get_files_in_directory(const char *path, char ***list);
int var_tmp(char **ret);
int tmp_dir(const char **ret);
int var_tmp_dir(const char **ret);
#define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1)