From e61f93d517a76c23a3bfc2fdbd32fa190fbbc286 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 24 Jun 2014 21:12:44 -0500 Subject: [PATCH] wimlib: Allow custom error file --- NEWS | 3 +++ include/wimlib.h | 33 +++++++++++++++++++++++++++++++++ include/wimlib/error.h | 2 ++ src/inode.c | 7 ++++--- src/ntfs-3g_apply.c | 7 ++++--- src/util.c | 41 ++++++++++++++++++++++++++++++++++++----- src/wim.c | 5 +++++ src/wimboot.c | 13 +++++++------ 8 files changed, 94 insertions(+), 17 deletions(-) diff --git a/NEWS b/NEWS index 74052dc3..82aef677 100644 --- 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. diff --git a/include/wimlib.h b/include/wimlib.h index 9c043c1b..56b6c893 100644 --- a/include/wimlib.h +++ b/include/wimlib.h @@ -3661,6 +3661,39 @@ extern int 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 FILE * 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 --without-error-messages 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 --without-error-messages option. + */ +extern int +wimlib_set_error_file_by_name(const char *path); + /** * @ingroup G_modifying_wims * diff --git a/include/wimlib/error.h b/include/wimlib/error.h index a36f8028..9657eda8 100644 --- a/include/wimlib/error.h +++ b/include/wimlib/error.h @@ -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__) diff --git a/src/inode.c b/src/inode.c index 42faa194..79adf365 100644 --- a/src/inode.c +++ b/src/inode.c @@ -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; } diff --git a/src/ntfs-3g_apply.c b/src/ntfs-3g_apply.c index 306daa5b..d1cebb9c 100644 --- a/src/ntfs-3g_apply.c +++ b/src/ntfs-3g_apply.c @@ -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; } diff --git a/src/util.c b/src/util.c index 54e29444..86fcb059 100644 --- a/src/util.c +++ b/src/util.c @@ -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"), diff --git a/src/wim.c b/src/wim.c index a3dd135c..38d90718 100644 --- 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 | diff --git a/src/wimboot.c b/src/wimboot.c index 4d52accc..86081dfc 100644 --- a/src/wimboot.c +++ b/src/wimboot.c @@ -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; -- 2.43.0