summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2013-03-03 09:50:44 +0100
committerStef Walter <stefw@gnome.org>2013-03-03 10:07:08 +0100
commitae76545a0094114ef29dba52df97e69ab28b3dbc (patch)
tree8052e7262deeba9962c31a13ec3f041507464678 /common
parent38acf11889c1e1da2610c8e05f1f380f2a2a1ae6 (diff)
Abstract mmap() into a compat API
The Win32 for mmap() is very different from Unix, so abstract this into our own p11_mmap_xxx() functions.
Diffstat (limited to 'common')
-rw-r--r--common/compat.c158
-rw-r--r--common/compat.h16
-rw-r--r--common/tests/frob-cert.c35
3 files changed, 151 insertions, 58 deletions
diff --git a/common/compat.c b/common/compat.c
index 33e608f..af28e1d 100644
--- a/common/compat.c
+++ b/common/compat.c
@@ -175,6 +175,10 @@ basename (const char *name)
#endif /* HAVE_BASENAME */
#ifdef OS_UNIX
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
void
p11_mutex_init (p11_mutex_t *mutex)
@@ -196,6 +200,57 @@ p11_dl_error (void)
return msg ? strdup (msg) : NULL;
}
+struct _p11_mmap {
+ int fd;
+ void *data;
+ size_t size;
+};
+
+p11_mmap *
+p11_mmap_open (const char *path,
+ void **data,
+ size_t *size)
+{
+ struct stat sb;
+ p11_mmap *map;
+
+ map = calloc (1, sizeof (p11_mmap));
+ if (map == NULL)
+ return NULL;
+
+ map->fd = open (path, O_RDONLY);
+ if (map->fd == -1) {
+ free (map);
+ return NULL;
+ }
+
+ if (fstat (map->fd, &sb) < 0) {
+ close (map->fd);
+ free (map);
+ return NULL;
+ }
+
+ map->size = sb.st_size;
+ map->data = mmap (NULL, map->size, PROT_READ, MAP_PRIVATE, map->fd, 0);
+ if (data == NULL) {
+ close (map->fd);
+ free (map);
+ return NULL;
+ }
+
+ *data = map->data;
+ *size = map->size;
+ return map;
+}
+
+void
+p11_mmap_close (p11_mmap *map)
+{
+ munmap (map->data, map->size);
+ close (map->fd);
+ free (map);
+}
+
#endif /* OS_UNIX */
#ifdef OS_WIN32
@@ -246,43 +301,78 @@ p11_thread_join (p11_thread_t thread)
return 0;
}
-#endif /* OS_WIN32 */
+struct _p11_mmap {
+ HANDLE file;
+ HANDLE mapping;
+ void *data;
+};
-#ifndef HAVE_STRNSTR
+p11_mmap *
+p11_mmap_open (const char *path,
+ void **data,
+ size_t *size)
+{
+ HANDLE mapping;
+ LARGE_INTEGER large;
+ DWORD errn;
+ p11_mmap *map;
-/*-
- * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
+ map = calloc (1, sizeof (p11_mmap));
+ if (map == NULL)
+ return NULL;
+
+ map->file = CreateFile (path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
+ if (map->file == INVALID_HANDLE_VALUE) {
+ errn = GetLastError ();
+ free (map);
+ SetLastError (errn);
+ return NULL;
+ }
+ if (!GetFileSizeEx (map->file, &large)) {
+ errn = GetLastError ();
+ CloseHandle (map->file);
+ free (map);
+ SetLastError (errn);
+ return NULL;
+ }
+
+ mapping = CreateFileMapping (map->file, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (!mapping) {
+ errn = GetLastError ();
+ CloseHandle (map->file);
+ free (map);
+ SetLastError (errn);
+ return NULL;
+ }
+
+ map->data = MapViewOfFile (mapping, FILE_MAP_READ, 0, 0, large.QuadPart);
+ CloseHandle (mapping);
+
+ if (map->data == NULL) {
+ errn = GetLastError ();
+ CloseHandle (map->file);
+ free (map);
+ SetLastError (errn);
+ return NULL;
+ }
+
+ *data = map->data;
+ *size = large.QuadPart;
+ return map;
+}
+
+void
+p11_mmap_close (p11_mmap *map)
+{
+ UnmapViewOfFile (map->data);
+ CloseHandle (map->file);
+ free (map);
+}
+
+#endif /* OS_WIN32 */
+
+#ifndef HAVE_STRNSTR
#include <string.h>
/*
diff --git a/common/compat.h b/common/compat.h
index 1b74a35..ad80ca5 100644
--- a/common/compat.h
+++ b/common/compat.h
@@ -133,6 +133,14 @@ char * p11_dl_error (void);
#define p11_sleep_ms(ms) \
(Sleep (ms))
+typedef struct _p11_mmap p11_mmap;
+
+p11_mmap * p11_mmap_open (const char *path,
+ void **data,
+ size_t *size);
+
+void p11_mmap_close (p11_mmap *map);
+
#endif /* OS_WIN32 */
/* ----------------------------------------------------------------------------
@@ -186,6 +194,14 @@ char * p11_dl_error (void);
nanosleep (&_ts, NULL); \
} while(0)
+typedef struct _p11_mmap p11_mmap;
+
+p11_mmap * p11_mmap_open (const char *path,
+ void **data,
+ size_t *size);
+
+void p11_mmap_close (p11_mmap *map);
+
#endif /* OS_UNIX */
#ifdef HAVE_ERRNO_H
diff --git a/common/tests/frob-cert.c b/common/tests/frob-cert.c
index f8ad392..71018bd 100644
--- a/common/tests/frob-cert.c
+++ b/common/tests/frob-cert.c
@@ -37,7 +37,6 @@
#include <libtasn1.h>
-#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -86,12 +85,12 @@ main (int argc,
char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = { 0, };
node_asn *definitions = NULL;
node_asn *cert = NULL;
- unsigned char *data;
- struct stat sb;
+ p11_mmap *map;
+ void *data;
+ size_t size;
int start, end;
ssize_t len;
int ret;
- int fd;
if (argc != 4) {
fprintf (stderr, "usage: frob-cert struct field filename\n");
@@ -107,38 +106,26 @@ main (int argc,
ret = asn1_create_element (definitions, argv[1], &cert);
err_if_fail (ret, "Certificate");
- fd = open (argv[3], O_RDONLY);
- if (fd == -1) {
+ map = p11_mmap_open (argv[3], &data, &size);
+ if (map == NULL) {
fprintf (stderr, "couldn't open file: %s\n", argv[3]);
return 1;
}
- if (fstat (fd, &sb) < 0) {
- fprintf (stderr, "couldn't stat file: %s\n", argv[3]);
- return 1;
- }
-
- data = mmap (NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- if (data == NULL) {
- fprintf (stderr, "couldn't map file: %s\n", argv[3]);
- return 1;
- }
-
- ret = asn1_der_decoding (&cert, data, sb.st_size, message);
+ ret = asn1_der_decoding (&cert, data, size, message);
err_if_fail (ret, message);
- ret = asn1_der_decoding_startEnd (cert, data, sb.st_size, argv[2], &start, &end);
+ ret = asn1_der_decoding_startEnd (cert, data, size, argv[2], &start, &end);
err_if_fail (ret, "asn1_der_decoding_startEnd");
- len = tlv_length (data + start, sb.st_size - start);
+ len = tlv_length ((unsigned char *)data + start, size - start);
assert (len >= 0);
- fprintf (stderr, "%lu %d %d %ld\n", sb.st_size, start, end, len);
- fwrite (data + start, 1, len, stdout);
+ fprintf (stderr, "%lu %d %d %ld\n", (unsigned long)size, start, end, (long)len);
+ fwrite ((unsigned char *)data + start, 1, len, stdout);
fflush (stdout);
- munmap (data, sb.st_size);
- close (fd);
+ p11_mmap_close (map);
asn1_delete_structure (&cert);
asn1_delete_structure (&definitions);