diff options
Diffstat (limited to 'ot_iovec.c')
-rw-r--r-- | ot_iovec.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/ot_iovec.c b/ot_iovec.c new file mode 100644 index 0000000..ea3dd23 --- /dev/null +++ b/ot_iovec.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* This software was written by Dirk Engling <erdgeist@erdgeist.org> | ||
2 | It is considered beerware. Prost. Skol. Cheers or whatever. */ | ||
3 | |||
4 | /* System */ | ||
5 | #include <sys/types.h> | ||
6 | #include <sys/mman.h> | ||
7 | #include <stdlib.h> | ||
8 | #include <unistd.h> | ||
9 | #include <sys/uio.h> | ||
10 | |||
11 | /* Libowfat */ | ||
12 | |||
13 | /* Opentracker */ | ||
14 | #include "ot_iovec.h" | ||
15 | |||
16 | void *iovec_increase( int *iovec_entries, struct iovec **iovector, size_t new_alloc ) { | ||
17 | void *new_ptr = realloc( *iovector, 1 + *iovec_entries * sizeof( struct iovec ) ); | ||
18 | if( !new_ptr ) | ||
19 | return NULL; | ||
20 | *iovector = new_ptr; | ||
21 | new_ptr = mmap( NULL, new_alloc, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0 ); | ||
22 | if( !new_ptr ) | ||
23 | return NULL; | ||
24 | ((*iovector)[*iovec_entries]).iov_base = new_ptr; | ||
25 | ((*iovector)[*iovec_entries]).iov_len = new_alloc; | ||
26 | ++*iovec_entries; | ||
27 | return new_ptr; | ||
28 | } | ||
29 | |||
30 | void iovec_free( int *iovec_entries, struct iovec **iovector ) { | ||
31 | int i; | ||
32 | for( i=0; i<*iovec_entries; ++i ) | ||
33 | munmap( ((*iovector)[i]).iov_base, ((*iovector)[i]).iov_len ); | ||
34 | *iovec_entries = 0; | ||
35 | } | ||
36 | |||
37 | void iovec_fixlast( int *iovec_entries, struct iovec **iovector, size_t new_alloc ) { | ||
38 | int page_size = getpagesize(); | ||
39 | size_t old_alloc, old_pages, new_pages; | ||
40 | |||
41 | if( !*iovec_entries ) return; | ||
42 | |||
43 | old_alloc = ((*iovector)[ *iovec_entries - 1 ]).iov_len; | ||
44 | old_pages = 1 + old_alloc / page_size; | ||
45 | new_pages = 1 + new_alloc / page_size; | ||
46 | |||
47 | if( old_pages != new_pages ) { | ||
48 | munmap( ((char*)((*iovector)[ *iovec_entries - 1 ]).iov_base ) + new_pages * page_size, | ||
49 | old_alloc - new_pages * page_size ); | ||
50 | } | ||
51 | ((*iovector)[*iovec_entries - 1 ]).iov_len = new_alloc; | ||
52 | } | ||
53 | |||
54 | size_t iovec_length( int *iovec_entries, struct iovec **iovector ) { | ||
55 | size_t length = 0; | ||
56 | int i; | ||
57 | for( i=0; i<*iovec_entries; ++i ) | ||
58 | length += ((*iovector)[i]).iov_len; | ||
59 | return length; | ||
60 | } | ||