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