X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Futil.c;h=3bb78efb6a553036905b40d418885f5d1a6d9e2a;hp=1addc857a5675ca0cc8f5ed8b4c1c230712ac637;hb=ce4af1bc0291503cae1b053d53efbc4123c50be5;hpb=edf0f7f5331e626b55819dcafa88e202cdb82a32 diff --git a/src/util.c b/src/util.c index 1addc857..3bb78efb 100644 --- a/src/util.c +++ b/src/util.c @@ -37,6 +37,7 @@ #endif #include "wimlib.h" +#include "wimlib/assert.h" #include "wimlib/compiler.h" #include "wimlib/encoding.h" #include "wimlib/error.h" @@ -65,6 +66,8 @@ utf16le_strlen(const utf16lechar *s) #ifdef ENABLE_ERROR_MESSAGES bool wimlib_print_errors = false; +FILE *wimlib_error_file = NULL; /* Set in wimlib_global_init() */ +static bool wimlib_owns_error_file = false; #endif #if defined(ENABLE_ERROR_MESSAGES) || defined(ENABLE_DEBUG) @@ -78,8 +81,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; @@ -93,10 +96,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; } } @@ -186,6 +189,38 @@ wimlib_set_print_errors(bool show_error_messages) #endif } +WIMLIBAPI int +wimlib_set_error_file(FILE *fp) +{ +#ifdef ENABLE_ERROR_MESSAGES + if (wimlib_owns_error_file) + fclose(wimlib_error_file); + wimlib_error_file = fp; + wimlib_print_errors = (fp != NULL); + wimlib_owns_error_file = false; + 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_set_error_file(fp); + wimlib_owns_error_file = true; + return 0; +#else + return WIMLIB_ERR_UNSUPPORTED; +#endif +} + static const tchar *error_strings[] = { [WIMLIB_ERR_SUCCESS] = T("Success"), @@ -193,17 +228,8 @@ static const tchar *error_strings[] = { = T("The WIM is already locked for writing"), [WIMLIB_ERR_DECOMPRESSION] = T("Failed to decompress compressed data"), - [WIMLIB_ERR_DELETE_STAGING_DIR] - = T("Failed to delete staging directory"), - [WIMLIB_ERR_FILESYSTEM_DAEMON_CRASHED] - = T("The process servicing the mounted WIM has crashed"), - [WIMLIB_ERR_FORK] - = T("Failed to fork another process"), [WIMLIB_ERR_FUSE] = T("An error was returned by fuse_main()"), - [WIMLIB_ERR_FUSERMOUNT] - = T("Could not execute the `fusermount' program, or it exited " - "with a failure status"), [WIMLIB_ERR_GLOB_HAD_NO_MATCHES] = T("The provided file glob did not match any files"), [WIMLIB_ERR_ICONV_NOT_AVAILABLE] @@ -232,6 +258,8 @@ static const tchar *error_strings[] = { = T("The WIM's integrity table is invalid"), [WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY] = T("An entry in the WIM's lookup table is invalid"), + [WIMLIB_ERR_INVALID_METADATA_RESOURCE] + = T("The metadata resource is invalid"), [WIMLIB_ERR_INVALID_MULTIBYTE_STRING] = T("A string was not valid in the current locale's character encoding"), [WIMLIB_ERR_INVALID_OVERLAY] @@ -246,11 +274,6 @@ static const tchar *error_strings[] = { = T("The reparse data of a reparse point was invalid"), [WIMLIB_ERR_INVALID_RESOURCE_HASH] = T("The SHA1 message digest of a WIM resource did not match the expected value"), - [WIMLIB_ERR_INVALID_METADATA_RESOURCE] - = T("The metadata resource is invalid"), - [WIMLIB_ERR_INVALID_UNMOUNT_MESSAGE] - = T("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] = T("A string provided as input by the user was not a valid UTF-8 string"), [WIMLIB_ERR_INVALID_UTF16_STRING] @@ -277,12 +300,12 @@ static const tchar *error_strings[] = { = T("Expected a directory"), [WIMLIB_ERR_NOTEMPTY] = T("Directory was not empty"), - [WIMLIB_ERR_NOT_A_WIM_FILE] - = T("The file did not begin with the magic characters that " - "identify a WIM file"), [WIMLIB_ERR_NOT_A_REGULAR_FILE] = T("One of the specified paths to extract did not " "correspond to a regular file"), + [WIMLIB_ERR_NOT_A_WIM_FILE] + = T("The file did not begin with the magic characters that " + "identify a WIM file"), [WIMLIB_ERR_NO_FILENAME] = T("The WIM is not identified with a filename"), [WIMLIB_ERR_NOT_PIPABLE] @@ -322,8 +345,6 @@ static const tchar *error_strings[] = { = T("The WIM is part of an invalid split WIM"), [WIMLIB_ERR_STAT] = T("Could not read the metadata for a file or directory"), - [WIMLIB_ERR_TIMEOUT] - = T("Timed out while waiting for a message to arrive from another process"), [WIMLIB_ERR_UNEXPECTED_END_OF_FILE] = T("Unexpectedly reached the end of the file"), [WIMLIB_ERR_UNICODE_STRING_NOT_REPRESENTABLE] @@ -334,8 +355,6 @@ static const tchar *error_strings[] = { = T("The requested operation is unsupported"), [WIMLIB_ERR_UNSUPPORTED_FILE] = T("A file in the directory tree to archive was not of a supported type"), - [WIMLIB_ERR_VOLUME_LACKS_FEATURES] - = T("The volume did not support a feature necessary to complete the operation"), [WIMLIB_ERR_WIM_IS_READONLY] = T("The WIM is read-only (file permissions, header flag, or split WIM)"), [WIMLIB_ERR_WRITE] @@ -346,6 +365,18 @@ static const tchar *error_strings[] = { = T("The WIM file (or parts of it) is encrypted"), [WIMLIB_ERR_WIMBOOT] = T("Failed to set WIMBoot pointer data"), + [WIMLIB_ERR_ABORTED_BY_PROGRESS] + = T("The operation was aborted by the library user"), + [WIMLIB_ERR_UNKNOWN_PROGRESS_STATUS] + = T("The user-provided progress function returned an unrecognized value"), + [WIMLIB_ERR_MKNOD] + = T("Unable to create a special file (e.g. device node or socket)"), + [WIMLIB_ERR_MOUNTED_IMAGE_IS_BUSY] + = T("There are still files open on the mounted WIM image"), + [WIMLIB_ERR_NOT_A_MOUNTPOINT] + = T("There is not a WIM image mounted on the directory"), + [WIMLIB_ERR_NOT_PERMITTED_TO_UNMOUNT] + = T("The current user does not have permission to unmount the WIM image"), }; /* API function documented in wimlib.h */ @@ -436,6 +467,36 @@ wimlib_wcsdup(const wchar_t *str) } #endif +void * +wimlib_aligned_malloc(size_t size, size_t alignment) +{ + u8 *raw_ptr; + u8 *ptr; + uintptr_t mask; + + wimlib_assert(alignment != 0 && is_power_of_2(alignment) && + alignment <= 4096); + mask = alignment - 1; + + raw_ptr = MALLOC(size + alignment - 1 + sizeof(size_t)); + if (!raw_ptr) + return NULL; + + ptr = (u8 *)raw_ptr + sizeof(size_t); + while ((uintptr_t)ptr & mask) + ptr++; + *((size_t *)ptr - 1) = (ptr - raw_ptr); + + return ptr; +} + +void +wimlib_aligned_free(void *ptr) +{ + if (ptr) + FREE((u8 *)ptr - *((size_t *)ptr - 1)); +} + void * memdup(const void *mem, size_t size) {