diff options
author | Brad King <brad.king@kitware.com> | 2013-07-26 20:08:54 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2013-07-31 12:19:13 (GMT) |
commit | 102071f80cf4ad7aa97bf8a1618cfc6ee6689ab6 (patch) | |
tree | db05ed527f04506957049a7b087be6c038d98435 /Utilities/cmlibarchive/libarchive/archive_write_open_filename.c | |
parent | 87402c995ed2460deb2f39e02acf77a0bb57f263 (diff) | |
parent | 35df7c8ba8854e97bd6994c4d1143f57535ed6f2 (diff) | |
download | CMake-102071f80cf4ad7aa97bf8a1618cfc6ee6689ab6.zip CMake-102071f80cf4ad7aa97bf8a1618cfc6ee6689ab6.tar.gz CMake-102071f80cf4ad7aa97bf8a1618cfc6ee6689ab6.tar.bz2 |
Merge branch 'libarchive-upstream' into update-libarchive
Conflicts:
Utilities/cmlibarchive/CMakeLists.txt
Utilities/cmlibarchive/libarchive/archive.h
Utilities/cmlibarchive/libarchive/archive_entry.h
Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
Utilities/cmlibarchive/libarchive/archive_windows.h
Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
Diffstat (limited to 'Utilities/cmlibarchive/libarchive/archive_write_open_filename.c')
-rw-r--r-- | Utilities/cmlibarchive/libarchive/archive_write_open_filename.c | 170 |
1 files changed, 86 insertions, 84 deletions
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c b/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c index 8689866..196b770 100644 --- a/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c +++ b/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c @@ -46,24 +46,25 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_open_filename.c 191165 200 #endif #include "archive.h" +#include "archive_private.h" #include "archive_string.h" #ifndef O_BINARY #define O_BINARY 0 #endif +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif struct write_file_data { int fd; - char mbs_filename; - union { - char m[1]; - wchar_t w[1]; - } filename; /* Must be last! */ + struct archive_mstring filename; }; static int file_close(struct archive *, void *); static int file_open(struct archive *, void *); static ssize_t file_write(struct archive *, void *, const void *buff, size_t); +static int open_filename(struct archive *, int, const void *); int archive_write_open_file(struct archive *a, const char *filename) @@ -74,123 +75,122 @@ archive_write_open_file(struct archive *a, const char *filename) int archive_write_open_filename(struct archive *a, const char *filename) { - struct write_file_data *mine; if (filename == NULL || filename[0] == '\0') return (archive_write_open_fd(a, 1)); - mine = (struct write_file_data *)malloc(sizeof(*mine) + strlen(filename)); - if (mine == NULL) { - archive_set_error(a, ENOMEM, "No memory"); - return (ARCHIVE_FATAL); - } - strcpy(mine->filename.m, filename); - mine->mbs_filename = 1; - mine->fd = -1; - return (archive_write_open(a, mine, - file_open, file_write, file_close)); + return (open_filename(a, 1, filename)); } int archive_write_open_filename_w(struct archive *a, const wchar_t *filename) { -#if defined(_WIN32) && !defined(__CYGWIN__) - struct write_file_data *mine; if (filename == NULL || filename[0] == L'\0') return (archive_write_open_fd(a, 1)); - mine = malloc(sizeof(*mine) + wcslen(filename) * sizeof(wchar_t)); + return (open_filename(a, 0, filename)); +} + +static int +open_filename(struct archive *a, int mbs_fn, const void *filename) +{ + struct write_file_data *mine; + int r; + + mine = (struct write_file_data *)calloc(1, sizeof(*mine)); if (mine == NULL) { archive_set_error(a, ENOMEM, "No memory"); return (ARCHIVE_FATAL); } - wcscpy(mine->filename.w, filename); - mine->mbs_filename = 0; + if (mbs_fn) + r = archive_mstring_copy_mbs(&mine->filename, filename); + else + r = archive_mstring_copy_wcs(&mine->filename, filename); + if (r < 0) { + if (errno == ENOMEM) { + archive_set_error(a, ENOMEM, "No memory"); + return (ARCHIVE_FATAL); + } + if (mbs_fn) + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "Can't convert '%s' to WCS", + (const char *)filename); + else + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "Can't convert '%S' to MBS", + (const wchar_t *)filename); + return (ARCHIVE_FAILED); + } mine->fd = -1; return (archive_write_open(a, mine, file_open, file_write, file_close)); -#else - /* - * POSIX system does not support a wchar_t interface for - * open() system call, so we have to translate a wchar_t - * filename to multi-byte one and use it. - */ - struct archive_string fn; - int r; - - if (filename == NULL || filename[0] == L'\0') - return (archive_write_open_fd(a, 1)); - - archive_string_init(&fn); - if (archive_string_append_from_wcs(&fn, filename, - wcslen(filename)) != 0) { - archive_set_error(a, EINVAL, - "Failed to convert a wide-character filename to" - " a multi-byte filename"); - archive_string_free(&fn); - return (ARCHIVE_FATAL); - } - r = archive_write_open_filename(a, fn.s); - archive_string_free(&fn); - return (r); -#endif } - static int file_open(struct archive *a, void *client_data) { int flags; struct write_file_data *mine; struct stat st; +#if defined(_WIN32) && !defined(__CYGWIN__) + wchar_t *fullpath; +#endif + const wchar_t *wcs; + const char *mbs; mine = (struct write_file_data *)client_data; - flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; + flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC; /* * Open the file. */ - if (mine->mbs_filename) { - mine->fd = open(mine->filename.m, flags, 0666); - if (mine->fd < 0) { - archive_set_error(a, errno, "Failed to open '%s'", - mine->filename.m); - return (ARCHIVE_FATAL); - } - - if (fstat(mine->fd, &st) != 0) { - archive_set_error(a, errno, "Couldn't stat '%s'", - mine->filename.m); - return (ARCHIVE_FATAL); - } - } else { + mbs = NULL; wcs = NULL; #if defined(_WIN32) && !defined(__CYGWIN__) - mine->fd = _wopen(mine->filename.w, flags, 0666); - if (mine->fd < 0 && errno == ENOENT) { - wchar_t *fullpath; - fullpath = __la_win_permissive_name_w(mine->filename.w); - if (fullpath != NULL) { - mine->fd = _wopen(fullpath, flags, 0666); - free(fullpath); - } - } - if (mine->fd < 0) { - archive_set_error(a, errno, "Failed to open '%S'", - mine->filename.w); - return (ARCHIVE_FATAL); - } - - if (fstat(mine->fd, &st) != 0) { - archive_set_error(a, errno, "Couldn't stat '%S'", - mine->filename.w); - return (ARCHIVE_FATAL); + if (archive_mstring_get_wcs(a, &mine->filename, &wcs) != 0) { + if (errno == ENOMEM) + archive_set_error(a, errno, "No memory"); + else { + archive_mstring_get_mbs(a, &mine->filename, &mbs); + archive_set_error(a, errno, + "Can't convert '%s' to WCS", mbs); } + return (ARCHIVE_FATAL); + } + fullpath = __la_win_permissive_name_w(wcs); + if (fullpath != NULL) { + mine->fd = _wopen(fullpath, flags, 0666); + free(fullpath); + } else + mine->fd = _wopen(wcs, flags, 0666); #else - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unexpedted operation in archive_write_open_filename"); + if (archive_mstring_get_mbs(a, &mine->filename, &mbs) != 0) { + if (errno == ENOMEM) + archive_set_error(a, errno, "No memory"); + else { + archive_mstring_get_wcs(a, &mine->filename, &wcs); + archive_set_error(a, errno, + "Can't convert '%S' to MBS", wcs); + } return (ARCHIVE_FATAL); + } + mine->fd = open(mbs, flags, 0666); + __archive_ensure_cloexec_flag(mine->fd); #endif + if (mine->fd < 0) { + if (mbs != NULL) + archive_set_error(a, errno, "Failed to open '%s'", mbs); + else + archive_set_error(a, errno, "Failed to open '%S'", wcs); + return (ARCHIVE_FATAL); + } + + if (fstat(mine->fd, &st) != 0) { + if (mbs != NULL) + archive_set_error(a, errno, "Couldn't stat '%s'", mbs); + else + archive_set_error(a, errno, "Couldn't stat '%S'", wcs); + return (ARCHIVE_FATAL); } /* @@ -218,7 +218,8 @@ file_open(struct archive *a, void *client_data) } static ssize_t -file_write(struct archive *a, void *client_data, const void *buff, size_t length) +file_write(struct archive *a, void *client_data, const void *buff, + size_t length) { struct write_file_data *mine; ssize_t bytesWritten; @@ -243,6 +244,7 @@ file_close(struct archive *a, void *client_data) (void)a; /* UNUSED */ close(mine->fd); + archive_mstring_clean(&mine->filename); free(mine); return (ARCHIVE_OK); } |