modify ptr_to_globals trick so that we do not violate

type safety (well, sort of ;))
This commit is contained in:
Denis Vlasenko 2007-03-15 00:57:01 +00:00
parent dd2b2f75ae
commit 972288e62f
4 changed files with 20 additions and 13 deletions

View File

@ -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;

View File

@ -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 <applet>_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.

View File

@ -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.

View File

@ -56,4 +56,5 @@ WTMP_FILE;
char bb_common_bufsiz1[BUFSIZ+1];
void *ptr_to_globals;
struct globals;
struct globals *ptr_to_globals;