wimlib: Allow custom error file
authorEric Biggers <ebiggers3@gmail.com>
Wed, 25 Jun 2014 02:12:44 +0000 (21:12 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Wed, 25 Jun 2014 02:12:44 +0000 (21:12 -0500)
NEWS
include/wimlib.h
include/wimlib/error.h
src/inode.c
src/ntfs-3g_apply.c
src/util.c
src/wim.c
src/wimboot.c

diff --git a/NEWS b/NEWS
index 74052dc..82aef67 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,9 @@ Version 1.7.1-BETA:
        Added experimental new write flag:
        WIMLIB_WRITE_FLAG_SEND_DONE_WITH_FILE_MESSAGES.
 
+       Library users can now specify a custom file for warning and error
+       messages to be sent to, rather than the default of standard error.
+
 Version 1.7.0:
        Improved compression, decompression, and extraction performance.
 
index 9c043c1..56b6c89 100644 (file)
@@ -3662,6 +3662,39 @@ wimlib_resolve_image(WIMStruct *wim,
                     const wimlib_tchar *image_name_or_num);
 
 /**
+ * Sets the file to which the library will print error and warning messages.
+ *
+ * This version of the function takes a C library <c>FILE *</c> opened for
+ * writing (or appending).  Use wimlib_set_error_file_by_name() to specify the
+ * file by name instead.
+ *
+ * This also enables error messages, as if by a call to
+ * wimlib_set_print_errors(true).
+ *
+ * @return 0 on success; nonzero on error.
+ * @retval ::WIMLIB_ERR_UNSUPPORTED
+ *     wimlib was compiled using the <c>--without-error-messages</c> option.
+ */
+extern int
+wimlib_set_error_file(FILE *fp);
+
+/**
+ * Sets the path to the file to which the library will print error and warning
+ * messages.  The library will open this file for appending.
+ *
+ * This also enables error messages, as if by a call to
+ * wimlib_set_print_errors(true).
+ *
+ * @return 0 on success; nonzero on error.
+ * @retval ::WIMLIB_ERR_OPEN
+ *     The file named by @p path could not be opened for appending.
+ * @retval ::WIMLIB_ERR_UNSUPPORTED
+ *     wimlib was compiled using the <c>--without-error-messages</c> option.
+ */
+extern int
+wimlib_set_error_file_by_name(const char *path);
+
+/**
  * @ingroup G_modifying_wims
  *
  * Changes the description of an image in the WIM.
index a36f802..9657eda 100644 (file)
@@ -34,8 +34,10 @@ wimlib_warning_with_errno(const tchar *format, ...)
 #  define WARNING(format, ...)                 wimlib_warning(T(format), ## __VA_ARGS__)
 #  define WARNING_WITH_ERRNO(format, ...)      wimlib_warning_with_errno(T(format), ## __VA_ARGS__)
 extern bool wimlib_print_errors;
+extern FILE *wimlib_error_file;
 #else /* ENABLE_ERROR_MESSAGES */
 #  define wimlib_print_errors 0
+#  define wimlib_error_file NULL
 #  define ERROR(format, ...)                   dummy_tprintf(T(format), ## __VA_ARGS__)
 #  define ERROR_WITH_ERRNO(format, ...)                dummy_tprintf(T(format), ## __VA_ARGS__)
 #  define WARNING(format, ...)                 dummy_tprintf(T(format), ## __VA_ARGS__)
index 42faa19..79adf36 100644 (file)
@@ -547,9 +547,10 @@ stream_not_found_error(const struct wim_inode *inode, const u8 *hash)
 {
        if (wimlib_print_errors) {
                ERROR("\"%"TS"\": stream not found", inode_first_full_path(inode));
-               tfprintf(stderr, T("        SHA-1 message digest of missing stream:\n        "));
-               print_hash(hash, stderr);
-               tputc(T('\n'), stderr);
+               tfprintf(wimlib_error_file,
+                        T("        SHA-1 message digest of missing stream:\n        "));
+               print_hash(hash, wimlib_error_file);
+               tputc(T('\n'), wimlib_error_file);
        }
        return WIMLIB_ERR_RESOURCE_NOT_FOUND;
 }
index 306daa5..d1cebb9 100644 (file)
@@ -401,9 +401,10 @@ ntfs_3g_set_metadata(ntfs_inode *ni, const struct wim_inode *inode,
                                ERROR_WITH_ERRNO("Failed to set security descriptor "
                                                 "on \"%s\" in NTFS volume",
                                                 dentry_full_path(one_dentry));
-                               fprintf(stderr, "The security descriptor is: ");
-                               print_byte_field(desc, desc_size, stderr);
-                               fprintf(stderr, "\n");
+                               fprintf(wimlib_error_file,
+                                       "The security descriptor is: ");
+                               print_byte_field(desc, desc_size, wimlib_error_file);
+                               fprintf(wimlib_error_file, "\n");
                        }
                        return ret;
                }
index 54e2944..86fcb05 100644 (file)
@@ -66,6 +66,7 @@ utf16le_strlen(const utf16lechar *s)
 
 #ifdef ENABLE_ERROR_MESSAGES
 bool wimlib_print_errors = false;
+FILE *wimlib_error_file = NULL; /* Set in wimlib_global_init() */
 #endif
 
 #if defined(ENABLE_ERROR_MESSAGES) || defined(ENABLE_DEBUG)
@@ -79,8 +80,8 @@ wimlib_vmsg(const tchar *tag, const tchar *format,
        {
                int errno_save = errno;
                fflush(stdout);
-               tfputs(tag, stderr);
-               tvfprintf(stderr, format, va);
+               tfputs(tag, wimlib_error_file);
+               tvfprintf(wimlib_error_file, format, va);
                if (perror && errno_save != 0) {
                        tchar buf[64];
                        int res;
@@ -94,10 +95,10 @@ wimlib_vmsg(const tchar *tag, const tchar *format,
                        if (errno_save == EBUSY)
                                tstrcpy(buf, T("Resource busy"));
                #endif
-                       tfprintf(stderr, T(": %"TS), buf);
+                       tfprintf(wimlib_error_file, T(": %"TS), buf);
                }
-               tputc(T('\n'), stderr);
-               fflush(stderr);
+               tputc(T('\n'), wimlib_error_file);
+               fflush(wimlib_error_file);
                errno = errno_save;
        }
 }
@@ -187,6 +188,36 @@ wimlib_set_print_errors(bool show_error_messages)
 #endif
 }
 
+WIMLIBAPI int
+wimlib_set_error_file(FILE *fp)
+{
+#ifdef ENABLE_ERROR_MESSAGES
+       wimlib_error_file = fp;
+       wimlib_print_errors = true;
+       return 0;
+#else
+       return WIMLIB_ERR_UNSUPPORTED;
+#endif
+}
+
+WIMLIBAPI int
+wimlib_set_error_file_by_name(const char *path)
+{
+#ifdef ENABLE_ERROR_MESSAGES
+       FILE *fp;
+
+       fp = fopen(path, "a");
+       if (!fp)
+               return WIMLIB_ERR_OPEN;
+
+       wimlib_error_file = fp;
+       wimlib_print_errors = true;
+       return 0;
+#else
+       return WIMLIB_ERR_UNSUPPORTED;
+#endif
+}
+
 static const tchar *error_strings[] = {
        [WIMLIB_ERR_SUCCESS]
                = T("Success"),
index a3dd135..38d9071 100644 (file)
--- a/src/wim.c
+++ b/src/wim.c
@@ -1020,6 +1020,11 @@ wimlib_global_init(int init_flags)
        if (lib_initialized)
                return 0;
 
+#ifdef ENABLE_ERROR_MESSAGES
+       if (wimlib_error_file == NULL)
+               wimlib_error_file = stderr;
+#endif
+
        if (init_flags & ~(WIMLIB_INIT_FLAG_ASSUME_UTF8 |
                           WIMLIB_INIT_FLAG_DONT_ACQUIRE_PRIVILEGES |
                           WIMLIB_INIT_FLAG_STRICT_CAPTURE_PRIVILEGES |
index 4d52acc..86081df 100644 (file)
@@ -610,8 +610,8 @@ retry:
                if (wimlib_print_errors) {
                        print_byte_field((const u8 *)hdr,
                                         sizeof(struct WimOverlay_dat_header),
-                                        stderr);
-                       fputc('\n', stderr);
+                                        wimlib_error_file);
+                       fputc('\n', wimlib_error_file);
                }
                ret = WIMLIB_ERR_UNSUPPORTED;
                goto out_free_contents;
@@ -681,8 +681,9 @@ retry:
                              path, i, entry_1->data_source_id);
                        if (wimlib_print_errors) {
                                print_byte_field((const u8 *)entry_2->wim_file_name,
-                                                wim_file_name_length, stderr);
-                               fputc('\n', stderr);
+                                                wim_file_name_length,
+                                                wimlib_error_file);
+                               fputc('\n', wimlib_error_file);
                        }
                        ret = WIMLIB_ERR_UNSUPPORTED;
                        goto out_free_contents;
@@ -719,8 +720,8 @@ retry:
                        if (wimlib_print_errors) {
                                print_byte_field((const u8 *)entry_2,
                                                 entry_1->entry_2_length,
-                                                stderr);
-                               fputc('\n', stderr);
+                                                wimlib_error_file);
+                               fputc('\n', wimlib_error_file);
                        }
                        ret = WIMLIB_ERR_UNSUPPORTED;
                        goto out_free_contents;