summaryrefslogtreecommitdiff
path: root/gsystem-file-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'gsystem-file-utils.c')
-rw-r--r--gsystem-file-utils.c78
1 files changed, 47 insertions, 31 deletions
diff --git a/gsystem-file-utils.c b/gsystem-file-utils.c
index 0486bf8..e23f17e 100644
--- a/gsystem-file-utils.c
+++ b/gsystem-file-utils.c
@@ -68,29 +68,56 @@ open_nointr (const char *path, int flags, mode_t mode)
return res;
}
-static int
-_open_fd_noatime (const char *path)
+static inline void
+_set_error_from_errno (GError **error)
+{
+ int errsv = errno;
+ g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv),
+ g_strerror (errsv));
+}
+
+/**
+ * gs_file_openat_noatime:
+ * @dfd: File descriptor for directory
+ * @name: Pathname, relative to @dfd
+ * @ret_fd: (out): Returned file descriptor
+ * @cancellable: Cancellable
+ * @error: Error
+ *
+ * Wrapper for openat() using %O_RDONLY with %O_NOATIME if available.
+ */
+gboolean
+gs_file_openat_noatime (int dfd,
+ const char *name,
+ int *ret_fd,
+ GCancellable *cancellable,
+ GError **error)
{
int fd;
#ifdef O_NOATIME
- fd = open_nointr (path, O_RDONLY | O_NOATIME, 0);
+ do
+ fd = openat (dfd, name, O_RDONLY | O_NOATIME, 0);
+ while (G_UNLIKELY (fd == -1 && errno == EINTR));
/* Only the owner or superuser may use O_NOATIME; so we may get
* EPERM. EINVAL may happen if the kernel is really old...
*/
if (fd == -1 && (errno == EPERM || errno == EINVAL))
#endif
- fd = open_nointr (path, O_RDONLY, 0);
+ do
+ fd = openat (dfd, name, O_RDONLY, 0);
+ while (G_UNLIKELY (fd == -1 && errno == EINTR));
- return fd;
-}
-
-static inline void
-_set_error_from_errno (GError **error)
-{
- int errsv = errno;
- g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv),
- g_strerror (errsv));
+ if (fd == -1)
+ {
+ _set_error_from_errno (error);
+ return FALSE;
+ }
+ else
+ {
+ *ret_fd = fd;
+ return TRUE;
+ }
}
/**
@@ -127,12 +154,8 @@ gs_file_read_noatime (GFile *file,
return NULL;
}
- fd = _open_fd_noatime (path);
- if (fd < 0)
- {
- _set_error_from_errno (error);
- return NULL;
- }
+ if (!gs_file_openat_noatime (AT_FDCWD, path, &fd, cancellable, error))
+ return NULL;
return g_unix_input_stream_new (fd, TRUE);
}
@@ -203,12 +226,8 @@ gs_file_map_noatime (GFile *file,
if (path == NULL)
return NULL;
- fd = _open_fd_noatime (path);
- if (fd < 0)
- {
- _set_error_from_errno (error);
- return NULL;
- }
+ if (!gs_file_openat_noatime (AT_FDCWD, path, &fd, cancellable, error))
+ return NULL;
ret = g_mapped_file_new_from_fd (fd, FALSE, error);
close_nointr_noerror (fd); /* Ignore errors - we always want to close */
@@ -267,12 +286,9 @@ gs_file_sync_data (GFile *file,
int res;
int fd = -1;
- fd = _open_fd_noatime (gs_file_get_path_cached (file));
- if (fd < 0)
- {
- _set_error_from_errno (error);
- goto out;
- }
+ if (!gs_file_openat_noatime (AT_FDCWD, gs_file_get_path_cached (file), &fd,
+ cancellable, error))
+ goto out;
do
res = fdatasync (fd);