about summary refs log tree commit diff
path: root/shared/systemd/src/basic/fileio.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared/systemd/src/basic/fileio.c')
-rw-r--r--shared/systemd/src/basic/fileio.c83
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 */