diff --git a/archival/gzip.c b/archival/gzip.c index 9411e17a9..68f1cc87d 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -235,7 +235,7 @@ enum { }; -struct global1 { +struct globals { lng block_start; @@ -343,7 +343,6 @@ struct global1 { uint32_t crc; /* shift register contents */ }; -extern struct global1 *ptr_to_globals; #define G1 (*(ptr_to_globals - 1)) @@ -869,7 +868,7 @@ typedef struct tree_desc { int max_code; /* largest code with non zero frequency */ } tree_desc; -struct global2 { +struct globals2 { ush heap[HEAP_SIZE]; /* heap used to build the Huffman trees */ int heap_len; /* number of elements in the heap */ @@ -956,7 +955,7 @@ struct global2 { ulg compressed_len; /* total bit length of compressed file */ }; -#define G2ptr ((struct global2*)(ptr_to_globals)) +#define G2ptr ((struct globals2*)(ptr_to_globals)) #define G2 (*G2ptr) @@ -2048,7 +2047,7 @@ int gzip_main(int argc, char **argv) } #endif - ptr_to_globals = xzalloc(sizeof(struct global1) + sizeof(struct global2)); + ptr_to_globals = xzalloc(sizeof(struct globals) + sizeof(struct globals2)); ptr_to_globals++; G2.l_desc.dyn_tree = G2.dyn_ltree; G2.l_desc.static_tree = G2.static_ltree; diff --git a/docs/keep_data_small.txt b/docs/keep_data_small.txt index 272aa21c5..ec13b4d3f 100644 --- a/docs/keep_data_small.txt +++ b/docs/keep_data_small.txt @@ -59,30 +59,33 @@ archival/libunarchive/decompress_unzip.c: This example completely eliminates globals in that module. Required memory is allocated in inflate_gunzip() [its main module] -and then passed down to all subroutines which need to access globals +and then passed down to all subroutines which need to access 'globals' as a parameter. Example 2 In case you don't want to pass this additional parameter everywhere, take a look at archival/gzip.c. Here all global data is replaced by -singe global pointer (ptr_to_globals) to allocated storage. +single global pointer (ptr_to_globals) to allocated storage. In order to not duplicate ptr_to_globals in every applet, you can reuse single common one. It is defined in libbb/messages.c -as void *ptr_to_globals, but is NOT declared in libbb.h. -You first define a struct: +as struct globals *ptr_to_globals, but the struct globals is +NOT defined in libbb.h. You first define your own struct: -struct my_globals { int a; char buf[1000]; }; +struct globals { int a; char buf[1000]; }; and then declare that ptr_to_globals is a pointer to it: -extern struct my_globals *ptr_to_globals; #define G (*ptr_to_globals) -Linker magic enures that these two merge into single pointer object. +Linker magic ensures that these two merge into single pointer object. Now initialize it in _main(): ptr_to_globals = xzalloc(sizeof(G)); and you can reference "globals" by G.a, G.buf and so on, in any function. + +The drawback is that now you have to initialize it by hand. xzalloc() +can be helpful in clearing allocated storage to 0, but anything more +must be done by hand. diff --git a/include/libbb.h b/include/libbb.h index 9ea9f5ae6..9a6966dbd 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -806,6 +806,10 @@ extern const int const_int_1; #define BUFSIZ 4096 #endif extern char bb_common_bufsiz1[BUFSIZ+1]; +/* This struct is deliberately not defined. */ +/* See docs/keep_data_small.txt */ +struct globals; +extern struct globals *ptr_to_globals; /* You can change LIBBB_DEFAULT_LOGIN_SHELL, but don't use it, * use bb_default_login_shell and following defines. diff --git a/libbb/messages.c b/libbb/messages.c index 39bb4c95b..1a10a8c9e 100644 --- a/libbb/messages.c +++ b/libbb/messages.c @@ -56,4 +56,5 @@ WTMP_FILE; char bb_common_bufsiz1[BUFSIZ+1]; -void *ptr_to_globals; +struct globals; +struct globals *ptr_to_globals;