diff options
| author | Michael Biebl <biebl@debian.org> | 2019-03-26 23:25:23 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2019-03-26 23:25:23 +0100 |
| commit | 9a6dcbf895f9da01768e64b73cec88c16157d91e (patch) | |
| tree | a359958930d731e9f1b59344642e10754419fe84 /shared/nm-utils/nm-io-utils.c | |
| parent | 964ae8cc391520440cf5aa13e2b9cc34850ea6c2 (diff) | |
New upstream version 1.16.0 upstream/1.16.0
Diffstat (limited to 'shared/nm-utils/nm-io-utils.c')
| -rw-r--r-- | shared/nm-utils/nm-io-utils.c | 81 |
1 files changed, 45 insertions, 36 deletions
diff --git a/shared/nm-utils/nm-io-utils.c b/shared/nm-utils/nm-io-utils.c index 88cb13ff..51312748 100644 --- a/shared/nm-utils/nm-io-utils.c +++ b/shared/nm-utils/nm-io-utils.c @@ -29,6 +29,7 @@ #include "nm-shared-utils.h" #include "nm-secret-utils.h" +#include "nm-errno.h" /*****************************************************************************/ @@ -36,14 +37,12 @@ _nm_printf (3, 4) static int _get_contents_error (GError **error, int errsv, const char *format, ...) { - if (errsv < 0) - errsv = -errsv; - else if (!errsv) - errsv = errno; + nm_assert (NM_ERRNO_NATIVE (errsv)); if (error) { - char *msg; + gs_free char *msg = NULL; va_list args; + char bstrerr[NM_STRERROR_BUFSIZE]; va_start (args, format); msg = g_strdup_vprintf (format, args); @@ -52,11 +51,17 @@ _get_contents_error (GError **error, int errsv, const char *format, ...) G_FILE_ERROR, g_file_error_from_errno (errsv), "%s: %s", - msg, g_strerror (errsv)); - g_free (msg); + msg, + nm_strerror_native_r (errsv, bstrerr, sizeof (bstrerr))); } return -errsv; } +#define _get_contents_error_errno(error, ...) \ + ({ \ + int _errsv = (errno); \ + \ + _get_contents_error (error, _errsv, __VA_ARGS__); \ + }) static char * _mem_realloc (char *old, gboolean do_bzero_mem, gsize cur_len, gsize new_len) @@ -110,7 +115,7 @@ _mem_realloc (char *old, gboolean do_bzero_mem, gsize cur_len, gsize new_len) * A reimplementation of g_file_get_contents() with a few differences: * - accepts an open fd, instead of a path name. This allows you to * use openat(). - * - limits the maxium filesize to max_length. + * - limits the maximum filesize to max_length. * * Returns: a negative error code on failure. */ @@ -127,13 +132,14 @@ nm_utils_fd_get_contents (int fd, struct stat stat_buf; gs_free char *str = NULL; const bool do_bzero_mem = NM_FLAGS_HAS (flags, NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET); + int errsv; g_return_val_if_fail (fd >= 0, -EINVAL); g_return_val_if_fail (contents, -EINVAL); g_return_val_if_fail (!error || !*error, -EINVAL); if (fstat (fd, &stat_buf) < 0) - return _get_contents_error (error, 0, "failure during fstat"); + return _get_contents_error_errno (error, "failure during fstat"); if (!max_length) { /* default to a very large size, but not extreme */ @@ -156,7 +162,7 @@ nm_utils_fd_get_contents (int fd, if (n_read < 0) { if (do_bzero_mem) nm_explicit_bzero (str, n_stat); - return _get_contents_error (error, n_read, "error reading %zu bytes from file descriptor", n_stat); + return _get_contents_error (error, -n_read, "error reading %zu bytes from file descriptor", n_stat); } str[n_read] = '\0'; @@ -176,19 +182,19 @@ nm_utils_fd_get_contents (int fd, else { fd2 = fcntl (fd, F_DUPFD_CLOEXEC, 0); if (fd2 < 0) - return _get_contents_error (error, 0, "error during dup"); + return _get_contents_error_errno (error, "error during dup"); } if (!(f = fdopen (fd2, "r"))) { + errsv = errno; nm_close (fd2); - return _get_contents_error (error, 0, "failure during fdopen"); + return _get_contents_error (error, errsv, "failure during fdopen"); } n_have = 0; n_alloc = 0; while (!feof (f)) { - int errsv; gsize n_read; n_read = fread (buf, 1, sizeof (buf), f); @@ -262,13 +268,13 @@ nm_utils_fd_get_contents (int fd, * @flags: %NMUtilsFileGetContentsFlags for reading the file. * @contents: the output buffer with the file read. It is always * NUL terminated. The buffer is at most @max_length long, including - * the NUL byte. That is, it reads only files up to a length of - * @max_length - 1 bytes. + * the NUL byte. That is, it reads only files up to a length of + * @max_length - 1 bytes. * @length: optional output argument of the read file size. * * A reimplementation of g_file_get_contents() with a few differences: * - accepts an @dirfd to open @filename relative to that path via openat(). - * - limits the maxium filesize to max_length. + * - limits the maximum filesize to max_length. * - uses O_CLOEXEC on internal file descriptor * * Returns: a negative error code on failure. @@ -284,6 +290,7 @@ nm_utils_file_get_contents (int dirfd, { int fd; int errsv; + char bstrerr[NM_STRERROR_BUFSIZE]; g_return_val_if_fail (filename && filename[0], -EINVAL); @@ -297,8 +304,8 @@ nm_utils_file_get_contents (int dirfd, g_file_error_from_errno (errsv), "Failed to open file \"%s\" with openat: %s", filename, - g_strerror (errsv)); - return -errsv; + nm_strerror_native_r (errsv, bstrerr, sizeof (bstrerr))); + return -NM_ERRNO_NATIVE (errsv); } } else { fd = open (filename, O_RDONLY | O_CLOEXEC); @@ -310,8 +317,8 @@ nm_utils_file_get_contents (int dirfd, g_file_error_from_errno (errsv), "Failed to open file \"%s\": %s", filename, - g_strerror (errsv)); - return -errsv; + nm_strerror_native_r (errsv, bstrerr, sizeof (bstrerr))); + return -NM_ERRNO_NATIVE (errsv); } } return nm_utils_fd_get_contents (fd, @@ -341,6 +348,7 @@ nm_utils_file_set_contents (const char *filename, int errsv; gssize s; int fd; + char bstrerr[NM_STRERROR_BUFSIZE]; g_return_val_if_fail (filename, FALSE); g_return_val_if_fail (contents || !length, FALSE); @@ -351,7 +359,7 @@ nm_utils_file_set_contents (const char *filename, length = strlen (contents); tmp_name = g_strdup_printf ("%s.XXXXXX", filename); - fd = g_mkstemp_full (tmp_name, O_RDWR, mode); + fd = g_mkstemp_full (tmp_name, O_RDWR | O_CLOEXEC, mode); if (fd < 0) { errsv = errno; g_set_error (error, @@ -359,7 +367,7 @@ nm_utils_file_set_contents (const char *filename, g_file_error_from_errno (errsv), "failed to create file %s: %s", tmp_name, - g_strerror (errsv)); + nm_strerror_native_r (errsv, bstrerr, sizeof (bstrerr))); return FALSE; } @@ -378,7 +386,7 @@ nm_utils_file_set_contents (const char *filename, g_file_error_from_errno (errsv), "failed to write to file %s: %s", tmp_name, - g_strerror (errsv)); + nm_strerror_native_r (errsv, bstrerr, sizeof (bstrerr))); return FALSE; } @@ -395,20 +403,21 @@ nm_utils_file_set_contents (const char *filename, * guarantee the data is written to the disk before the metadata.) */ if ( lstat (filename, &statbuf) == 0 - && statbuf.st_size > 0 - && fsync (fd) != 0) { - errsv = errno; + && statbuf.st_size > 0) { + if (fsync (fd) != 0) { + errsv = errno; - nm_close (fd); - unlink (tmp_name); + nm_close (fd); + unlink (tmp_name); - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (errsv), - "failed to fsync %s: %s", - tmp_name, - g_strerror (errsv)); - return FALSE; + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errsv), + "failed to fsync %s: %s", + tmp_name, + nm_strerror_native_r (errsv, bstrerr, sizeof (bstrerr))); + return FALSE; + } } nm_close (fd); @@ -422,7 +431,7 @@ nm_utils_file_set_contents (const char *filename, "failed to rename %s to %s: %s", tmp_name, filename, - g_strerror (errsv)); + nm_strerror_native_r (errsv, bstrerr, sizeof (bstrerr))); return FALSE; } |