]> wimlib.net Git - wimlib/blobdiff - src/util.c
wimlib_vmsg(): Fix error msg printing
[wimlib] / src / util.c
index ed4779516b7501c985080ae3700cac4c5311664f..f915f2fe855b2f67db21e5b0be1365acfd0d943a 100644 (file)
  * along with wimlib; if not, see http://www.gnu.org/licenses/.
  */
 
+#undef _GNU_SOURCE
+/* Make sure the POSIX-compatible strerror_r() is declared, rather than the GNU
+ * version, which has a different return type. */
+#define _POSIX_C_SOURCE 200112
+#include <string.h>
+#define _GNU_SOURCE
+
 #include "wimlib_internal.h"
 #include "endianness.h"
-#include "sha1.h"
 #include "timestamp.h"
-#include <sys/time.h>
 
-
-#include <iconv.h>
-#include <string.h>
 #include <ctype.h>
-#include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
 #include <errno.h>
+#include <stdlib.h>
+
+#include <unistd.h> /* for getpid() */
 
 /* True if wimlib is to print an informational message when an error occurs.
  * This can be turned off by calling wimlib_set_print_errors(false). */
 #ifdef ENABLE_ERROR_MESSAGES
 #include <stdarg.h>
-bool __wimlib_print_errors = false;
+static bool wimlib_print_errors = false;
 
-void wimlib_error(const char *format, ...)
+static void wimlib_vmsg(const char *tag, const char *format,
+                       va_list va, bool perror)
 {
-       if (__wimlib_print_errors) {
-               va_list va;
-               int errno_save;
-
-               va_start(va, format);
-               errno_save = errno;
-               fputs("[ERROR] ", stderr);
+       if (wimlib_print_errors) {
+               int errno_save = errno;
+               fflush(stdout);
+               fputs(tag, stderr);
                vfprintf(stderr, format, va);
+               if (perror && errno_save != 0) {
+                       char buf[50];
+                       int res = strerror_r(errno_save, buf, sizeof(buf));
+                       if (res) {
+                               snprintf(buf, sizeof(buf),
+                                        "unknown error (errno=%d)", errno_save);
+                       }
+                       fprintf(stderr, ": %s", buf);
+               }
                putc('\n', stderr);
                errno = errno_save;
-               va_end(va);
        }
 }
 
+void wimlib_error(const char *format, ...)
+{
+       va_list va;
+
+       va_start(va, format);
+       wimlib_vmsg("[ERROR] ", format, va, false);
+       va_end(va);
+}
+
 void wimlib_error_with_errno(const char *format, ...)
 {
-       if (__wimlib_print_errors) {
-               va_list va;
-               int errno_save;
+       va_list va;
 
-               va_start(va, format);
-               errno_save = errno;
-               fflush(stdout);
-               fputs("[ERROR] ", stderr);
-               vfprintf(stderr, format, va);
-               fprintf(stderr, ": %s\n", strerror(errno_save));
-               errno = errno_save;
-               va_end(va);
-       }
+       va_start(va, format);
+       wimlib_vmsg("[ERROR] ", format, va, true);
+       va_end(va);
 }
 
 void wimlib_warning(const char *format, ...)
 {
-       if (__wimlib_print_errors) {
-               va_list va;
-               int errno_save;
+       va_list va;
 
-               va_start(va, format);
-               errno_save = errno;
-               fflush(stdout);
-               fputs("[WARNING] ", stderr);
-               vfprintf(stderr, format, va);
-               putc('\n', stderr);
-               errno = errno_save;
-               va_end(va);
-       }
+       va_start(va, format);
+       wimlib_vmsg("[WARNING] ", format, va, false);
+       va_end(va);
+}
+
+void wimlib_warning_with_errno(const char *format, ...)
+{
+       va_list va;
+
+       va_start(va, format);
+       wimlib_vmsg("[WARNING] ", format, va, true);
+       va_end(va);
 }
 
 #endif
@@ -97,7 +107,7 @@ void wimlib_warning(const char *format, ...)
 WIMLIBAPI int wimlib_set_print_errors(bool show_error_messages)
 {
 #ifdef ENABLE_ERROR_MESSAGES
-       __wimlib_print_errors = show_error_messages;
+       wimlib_print_errors = show_error_messages;
        return 0;
 #else
        if (show_error_messages)
@@ -112,14 +122,14 @@ static const char *error_strings[] = {
                = "Success",
        [WIMLIB_ERR_ALREADY_LOCKED]
                = "The WIM is already locked for writing",
-       [WIMLIB_ERR_CHAR_CONVERSION]
-               = "Failed to perform a conversion between UTF-8 and UTF-16LE",
        [WIMLIB_ERR_COMPRESSED_LOOKUP_TABLE]
                = "Lookup table is compressed",
        [WIMLIB_ERR_DECOMPRESSION]
                = "Failed to decompress compressed data",
        [WIMLIB_ERR_DELETE_STAGING_DIR]
                = "Failed to delete staging directory",
+       [WIMLIB_ERR_FILESYSTEM_DAEMON_CRASHED]
+               = "The process servicing the mounted WIM has crashed",
        [WIMLIB_ERR_FORK]
                = "Failed to fork another process",
        [WIMLIB_ERR_FUSE]
@@ -158,11 +168,21 @@ static const char *error_strings[] = {
                = "The part number or total parts of the WIM is invalid",
        [WIMLIB_ERR_INVALID_RESOURCE_HASH]
                = "The SHA1 message digest of a WIM resource did not match the expected value",
+       [WIMLIB_ERR_ICONV_NOT_AVAILABLE]
+               = "The iconv() function does not seem to work. "
+                 "Maybe check to make sure the directory /usr/lib/gconv exists",
        [WIMLIB_ERR_INVALID_RESOURCE_SIZE]
                = "A resource entry in the WIM has an invalid size",
        [WIMLIB_ERR_INVALID_UNMOUNT_MESSAGE]
                = "The version of wimlib that has mounted a WIM image is incompatible with the "
                  "version being used to unmount it",
+       [WIMLIB_ERR_INVALID_UTF8_STRING]
+               = "A string provided as input by the user was not a valid UTF-8 string",
+       [WIMLIB_ERR_INVALID_UTF16_STRING]
+               = "A string in a WIM dentry is not a valid UTF-16LE string",
+       [WIMLIB_ERR_LIBXML_UTF16_HANDLER_NOT_AVAILABLE]
+               = "libxml2 was unable to find a character encoding conversion handler "
+                 "for UTF-16LE",
        [WIMLIB_ERR_LINK]
                = "Failed to create a hard or symbolic link when extracting "
                        "a file from the WIM",
@@ -203,8 +223,6 @@ static const char *error_strings[] = {
                = "The WIM is part of a split WIM, which is not supported for this operation",
        [WIMLIB_ERR_STAT]
                = "Could not read the metadata for a file or directory",
-       [WIMLIB_ERR_TIMEOUT]
-               = "Timed out",
        [WIMLIB_ERR_UNKNOWN_VERSION]
                = "The WIM file is marked with an unknown version number",
        [WIMLIB_ERR_UNSUPPORTED]
@@ -276,93 +294,6 @@ WIMLIBAPI int wimlib_set_memory_allocator(void *(*malloc_func)(size_t),
 #endif
 }
 
-
-
-static iconv_t cd_utf16_to_utf8 = (iconv_t)(-1);
-
-/* Converts a string in the UTF-16 encoding to a newly allocated string in the
- * UTF-8 encoding.  */
-char *utf16_to_utf8(const char *utf16_str, size_t utf16_len,
-                   size_t *utf8_len_ret)
-{
-       if (cd_utf16_to_utf8 == (iconv_t)(-1)) {
-               cd_utf16_to_utf8 = iconv_open("UTF-8", "UTF-16LE");
-               if (cd_utf16_to_utf8 == (iconv_t)-1) {
-                       ERROR_WITH_ERRNO("Failed to get conversion descriptor "
-                                        "for converting UTF-16LE to UTF-8");
-                       return NULL;
-               }
-       }
-       size_t utf16_bytes_left  = utf16_len;
-       size_t utf8_bytes_left   = utf16_len;
-
-       char *utf8_str = MALLOC(utf8_bytes_left);
-       if (!utf8_str)
-               return NULL;
-
-       char *orig_utf8_str = utf8_str;
-
-       size_t num_chars_converted = iconv(cd_utf16_to_utf8, (char**)&utf16_str,
-                       &utf16_bytes_left, &utf8_str, &utf8_bytes_left);
-
-       if (num_chars_converted == (size_t)(-1)) {
-               ERROR_WITH_ERRNO("Failed to convert UTF-16LE string to UTF-8 "
-                                "string");
-               FREE(orig_utf8_str);
-               return NULL;
-       }
-
-       size_t utf8_len = utf16_len - utf8_bytes_left;
-
-       *utf8_len_ret = utf8_len;
-       orig_utf8_str[utf8_len] = '\0';
-       return orig_utf8_str;
-}
-
-static iconv_t cd_utf8_to_utf16 = (iconv_t)(-1);
-
-/* Converts a string in the UTF-8 encoding to a newly allocated string in the
- * UTF-16 encoding.  */
-char *utf8_to_utf16(const char *utf8_str, size_t utf8_len,
-                   size_t *utf16_len_ret)
-{
-       if (cd_utf8_to_utf16 == (iconv_t)(-1)) {
-               cd_utf8_to_utf16 = iconv_open("UTF-16LE", "UTF-8");
-               if (cd_utf8_to_utf16 == (iconv_t)-1) {
-                       ERROR_WITH_ERRNO("Failed to get conversion descriptor "
-                                        "for converting UTF-8 to UTF-16LE");
-                       return NULL;
-               }
-       }
-
-       size_t utf8_bytes_left   = utf8_len;
-       size_t utf16_capacity    = utf8_len * 4;
-       size_t utf16_bytes_left  = utf16_capacity;
-
-       char *utf16_str = MALLOC(utf16_capacity + 2);
-       if (!utf16_str)
-               return NULL;
-
-       char *orig_utf16_str = utf16_str;
-
-       size_t num_chars_converted = iconv(cd_utf8_to_utf16, (char**)&utf8_str,
-                       &utf8_bytes_left, &utf16_str, &utf16_bytes_left);
-
-       if (num_chars_converted == (size_t)(-1)) {
-               ERROR_WITH_ERRNO("Failed to convert UTF-8 string to UTF-16LE "
-                                "string");
-               FREE(orig_utf16_str);
-               return NULL;
-       }
-
-       size_t utf16_len = utf16_capacity - utf16_bytes_left;
-
-       *utf16_len_ret = utf16_len;
-       orig_utf16_str[utf16_len] = '\0';
-       orig_utf16_str[utf16_len + 1] = '\0';
-       return orig_utf16_str;
-}
-
 static bool seeded = false;
 
 static void seed_random()