*/
/*
- * Copyright (C) 2012, 2013 Biggers
+ * Copyright (C) 2012, 2013 Eric Biggers
*
* This file is part of wimlib, a library for working with WIM files.
*
#if defined(HAVE_SYS_FILE_H) && defined(HAVE_FLOCK)
/* On BSD, this should be included before "list.h" so that "list.h" can
* overwrite the LIST_HEAD macro. */
-#include <sys/file.h>
+# include <sys/file.h>
+#endif
+
+#ifdef __WIN32__
+# include <win32.h>
#endif
#include "list.h"
#include "xpress.h"
#ifdef ENABLE_MULTITHREADED_COMPRESSION
-#include <pthread.h>
+# include <pthread.h>
#endif
#include <unistd.h>
#include <errno.h>
#ifdef WITH_NTFS_3G
-#include <time.h>
-#include <ntfs-3g/attrib.h>
-#include <ntfs-3g/inode.h>
-#include <ntfs-3g/dir.h>
+# include <time.h>
+# include <ntfs-3g/attrib.h>
+# include <ntfs-3g/inode.h>
+# include <ntfs-3g/dir.h>
#endif
#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
+# include <alloca.h>
#else
-#include <stdlib.h>
+# include <stdlib.h>
#endif
+#include <limits.h>
+
static int fflush_and_ftruncate(FILE *fp, off_t size)
{
int ret;
#endif
)
{
- if (lte->resource_location == RESOURCE_IN_FILE_ON_DISK
- && !lte->file_on_disk_fp)
- {
- wimlib_assert(lte->file_on_disk);
- lte->file_on_disk_fp = fopen(lte->file_on_disk, "rb");
+ switch (lte->resource_location) {
+ case RESOURCE_IN_FILE_ON_DISK:
if (!lte->file_on_disk_fp) {
- ERROR_WITH_ERRNO("Failed to open the file `%s' for "
- "reading", lte->file_on_disk);
- return WIMLIB_ERR_OPEN;
+ lte->file_on_disk_fp = fopen(lte->file_on_disk, "rb");
+ if (!lte->file_on_disk_fp) {
+ ERROR_WITH_ERRNO("Failed to open the file "
+ "`%s'", lte->file_on_disk);
+ return WIMLIB_ERR_OPEN;
+ }
}
- }
+ break;
#ifdef WITH_NTFS_3G
- else if (lte->resource_location == RESOURCE_IN_NTFS_VOLUME
- && !lte->attr)
- {
- struct ntfs_location *loc = lte->ntfs_loc;
- ntfs_inode *ni;
- wimlib_assert(loc);
- ni = ntfs_pathname_to_inode(*loc->ntfs_vol_p, NULL, loc->path_utf8);
- if (!ni) {
- ERROR_WITH_ERRNO("Failed to open inode `%s' in NTFS "
- "volume", loc->path_utf8);
- return WIMLIB_ERR_NTFS_3G;
- }
- lte->attr = ntfs_attr_open(ni,
- loc->is_reparse_point ? AT_REPARSE_POINT : AT_DATA,
- (ntfschar*)loc->stream_name_utf16,
- loc->stream_name_utf16_num_chars);
+ case RESOURCE_IN_NTFS_VOLUME:
if (!lte->attr) {
- ERROR_WITH_ERRNO("Failed to open attribute of `%s' in "
- "NTFS volume", loc->path_utf8);
- ntfs_inode_close(ni);
- return WIMLIB_ERR_NTFS_3G;
+ struct ntfs_location *loc = lte->ntfs_loc;
+ ntfs_inode *ni;
+ wimlib_assert(loc);
+ ni = ntfs_pathname_to_inode(*loc->ntfs_vol_p, NULL, loc->path_utf8);
+ if (!ni) {
+ ERROR_WITH_ERRNO("Failed to open inode `%s' in NTFS "
+ "volume", loc->path_utf8);
+ return WIMLIB_ERR_NTFS_3G;
+ }
+ lte->attr = ntfs_attr_open(ni,
+ loc->is_reparse_point ? AT_REPARSE_POINT : AT_DATA,
+ (ntfschar*)loc->stream_name_utf16,
+ loc->stream_name_utf16_num_chars);
+ if (!lte->attr) {
+ ERROR_WITH_ERRNO("Failed to open attribute of `%s' in "
+ "NTFS volume", loc->path_utf8);
+ ntfs_inode_close(ni);
+ return WIMLIB_ERR_NTFS_3G;
+ }
+ *ni_ret = ni;
}
- *ni_ret = ni;
- }
+ break;
#endif
+#ifdef __WIN32__
+ case RESOURCE_WIN32:
+ if (!lte->file_on_disk_fp) {
+ lte->file_on_disk_fp = win32_open_file_readonly(lte->file_on_disk);
+ if (!lte->file_on_disk_fp)
+ return WIMLIB_ERR_OPEN;
+ }
+ break;
+#endif
+ default:
+ break;
+ }
return 0;
}
)
{
if (lte->resource_location == RESOURCE_IN_FILE_ON_DISK
- && lte->file_on_disk_fp) {
+ && lte->file_on_disk_fp)
+ {
fclose(lte->file_on_disk_fp);
lte->file_on_disk_fp = NULL;
}
ntfs_inode_close(ni);
}
#endif
+#ifdef __WIN32__
+ else if (lte->resource_location == RESOURCE_WIN32
+ && lte->file_on_disk_fp)
+ {
+ win32_close_file(lte->file_on_disk_fp);
+ lte->file_on_disk_fp = NULL;
+ }
+#endif
}
static int
for (size_t j = 0; j < MAX_CHUNKS_PER_MSG; j++) {
msgs[i].compressed_chunks[j] = MALLOC(WIM_CHUNK_SIZE);
- // The extra 8 bytes is because longest_match() in lz.c
- // may read a little bit off the end of the uncompressed
- // data. It doesn't need to be initialized--- we really
- // just need to avoid accessing an unmapped page.
+ // The extra 8 bytes is because longest_match() in
+ // lz77.c may read a little bit off the end of the
+ // uncompressed data. It doesn't need to be
+ // initialized--- we really just need to avoid accessing
+ // an unmapped page.
msgs[i].uncompressed_chunks[j] = MALLOC(WIM_CHUNK_SIZE + 8);
if (msgs[i].compressed_chunks[j] == NULL ||
msgs[i].uncompressed_chunks[j] == NULL)
return ret;
}
+static long get_default_num_threads()
+{
+#ifdef __WIN32__
+ return win32_get_number_of_processors();
+#else
+ return sysconf(_SC_NPROCESSORS_ONLN);
+#endif
+}
static int write_stream_list_parallel(struct list_head *stream_list,
FILE *out_fp,
pthread_t *compressor_threads = NULL;
if (num_threads == 0) {
- long nthreads = sysconf(_SC_NPROCESSORS_ONLN);
- if (nthreads < 1) {
+ long nthreads = get_default_num_threads();
+ if (nthreads < 1 || nthreads > UINT_MAX) {
WARNING("Could not determine number of processors! Assuming 1");
goto out_serial;
} else {
ret = finish_write(w, image, write_flags, progress_func);
out:
close_wim_writable(w);
+ DEBUG("wimlib_write(path=%s) = %d", path, ret);
return ret;
}