From d35c21587a4139031c077fd122252217a4713681 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Thu, 25 Jan 2001 23:49:09 +0000 Subject: Commit Larry Doolittle's buffers-on-stack/buffers-via-malloc patch. -Erik --- Config.h | 5 +++++ archival/gunzip.c | 4 ++-- busybox.h | 8 ++++++++ coreutils/tr.c | 9 +++++---- cp_mv.c | 4 ++-- docs/style-guide.txt | 18 +++++++++--------- gunzip.c | 4 ++-- include/busybox.h | 8 ++++++++ rpmunpack.c | 2 +- sysklogd/syslogd.c | 4 ++-- syslogd.c | 4 ++-- tr.c | 9 +++++---- 12 files changed, 51 insertions(+), 28 deletions(-) diff --git a/Config.h b/Config.h index 667612cb5..a2e2d0469 100644 --- a/Config.h +++ b/Config.h @@ -129,6 +129,11 @@ // pretty/useful). // // +// BusyBox will, by default, malloc space for its buffers. This costs code +// size for the call to xmalloc. You can use the following feature to have +// them put on the stack. For some very small machines with limited stack +// space, this can be deadly. For most folks, this works just fine... +//#define BB_FEATURE_BUFFERS_GO_ON_STACK // // Turn this on to use Erik's very cool devps, and devmtab kernel drivers, // thereby eliminating the need for the /proc filesystem and thereby saving diff --git a/archival/gunzip.c b/archival/gunzip.c index 194921682..09571f91c 100644 --- a/archival/gunzip.c +++ b/archival/gunzip.c @@ -1222,8 +1222,8 @@ int gunzip_main(int argc, char **argv) int force = 0; struct stat statBuf; char *delFileName; - char ifname[MAX_PATH_LEN + 1]; /* input file name */ - char ofname[MAX_PATH_LEN + 1]; /* output file name */ + RESERVE_BB_BUFFER(ifname, MAX_PATH_LEN+1); /* input file name */ + RESERVE_BB_BUFFER(ofname, MAX_PATH_LEN+1); /* output file name */ method = DEFLATED; /* default compression method */ exit_code = OK; /* let's go out on a limb and assume everything will run fine (wink wink) */ diff --git a/busybox.h b/busybox.h index 018c636cf..be6c6f305 100644 --- a/busybox.h +++ b/busybox.h @@ -266,4 +266,12 @@ char *format(unsigned long val, unsigned long hr); #define GIGABYTE (MEGABYTE*1024) #endif +#ifdef BB_FEATURE_BUFFERS_GO_ON_STACK +#define RESERVE_BB_BUFFER(buffer,len) char buffer[len] +#define RESERVE_BB_UBUFFER(buffer,len) unsigned char buffer[len] +#else +#define RESERVE_BB_BUFFER(buffer,len) char *buffer=xmalloc(len) +#define RESERVE_BB_UBUFFER(buffer,len) unsigned char *buffer=xmalloc(len) +#endif + #endif /* _BB_INTERNAL_H_ */ diff --git a/coreutils/tr.c b/coreutils/tr.c index d21e672fe..15e3709bb 100644 --- a/coreutils/tr.c +++ b/coreutils/tr.c @@ -144,10 +144,11 @@ extern int tr_main(int argc, char **argv) int output_length=0, input_length; int index = 1; int i; - /* set up big arrays here (better than making a bunch of static arrays up top) */ - unsigned char output[BUFSIZ], input[BUFSIZ]; - unsigned char vector[ASCII + 1]; - char invec[ASCII + 1], outvec[ASCII + 1]; + RESERVE_BB_BUFFER(output, BUFSIZ); + RESERVE_BB_BUFFER(input, BUFSIZ); + RESERVE_BB_UBUFFER(vector, ASCII+1); + RESERVE_BB_BUFFER(invec, ASCII+1); + RESERVE_BB_BUFFER(outvec, ASCII+1); /* ... but make them available globally */ poutput = output; diff --git a/cp_mv.c b/cp_mv.c index 55483505f..9bcac02d4 100644 --- a/cp_mv.c +++ b/cp_mv.c @@ -175,8 +175,8 @@ extern int cp_mv_main(int argc, char **argv) { volatile int i; int c; - char baseDestName[BUFSIZ + 1]; /* not declared globally == less bss used */ - pBaseDestName = baseDestName; /* but available globally */ + RESERVE_BB_BUFFER(baseDestName,BUFSIZ + 1); + pBaseDestName = baseDestName; /* available globally */ if (*applet_name == 'c' && *(applet_name + 1) == 'p') dz_i = is_cp; diff --git a/docs/style-guide.txt b/docs/style-guide.txt index 9a3b10207..1a04e4474 100644 --- a/docs/style-guide.txt +++ b/docs/style-guide.txt @@ -402,7 +402,7 @@ The problem with these is that any time any busybox app is run, you pay a memory penalty for this buffer, even if the applet that uses said buffer is not run. This can be fixed, thusly: - static char *buffer + static char *buffer; ... other_func() { @@ -418,7 +418,7 @@ mallocing the buffers (and thus growing the text size), buffers can be declared on the stack in the *_main() function and made available globally by assigning them to a global pointer thusly: - static char *pbuffer + static char *pbuffer; ... other_func() { @@ -430,13 +430,13 @@ assigning them to a global pointer thusly: pbuffer = buffer; /* but available globally */ ... -Thus: - - global static buffers are eliminated - - we don't grow the text segment as much because no malloc() call is made; - memory is automatically allocated on the stack when execution context - enters the function. (We still grow text a little bit because of the - assignment, but that's cheap compared to a function call.) - - the buffer is still available globally via the pointer +This last approach has some advantages (low code size, space not used until +it's needed), but can be a problem in some low resource machines that have +very limited stack space (e.g., uCLinux). busybox.h declares a macro that +implements compile-time selection between xmalloc() and stack creation, so +you can code the line in question as + RESERVE_BB_BUFFER(buffer, BUFSIZ); +and the right thing will happen, based on the customer's configuration. diff --git a/gunzip.c b/gunzip.c index 194921682..09571f91c 100644 --- a/gunzip.c +++ b/gunzip.c @@ -1222,8 +1222,8 @@ int gunzip_main(int argc, char **argv) int force = 0; struct stat statBuf; char *delFileName; - char ifname[MAX_PATH_LEN + 1]; /* input file name */ - char ofname[MAX_PATH_LEN + 1]; /* output file name */ + RESERVE_BB_BUFFER(ifname, MAX_PATH_LEN+1); /* input file name */ + RESERVE_BB_BUFFER(ofname, MAX_PATH_LEN+1); /* output file name */ method = DEFLATED; /* default compression method */ exit_code = OK; /* let's go out on a limb and assume everything will run fine (wink wink) */ diff --git a/include/busybox.h b/include/busybox.h index 018c636cf..be6c6f305 100644 --- a/include/busybox.h +++ b/include/busybox.h @@ -266,4 +266,12 @@ char *format(unsigned long val, unsigned long hr); #define GIGABYTE (MEGABYTE*1024) #endif +#ifdef BB_FEATURE_BUFFERS_GO_ON_STACK +#define RESERVE_BB_BUFFER(buffer,len) char buffer[len] +#define RESERVE_BB_UBUFFER(buffer,len) unsigned char buffer[len] +#else +#define RESERVE_BB_BUFFER(buffer,len) char *buffer=xmalloc(len) +#define RESERVE_BB_UBUFFER(buffer,len) unsigned char *buffer=xmalloc(len) +#endif + #endif /* _BB_INTERNAL_H_ */ diff --git a/rpmunpack.c b/rpmunpack.c index 512d63839..0f36077c1 100644 --- a/rpmunpack.c +++ b/rpmunpack.c @@ -51,7 +51,7 @@ static void myread(int num, char *buffer) int rpmunpack_main(int argc, char **argv) { int len, status = 0; - char buffer[BUFSIZ]; + RESERVE_BB_BUFFER(buffer, BUFSIZ); /* Get our own program name */ if ((progname = strrchr(argv[0], '/')) == NULL) diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 114516e2f..972fda15f 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -209,7 +209,7 @@ static void domark(int sig) static const int BUFSIZE = 1023; static int serveConnection (int conn) { - char buf[ BUFSIZE + 1 ]; + RESERVE_BB_BUFFER(buf, BUFSIZE + 1); int n_read; while ((n_read = read (conn, buf, BUFSIZE )) > 0) { @@ -296,7 +296,7 @@ static void doSyslogd (void) int sock_fd; fd_set fds; - char lfile[BUFSIZ]; + RESERVE_BB_BUFFER(lfile, BUFSIZ); /* Set up signal handlers. */ signal (SIGINT, quit_signal); diff --git a/syslogd.c b/syslogd.c index 114516e2f..972fda15f 100644 --- a/syslogd.c +++ b/syslogd.c @@ -209,7 +209,7 @@ static void domark(int sig) static const int BUFSIZE = 1023; static int serveConnection (int conn) { - char buf[ BUFSIZE + 1 ]; + RESERVE_BB_BUFFER(buf, BUFSIZE + 1); int n_read; while ((n_read = read (conn, buf, BUFSIZE )) > 0) { @@ -296,7 +296,7 @@ static void doSyslogd (void) int sock_fd; fd_set fds; - char lfile[BUFSIZ]; + RESERVE_BB_BUFFER(lfile, BUFSIZ); /* Set up signal handlers. */ signal (SIGINT, quit_signal); diff --git a/tr.c b/tr.c index d21e672fe..15e3709bb 100644 --- a/tr.c +++ b/tr.c @@ -144,10 +144,11 @@ extern int tr_main(int argc, char **argv) int output_length=0, input_length; int index = 1; int i; - /* set up big arrays here (better than making a bunch of static arrays up top) */ - unsigned char output[BUFSIZ], input[BUFSIZ]; - unsigned char vector[ASCII + 1]; - char invec[ASCII + 1], outvec[ASCII + 1]; + RESERVE_BB_BUFFER(output, BUFSIZ); + RESERVE_BB_BUFFER(input, BUFSIZ); + RESERVE_BB_UBUFFER(vector, ASCII+1); + RESERVE_BB_BUFFER(invec, ASCII+1); + RESERVE_BB_BUFFER(outvec, ASCII+1); /* ... but make them available globally */ poutput = output; -- cgit v1.2.3