aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Config.h5
-rw-r--r--archival/gunzip.c4
-rw-r--r--busybox.h8
-rw-r--r--coreutils/tr.c9
-rw-r--r--cp_mv.c4
-rw-r--r--docs/style-guide.txt18
-rw-r--r--gunzip.c4
-rw-r--r--include/busybox.h8
-rw-r--r--rpmunpack.c2
-rw-r--r--sysklogd/syslogd.c4
-rw-r--r--syslogd.c4
-rw-r--r--tr.c9
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;