summaryrefslogtreecommitdiff
path: root/ot_iovec.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_iovec.c')
-rw-r--r--ot_iovec.c57
1 files changed, 29 insertions, 28 deletions
diff --git a/ot_iovec.c b/ot_iovec.c
index ec0bd12..c50003c 100644
--- a/ot_iovec.c
+++ b/ot_iovec.c
@@ -16,56 +16,57 @@
16#include "ot_iovec.h" 16#include "ot_iovec.h"
17 17
18void *iovec_increase( int *iovec_entries, struct iovec **iovector, size_t new_alloc ) { 18void *iovec_increase( int *iovec_entries, struct iovec **iovector, size_t new_alloc ) {
19 void *new_ptr = realloc( *iovector, (1 + *iovec_entries ) * sizeof( struct iovec ) ); 19 void *new_data;
20 if( !new_ptr ) 20 int new_entries = 1 + *iovec_entries;
21 struct iovec *new_vec = realloc( *iovector, new_entries * sizeof( struct iovec ) );
22
23 if( !new_vec )
21 return NULL; 24 return NULL;
22 *iovector = new_ptr; 25
23 new_ptr = mmap( NULL, new_alloc, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0 ); 26 /* Only allocate after we have a place to store the pointer */
24 if( !new_ptr ) 27 new_data = malloc( new_alloc );
28 if( !new_data )
25 return NULL; 29 return NULL;
26 ((*iovector)[*iovec_entries]).iov_base = new_ptr; 30
27 ((*iovector)[*iovec_entries]).iov_len = new_alloc; 31 new_vec[new_entries - 1].iov_base = new_data;
32 new_vec[new_entries - 1].iov_len = new_alloc;
33
34 *iovector = new_vec;
28 ++*iovec_entries; 35 ++*iovec_entries;
29 return new_ptr; 36 return new_data;
30} 37}
31 38
32void iovec_free( int *iovec_entries, struct iovec **iovector ) { 39void iovec_free( int *iovec_entries, struct iovec **iovector ) {
33 int i; 40 int i;
34 for( i=0; i<*iovec_entries; ++i ) 41 for( i=0; i<*iovec_entries; ++i )
35 munmap( ((*iovector)[i]).iov_base, ((*iovector)[i]).iov_len ); 42 free( ((*iovector)[i]).iov_base );
43 *iovector = NULL;
36 *iovec_entries = 0; 44 *iovec_entries = 0;
37} 45}
38 46
39void iovec_fixlast( int *iovec_entries, struct iovec **iovector, void *last_ptr ) { 47void iovec_fixlast( int *iovec_entries, struct iovec **iovector, void *last_ptr ) {
40 int page_size = getpagesize(); 48 if( *iovec_entries ) {
41 size_t old_alloc, new_alloc, old_pages, new_pages; 49 char * base = (char*)((*iovector)[ *iovec_entries - 1 ]).iov_base;
42 char * base = (char*)((*iovector)[ *iovec_entries - 1 ]).iov_base; 50 size_t new_alloc = ((char*)last_ptr) - base;
43
44 if( !*iovec_entries ) return;
45
46 old_alloc = ((*iovector)[ *iovec_entries - 1 ]).iov_len;
47 new_alloc = ((char*)last_ptr) - base;
48 old_pages = 1 + old_alloc / page_size;
49 new_pages = 1 + new_alloc / page_size;
50 51
51 if( old_pages != new_pages ) 52 ((*iovector)[*iovec_entries - 1 ]).iov_base = realloc( base, new_alloc );
52 munmap( base + new_pages * page_size, old_alloc - new_pages * page_size ); 53 ((*iovector)[*iovec_entries - 1 ]).iov_len = new_alloc;
53 ((*iovector)[*iovec_entries - 1 ]).iov_len = new_alloc; 54 }
54} 55}
55 56
56void *iovec_fix_increase_or_free( int *iovec_entries, struct iovec **iovector, void *last_ptr, size_t new_alloc ) { 57void *iovec_fix_increase_or_free( int *iovec_entries, struct iovec **iovector, void *last_ptr, size_t new_alloc ) {
57 void *new_ptr; 58 void *new_data;
58 59
59 iovec_fixlast( iovec_entries, iovector, last_ptr ); 60 iovec_fixlast( iovec_entries, iovector, last_ptr );
60 61
61 if( !( new_ptr = iovec_increase( iovec_entries, iovector, new_alloc ) ) ) 62 if( !( new_data = iovec_increase( iovec_entries, iovector, new_alloc ) ) )
62 iovec_free( iovec_entries, iovector ); 63 iovec_free( iovec_entries, iovector );
63 64
64 return new_ptr; 65 return new_data;
65} 66}
66 67
67 68
68size_t iovec_length( int *iovec_entries, struct iovec **iovector ) { 69size_t iovec_length( const int *iovec_entries, const struct iovec **iovector ) {
69 size_t length = 0; 70 size_t length = 0;
70 int i; 71 int i;
71 for( i=0; i<*iovec_entries; ++i ) 72 for( i=0; i<*iovec_entries; ++i )