diff options
| author | Michael Biebl <biebl@debian.org> | 2020-06-28 18:58:14 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-06-28 18:58:14 +0200 |
| commit | a54ac63bbf9b2c71026ac9028a8ffaf186cf3c82 (patch) | |
| tree | 6a32883bd916c4096357b35298beff6db8bcd0b5 /shared/systemd/src/basic/fileio.c | |
| parent | 45e8e1149027529194982212c804c0468aa01d98 (diff) | |
New upstream version 1.25.90 upstream/1.25.90
Diffstat (limited to 'shared/systemd/src/basic/fileio.c')
| -rw-r--r-- | shared/systemd/src/basic/fileio.c | 83 |
1 files changed, 69 insertions, 14 deletions
diff --git a/shared/systemd/src/basic/fileio.c b/shared/systemd/src/basic/fileio.c index 543dd4eb..30903263 100644 --- a/shared/systemd/src/basic/fileio.c +++ b/shared/systemd/src/basic/fileio.c @@ -122,7 +122,7 @@ int write_string_stream_ts( struct timespec *ts) { bool needs_nl; - int r; + int r, fd; assert(f); assert(line); @@ -130,6 +130,14 @@ int write_string_stream_ts( if (ferror(f)) return -EIO; + if (ts) { + /* If we shall set the timestamp we need the fd. But fmemopen() streams generally don't have + * an fd. Let's fail early in that case. */ + fd = fileno(f); + if (fd < 0) + return -EBADF; + } + needs_nl = !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n"); if (needs_nl && (flags & WRITE_STRING_FILE_DISABLE_BUFFER)) { @@ -157,7 +165,7 @@ int write_string_stream_ts( if (ts) { struct timespec twice[2] = {*ts, *ts}; - if (futimens(fileno(f), twice) < 0) + if (futimens(fd, twice) < 0) return -errno; } @@ -197,6 +205,13 @@ static int write_string_file_atomic( goto fail; } + if (FLAGS_SET(flags, WRITE_STRING_FILE_SYNC)) { + /* Sync the rename, too */ + r = fsync_directory_of_file(fileno(f)); + if (r < 0) + return r; + } + return 0; fail: @@ -415,7 +430,7 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re break; } - if (errno != -EINTR) + if (errno != EINTR) return -errno; } @@ -895,7 +910,7 @@ int fflush_and_check(FILE *f) { #if 0 /* NM_IGNORED */ int fflush_sync_and_check(FILE *f) { - int r; + int r, fd; assert(f); @@ -903,10 +918,16 @@ int fflush_sync_and_check(FILE *f) { if (r < 0) return r; - if (fsync(fileno(f)) < 0) + /* Not all file streams have an fd associated (think: fmemopen()), let's handle this gracefully and + * assume that in that case we need no explicit syncing */ + fd = fileno(f); + if (fd < 0) + return 0; + + if (fsync(fd) < 0) return -errno; - r = fsync_directory_of_file(fileno(f)); + r = fsync_directory_of_file(fd); if (r < 0) return r; @@ -1006,7 +1027,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, funlockfile); int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) { size_t n = 0, allocated = 0, count = 0; _cleanup_free_ char *buffer = NULL; - int r, tty = -1; + int r; assert(f); @@ -1081,13 +1102,23 @@ int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) { count++; if (eol != EOL_NONE) { - /* If we are on a tty, we can't wait for more input. But we expect only - * \n as the single EOL marker, so there is no need to wait. We check - * this condition last to avoid isatty() check if not necessary. */ - - if (tty < 0) - tty = isatty(fileno(f)); - if (tty > 0) + /* If we are on a tty, we can't shouldn't wait for more input, because that + * generally means waiting for the user, interactively. In the case of a TTY + * we expect only \n as the single EOL marker, so we are in the lucky + * position that there is no need to wait. We check this condition last, to + * avoid isatty() check if not necessary. */ + + if ((flags & (READ_LINE_IS_A_TTY|READ_LINE_NOT_A_TTY)) == 0) { + int fd; + + fd = fileno(f); + if (fd < 0) /* Maybe an fmemopen() stream? Handle this gracefully, + * and don't call isatty() on an invalid fd */ + flags |= READ_LINE_NOT_A_TTY; + else + flags |= isatty(fd) ? READ_LINE_IS_A_TTY : READ_LINE_NOT_A_TTY; + } + if (FLAGS_SET(flags, READ_LINE_IS_A_TTY)) break; } @@ -1168,3 +1199,27 @@ int warn_file_is_world_accessible(const char *filename, struct stat *st, const c filename, st->st_mode & 07777); return 0; } + +#if 0 /* NM_IGNORED */ +int sync_rights(int from, int to) { + struct stat st; + + if (fstat(from, &st) < 0) + return -errno; + + return fchmod_and_chown(to, st.st_mode & 07777, st.st_uid, st.st_gid); +} + +int rename_and_apply_smack_floor_label(const char *from, const char *to) { + int r = 0; + if (rename(from, to) < 0) + return -errno; + +#ifdef SMACK_RUN_LABEL + r = mac_smack_apply(to, SMACK_ATTR_ACCESS, SMACK_FLOOR_LABEL); + if (r < 0) + return r; +#endif + return r; +} +#endif /* NM_IGNORED */ |