diff options
Diffstat (limited to 'ot_iovec.c')
-rw-r--r-- | ot_iovec.c | 57 |
1 files changed, 29 insertions, 28 deletions
@@ -16,56 +16,57 @@ | |||
16 | #include "ot_iovec.h" | 16 | #include "ot_iovec.h" |
17 | 17 | ||
18 | void *iovec_increase( int *iovec_entries, struct iovec **iovector, size_t new_alloc ) { | 18 | void *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 | ||
32 | void iovec_free( int *iovec_entries, struct iovec **iovector ) { | 39 | void 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 | ||
39 | void iovec_fixlast( int *iovec_entries, struct iovec **iovector, void *last_ptr ) { | 47 | void 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 | ||
56 | void *iovec_fix_increase_or_free( int *iovec_entries, struct iovec **iovector, void *last_ptr, size_t new_alloc ) { | 57 | void *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 | ||
68 | size_t iovec_length( int *iovec_entries, struct iovec **iovector ) { | 69 | size_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 ) |