diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/compat.c | 39 | ||||
-rw-r--r-- | common/compat.h | 3 | ||||
-rw-r--r-- | common/test.c | 2 |
3 files changed, 32 insertions, 12 deletions
diff --git a/common/compat.c b/common/compat.c index d813236..9aa556a 100644 --- a/common/compat.c +++ b/common/compat.c @@ -182,10 +182,11 @@ struct _p11_mmap { p11_mmap * p11_mmap_open (const char *path, + struct stat *sb, void **data, size_t *size) { - struct stat sb; + struct stat stb; p11_mmap *map; map = calloc (1, sizeof (p11_mmap)); @@ -198,13 +199,24 @@ p11_mmap_open (const char *path, return NULL; } - if (fstat (map->fd, &sb) < 0) { + if (sb == NULL) { + sb = &stb; + if (fstat (map->fd, &stb) < 0) { + close (map->fd); + free (map); + return NULL; + } + } + + /* Workaround for broken ZFS on Linux */ + if (S_ISDIR (sb->st_mode)) { + errno = EISDIR; close (map->fd); free (map); return NULL; } - map->size = sb.st_size; + map->size = sb->st_size; map->data = mmap (NULL, map->size, PROT_READ, MAP_PRIVATE, map->fd, 0); if (map->data == NULL) { close (map->fd); @@ -289,6 +301,7 @@ struct _p11_mmap { p11_mmap * p11_mmap_open (const char *path, + struct stat *sb, void **data, size_t *size) { @@ -315,14 +328,18 @@ p11_mmap_open (const char *path, return NULL; } - if (!GetFileSizeEx (map->file, &large)) { - errn = GetLastError (); - CloseHandle (map->file); - free (map); - SetLastError (errn); - if (errn == ERROR_ACCESS_DENIED) - errno = EPERM; - return NULL; + if (sb == NULL) { + if (!GetFileSizeEx (map->file, &large)) { + errn = GetLastError (); + CloseHandle (map->file); + free (map); + SetLastError (errn); + if (errn == ERROR_ACCESS_DENIED) + errno = EPERM; + return NULL; + } + } else { + large.QuadPart = sb->st_size; } mapping = CreateFileMapping (map->file, NULL, PAGE_READONLY, 0, 0, NULL); diff --git a/common/compat.h b/common/compat.h index b593cf6..d7fe414 100644 --- a/common/compat.h +++ b/common/compat.h @@ -38,6 +38,7 @@ #include "config.h" #include <sys/types.h> +#include <sys/stat.h> #ifdef _GNU_SOURCE #error Make the crap stop. _GNU_SOURCE is completely unportable and breaks all sorts of behavior @@ -158,6 +159,7 @@ void p11_dl_close (void * dl); typedef struct _p11_mmap p11_mmap; p11_mmap * p11_mmap_open (const char *path, + struct stat *sb, void **data, size_t *size); @@ -220,6 +222,7 @@ char * p11_dl_error (void); typedef struct _p11_mmap p11_mmap; p11_mmap * p11_mmap_open (const char *path, + struct stat *sb, void **data, size_t *size); diff --git a/common/test.c b/common/test.c index daee663..83e9644 100644 --- a/common/test.c +++ b/common/test.c @@ -350,7 +350,7 @@ copy_file (const char *input, ssize_t written; size_t size; - mmap = p11_mmap_open (input, (void **)&data, &size); + mmap = p11_mmap_open (input, NULL, (void **)&data, &size); assert (mmap != NULL); while (size > 0) { |