diff --git a/glnx-fdio.c b/glnx-fdio.c index 42fc10ab0138833b048a8ab1ac1e33a3b18e9055..b45b927bca3a81e03a833f5a9d93f06fa45007e0 100644 --- a/glnx-fdio.c +++ b/glnx-fdio.c @@ -587,7 +587,7 @@ glnx_file_copy_at (int src_dfd, } /** - * glnx_file_replace_contents_utf8_at: + * glnx_file_replace_contents_at: * @dfd: Directory fd * @subpath: Subpath * @buf: (array len=len) (element-type guint8): File contents @@ -609,10 +609,40 @@ glnx_file_replace_contents_at (int dfd, const char *subpath, const guint8 *buf, gsize len, - int mode, GLnxFileReplaceFlags flags, GCancellable *cancellable, GError **error) +{ + return glnx_file_replace_contents_with_perms_at (dfd, subpath, buf, len, + (mode_t) -1, (uid_t) -1, (gid_t) -1, + flags, cancellable, error); + +} + +/** + * glnx_file_replace_contents_with_perms_at: + * @dfd: Directory fd + * @subpath: Subpath + * @buf: (array len=len) (element-type guint8): File contents + * @len: Length (if `-1`, assume @buf is `NUL` terminated) + * @flags: Flags + * @cancellable: Cancellable + * @error: Error + * + * Like glnx_file_replace_contents_at(), but also supports + * setting mode, and uid/gid. + */ +gboolean +glnx_file_replace_contents_with_perms_at (int dfd, + const char *subpath, + const guint8 *buf, + gsize len, + mode_t mode, + uid_t uid, + gid_t gid, + GLnxFileReplaceFlags flags, + GCancellable *cancellable, + GError **error) { gboolean ret = FALSE; /* We use the /proc/self trick as there's no mkostemp_at() yet */ @@ -625,12 +655,6 @@ glnx_file_replace_contents_at (int dfd, goto out; } - if (fchmod (fd, mode) != 0) - { - glnx_set_error_from_errno (error); - goto out; - } - if (len == -1) len = strlen ((char*)buf); @@ -673,6 +697,24 @@ glnx_file_replace_contents_at (int dfd, } } + if (uid != (uid_t) -1) + { + if (fchown (fd, uid, gid) != 0) + { + glnx_set_error_from_errno (error); + goto out; + } + } + + if (mode != (mode_t) -1) + { + if (fchmod (fd, mode) != 0) + { + glnx_set_error_from_errno (error); + goto out; + } + } + if (renameat (dfd, tmppath, dfd, subpath) != 0) { glnx_set_error_from_errno (error); diff --git a/glnx-fdio.h b/glnx-fdio.h index a380c1f8c46fd8f9d215692e738bd6be6b865e64..a90544a9d80c2cc2a600e9f93f0d158aee8e1baf 100644 --- a/glnx-fdio.h +++ b/glnx-fdio.h @@ -80,11 +80,22 @@ glnx_file_replace_contents_at (int dfd, const char *subpath, const guint8 *buf, gsize len, - int mode, GLnxFileReplaceFlags flags, GCancellable *cancellable, GError **error); +gboolean +glnx_file_replace_contents_with_perms_at (int dfd, + const char *subpath, + const guint8 *buf, + gsize len, + mode_t mode, + uid_t uid, + gid_t gid, + GLnxFileReplaceFlags flags, + GCancellable *cancellable, + GError **error); + char * glnx_readlinkat_malloc (int dfd, const char *subpath,