aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-01-12 22:11:24 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-01-12 22:11:24 +0100
commit7306727d1b2ed05afc91548ba374f7400a2389e3 (patch)
tree39cf4dff144f82dc9eaad30eae9c4fe67d405e4e
parent6c93b24ce9dfb5c3970178ca2545502a7830716c (diff)
downloadbusybox-w32-7306727d1b2ed05afc91548ba374f7400a2389e3.tar.gz
busybox-w32-7306727d1b2ed05afc91548ba374f7400a2389e3.tar.bz2
busybox-w32-7306727d1b2ed05afc91548ba374f7400a2389e3.zip
shell: split read builtin from ash
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--TODO_config_nommu2
-rw-r--r--scripts/defconfig2
-rw-r--r--shell/Kbuild2
-rw-r--r--shell/ash.c234
-rw-r--r--shell/ash_test/ash-read/read_REPLY.right5
-rwxr-xr-xshell/ash_test/ash-read/read_REPLY.tests5
-rw-r--r--shell/builtin_read.c205
-rw-r--r--shell/builtin_read.h42
-rw-r--r--shell/match.c10
-rw-r--r--shell/match.h5
-rw-r--r--shell/math.c15
-rw-r--r--shell/random.h8
-rw-r--r--shell/shell_common.c26
-rw-r--r--shell/shell_common.h35
14 files changed, 379 insertions, 217 deletions
diff --git a/TODO_config_nommu b/TODO_config_nommu
index d5ee7bebd..804fc61c9 100644
--- a/TODO_config_nommu
+++ b/TODO_config_nommu
@@ -859,8 +859,6 @@ CONFIG_FEATURE_SH_IS_HUSH=y
859# CONFIG_ASH is not set 859# CONFIG_ASH is not set
860# CONFIG_ASH_BASH_COMPAT is not set 860# CONFIG_ASH_BASH_COMPAT is not set
861# CONFIG_ASH_JOB_CONTROL is not set 861# CONFIG_ASH_JOB_CONTROL is not set
862# CONFIG_ASH_READ_NCHARS is not set
863# CONFIG_ASH_READ_TIMEOUT is not set
864# CONFIG_ASH_ALIAS is not set 862# CONFIG_ASH_ALIAS is not set
865# CONFIG_ASH_GETOPTS is not set 863# CONFIG_ASH_GETOPTS is not set
866# CONFIG_ASH_BUILTIN_ECHO is not set 864# CONFIG_ASH_BUILTIN_ECHO is not set
diff --git a/scripts/defconfig b/scripts/defconfig
index a98c7b6fa..3a3d08260 100644
--- a/scripts/defconfig
+++ b/scripts/defconfig
@@ -856,8 +856,6 @@ CONFIG_FEATURE_SH_IS_ASH=y
856CONFIG_ASH=y 856CONFIG_ASH=y
857CONFIG_ASH_BASH_COMPAT=y 857CONFIG_ASH_BASH_COMPAT=y
858CONFIG_ASH_JOB_CONTROL=y 858CONFIG_ASH_JOB_CONTROL=y
859CONFIG_ASH_READ_NCHARS=y
860CONFIG_ASH_READ_TIMEOUT=y
861CONFIG_ASH_ALIAS=y 859CONFIG_ASH_ALIAS=y
862CONFIG_ASH_GETOPTS=y 860CONFIG_ASH_GETOPTS=y
863CONFIG_ASH_BUILTIN_ECHO=y 861CONFIG_ASH_BUILTIN_ECHO=y
diff --git a/shell/Kbuild b/shell/Kbuild
index 03960a8ea..155ac6f0f 100644
--- a/shell/Kbuild
+++ b/shell/Kbuild
@@ -5,7 +5,7 @@
5# Licensed under the GPL v2, see the file LICENSE in this tarball. 5# Licensed under the GPL v2, see the file LICENSE in this tarball.
6 6
7lib-y:= 7lib-y:=
8lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o 8lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o builtin_read.o
9lib-$(CONFIG_HUSH) += hush.o match.o 9lib-$(CONFIG_HUSH) += hush.o match.o
10lib-$(CONFIG_CTTYHACK) += cttyhack.o 10lib-$(CONFIG_CTTYHACK) += cttyhack.o
11 11
diff --git a/shell/ash.c b/shell/ash.c
index e668f41e1..c7deffd08 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2,18 +2,18 @@
2/* 2/*
3 * ash shell port for busybox 3 * ash shell port for busybox
4 * 4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kenneth Almquist.
7 *
8 * Original BSD copyright notice is retained at the end of this file.
9 *
5 * Copyright (c) 1989, 1991, 1993, 1994 10 * Copyright (c) 1989, 1991, 1993, 1994
6 * The Regents of the University of California. All rights reserved. 11 * The Regents of the University of California. All rights reserved.
7 * 12 *
8 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au> 13 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
9 * was re-ported from NetBSD and debianized. 14 * was re-ported from NetBSD and debianized.
10 * 15 *
11 * This code is derived from software contributed to Berkeley by
12 * Kenneth Almquist.
13 *
14 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 16 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
15 *
16 * Original BSD copyright notice is retained at the end of this file.
17 */ 17 */
18 18
19/* 19/*
@@ -34,8 +34,6 @@
34 34
35#define PROFILE 0 35#define PROFILE 0
36 36
37#define IFS_BROKEN
38
39#define JOBS ENABLE_ASH_JOB_CONTROL 37#define JOBS ENABLE_ASH_JOB_CONTROL
40 38
41#if DEBUG 39#if DEBUG
@@ -50,6 +48,9 @@
50#include <paths.h> 48#include <paths.h>
51#include <setjmp.h> 49#include <setjmp.h>
52#include <fnmatch.h> 50#include <fnmatch.h>
51
52#include "shell_common.h"
53#include "builtin_read.h"
53#include "math.h" 54#include "math.h"
54#if ENABLE_ASH_RANDOM_SUPPORT 55#if ENABLE_ASH_RANDOM_SUPPORT
55# include "random.h" 56# include "random.h"
@@ -1737,13 +1738,6 @@ struct localvar {
1737# define VDYNAMIC 0 1738# define VDYNAMIC 0
1738#endif 1739#endif
1739 1740
1740#ifdef IFS_BROKEN
1741static const char defifsvar[] ALIGN1 = "IFS= \t\n";
1742#define defifs (defifsvar + 4)
1743#else
1744static const char defifs[] ALIGN1 = " \t\n";
1745#endif
1746
1747 1741
1748/* Need to be before varinit_data[] */ 1742/* Need to be before varinit_data[] */
1749#if ENABLE_LOCALE_SUPPORT 1743#if ENABLE_LOCALE_SUPPORT
@@ -1774,7 +1768,7 @@ static const struct {
1774 const char *text; 1768 const char *text;
1775 void (*func)(const char *) FAST_FUNC; 1769 void (*func)(const char *) FAST_FUNC;
1776} varinit_data[] = { 1770} varinit_data[] = {
1777#ifdef IFS_BROKEN 1771#if IFS_BROKEN
1778 { VSTRFIXED|VTEXTFIXED , defifsvar , NULL }, 1772 { VSTRFIXED|VTEXTFIXED , defifsvar , NULL },
1779#else 1773#else
1780 { VSTRFIXED|VTEXTFIXED|VUNSET, "IFS\0" , NULL }, 1774 { VSTRFIXED|VTEXTFIXED|VUNSET, "IFS\0" , NULL },
@@ -12499,211 +12493,53 @@ typedef enum __rlimit_resource rlim_t;
12499static int FAST_FUNC 12493static int FAST_FUNC
12500readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) 12494readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
12501{ 12495{
12502 static const char *const arg_REPLY[] = { "REPLY", NULL }; 12496 char *opt_n = NULL;
12503 12497 char *opt_p = NULL;
12504 char **ap; 12498 char *opt_t = NULL;
12505 int backslash; 12499 char *opt_u = NULL;
12506 char c; 12500 int read_flags = 0;
12507 int rflag; 12501 const char *r;
12508 char *prompt;
12509 const char *ifs;
12510 char *p;
12511 int startword;
12512 int status;
12513 int i; 12502 int i;
12514 int fd = 0; 12503
12515#if ENABLE_ASH_READ_NCHARS 12504 while ((i = nextopt("p:u:rt:n:s")) != '\0') {
12516 int nchars = 0; /* if != 0, -n is in effect */
12517 int silent = 0;
12518 struct termios tty, old_tty;
12519#endif
12520#if ENABLE_ASH_READ_TIMEOUT
12521 unsigned end_ms = 0;
12522 unsigned timeout = 0;
12523#endif
12524
12525 rflag = 0;
12526 prompt = NULL;
12527 while ((i = nextopt("p:u:r"
12528 IF_ASH_READ_TIMEOUT("t:")
12529 IF_ASH_READ_NCHARS("n:s")
12530 )) != '\0') {
12531 switch (i) { 12505 switch (i) {
12532 case 'p': 12506 case 'p':
12533 prompt = optionarg; 12507 opt_p = optionarg;
12534 break; 12508 break;
12535#if ENABLE_ASH_READ_NCHARS
12536 case 'n': 12509 case 'n':
12537 nchars = bb_strtou(optionarg, NULL, 10); 12510 opt_n = optionarg;
12538 if (nchars < 0 || errno)
12539 ash_msg_and_raise_error("invalid count");
12540 /* nchars == 0: off (bash 3.2 does this too) */
12541 break; 12511 break;
12542 case 's': 12512 case 's':
12543 silent = 1; 12513 read_flags |= BUILTIN_READ_SILENT;
12544 break; 12514 break;
12545#endif
12546#if ENABLE_ASH_READ_TIMEOUT
12547 case 't': 12515 case 't':
12548 timeout = bb_strtou(optionarg, NULL, 10); 12516 opt_t = optionarg;
12549 if (errno || timeout > UINT_MAX / 2048)
12550 ash_msg_and_raise_error("invalid timeout");
12551 timeout *= 1000;
12552#if 0 /* even bash have no -t N.NNN support */
12553 ts.tv_sec = bb_strtou(optionarg, &p, 10);
12554 ts.tv_usec = 0;
12555 /* EINVAL means number is ok, but not terminated by NUL */
12556 if (*p == '.' && errno == EINVAL) {
12557 char *p2;
12558 if (*++p) {
12559 int scale;
12560 ts.tv_usec = bb_strtou(p, &p2, 10);
12561 if (errno)
12562 ash_msg_and_raise_error("invalid timeout");
12563 scale = p2 - p;
12564 /* normalize to usec */
12565 if (scale > 6)
12566 ash_msg_and_raise_error("invalid timeout");
12567 while (scale++ < 6)
12568 ts.tv_usec *= 10;
12569 }
12570 } else if (ts.tv_sec < 0 || errno) {
12571 ash_msg_and_raise_error("invalid timeout");
12572 }
12573 if (!(ts.tv_sec | ts.tv_usec)) { /* both are 0? */
12574 ash_msg_and_raise_error("invalid timeout");
12575 }
12576#endif /* if 0 */
12577 break; 12517 break;
12578#endif
12579 case 'r': 12518 case 'r':
12580 rflag = 1; 12519 read_flags |= BUILTIN_READ_RAW;
12581 break; 12520 break;
12582 case 'u': 12521 case 'u':
12583 fd = bb_strtou(optionarg, NULL, 10); 12522 opt_u = optionarg;
12584 if (fd < 0 || errno)
12585 ash_msg_and_raise_error("invalid file descriptor");
12586 break; 12523 break;
12587 default: 12524 default:
12588 break; 12525 break;
12589 } 12526 }
12590 } 12527 }
12591 if (prompt && isatty(fd)) {
12592 out2str(prompt);
12593 }
12594 ap = argptr;
12595 if (*ap == NULL)
12596 ap = (char**)arg_REPLY;
12597 ifs = bltinlookup("IFS");
12598 if (ifs == NULL)
12599 ifs = defifs;
12600#if ENABLE_ASH_READ_NCHARS
12601 tcgetattr(fd, &tty);
12602 old_tty = tty;
12603 if (nchars || silent) {
12604 if (nchars) {
12605 tty.c_lflag &= ~ICANON;
12606 tty.c_cc[VMIN] = nchars < 256 ? nchars : 255;
12607 }
12608 if (silent) {
12609 tty.c_lflag &= ~(ECHO | ECHOK | ECHONL);
12610 }
12611 /* if tcgetattr failed, tcsetattr will fail too.
12612 * Ignoring, it's harmless. */
12613 tcsetattr(fd, TCSANOW, &tty);
12614 }
12615#endif
12616 12528
12617 status = 0; 12529 r = builtin_read(setvar,
12618 startword = 1; 12530 argptr,
12619 backslash = 0; 12531 bltinlookup("IFS"), /* can be NULL */
12620#if ENABLE_ASH_READ_TIMEOUT 12532 read_flags,
12621 if (timeout) /* NB: ensuring end_ms is nonzero */ 12533 opt_n,
12622 end_ms = ((unsigned)monotonic_ms() + timeout) | 1; 12534 opt_p,
12623#endif 12535 opt_t,
12624 STARTSTACKSTR(p); 12536 opt_u
12625 do { 12537 );
12626 const char *is_ifs;
12627
12628#if ENABLE_ASH_READ_TIMEOUT
12629 if (end_ms) {
12630 struct pollfd pfd[1];
12631 pfd[0].fd = fd;
12632 pfd[0].events = POLLIN;
12633 timeout = end_ms - (unsigned)monotonic_ms();
12634 if ((int)timeout <= 0 /* already late? */
12635 || safe_poll(pfd, 1, timeout) != 1 /* no? wait... */
12636 ) { /* timed out! */
12637#if ENABLE_ASH_READ_NCHARS
12638 tcsetattr(fd, TCSANOW, &old_tty);
12639#endif
12640 return 1;
12641 }
12642 }
12643#endif
12644 if (nonblock_safe_read(fd, &c, 1) != 1) {
12645 status = 1;
12646 break;
12647 }
12648 if (c == '\0')
12649 continue;
12650 if (backslash) {
12651 backslash = 0;
12652 if (c != '\n')
12653 goto put;
12654 continue;
12655 }
12656 if (!rflag && c == '\\') {
12657 backslash = 1;
12658 continue;
12659 }
12660 if (c == '\n')
12661 break;
12662 /* $IFS splitting */
12663/* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05 */
12664 is_ifs = strchr(ifs, c);
12665 if (startword && is_ifs) {
12666 if (isspace(c))
12667 continue;
12668 /* it is a non-space ifs char */
12669 startword--;
12670 if (startword == 1) /* first one? */
12671 continue; /* yes, it is not next word yet */
12672 }
12673 startword = 0;
12674 if (ap[1] != NULL && is_ifs) {
12675 const char *beg;
12676 STACKSTRNUL(p);
12677 beg = stackblock();
12678 setvar(*ap, beg, 0);
12679 ap++;
12680 /* can we skip one non-space ifs char? (2: yes) */
12681 startword = isspace(c) ? 2 : 1;
12682 STARTSTACKSTR(p);
12683 continue;
12684 }
12685 put:
12686 STPUTC(c, p);
12687 }
12688/* end of do {} while: */
12689#if ENABLE_ASH_READ_NCHARS
12690 while (--nchars);
12691#else
12692 while (1);
12693#endif
12694 12538
12695#if ENABLE_ASH_READ_NCHARS 12539 if ((uintptr_t)r > 1)
12696 tcsetattr(fd, TCSANOW, &old_tty); 12540 ash_msg_and_raise_error(r);
12697#endif
12698 12541
12699 STACKSTRNUL(p); 12542 return (uintptr_t)r;
12700 /* Remove trailing space ifs chars */
12701 while ((char *)stackblock() <= --p && isspace(*p) && strchr(ifs, *p) != NULL)
12702 *p = '\0';
12703 setvar(*ap, stackblock(), 0);
12704 while (*++ap != NULL)
12705 setvar(*ap, nullstr, 0);
12706 return status;
12707} 12543}
12708 12544
12709static int FAST_FUNC 12545static int FAST_FUNC
diff --git a/shell/ash_test/ash-read/read_REPLY.right b/shell/ash_test/ash-read/read_REPLY.right
new file mode 100644
index 000000000..59f5d5487
--- /dev/null
+++ b/shell/ash_test/ash-read/read_REPLY.right
@@ -0,0 +1,5 @@
1test 1: | abc1 def |
2test 2: | \abc2 d\ef |
3test 3: |abc3 def|
4test 4: |\abc4 d\ef|
5Done
diff --git a/shell/ash_test/ash-read/read_REPLY.tests b/shell/ash_test/ash-read/read_REPLY.tests
new file mode 100755
index 000000000..ba20cae8d
--- /dev/null
+++ b/shell/ash_test/ash-read/read_REPLY.tests
@@ -0,0 +1,5 @@
1echo ' \abc1 d\ef ' | ( read ; echo "test 1: |$REPLY|" )
2echo ' \abc2 d\ef ' | ( read -r ; echo "test 2: |$REPLY|" )
3echo ' \abc3 d\ef ' | ( read REPLY; echo "test 3: |$REPLY|" )
4echo ' \abc4 d\ef ' | ( read -r REPLY; echo "test 4: |$REPLY|" )
5echo Done
diff --git a/shell/builtin_read.c b/shell/builtin_read.c
new file mode 100644
index 000000000..7f667e9c1
--- /dev/null
+++ b/shell/builtin_read.c
@@ -0,0 +1,205 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Adapted from ash applet code
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kenneth Almquist.
7 *
8 * Copyright (c) 1989, 1991, 1993, 1994
9 * The Regents of the University of California. All rights reserved.
10 *
11 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
12 * was re-ported from NetBSD and debianized.
13 *
14 * Copyright (c) 2010 Denys Vlasenko
15 * Split from ash.c
16 *
17 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
18 */
19#include "libbb.h"
20#include "shell_common.h"
21#include "builtin_read.h"
22
23const char* FAST_FUNC
24builtin_read(void (*setvar)(const char *name, const char *val, int flags),
25 char **argv,
26 const char *ifs,
27 int read_flags,
28 const char *opt_n,
29 const char *opt_p,
30 const char *opt_t,
31 const char *opt_u
32)
33{
34 static const char *const arg_REPLY[] = { "REPLY", NULL };
35
36 unsigned end_ms; /* -t TIMEOUT */
37 int fd; /* -u FD */
38 int nchars; /* -n NUM */
39 char *buffer;
40 struct termios tty, old_tty;
41 const char *retval;
42 int bufpos; /* need to be able to hold -1 */
43 int startword;
44 smallint backslash;
45
46 nchars = 0; /* if != 0, -n is in effect */
47 if (opt_n) {
48 nchars = bb_strtou(opt_n, NULL, 10);
49 if (nchars < 0 || errno)
50 return "invalid count";
51 /* note: "-n 0": off (bash 3.2 does this too) */
52 }
53 end_ms = 0;
54 if (opt_t) {
55 end_ms = bb_strtou(opt_t, NULL, 10);
56 if (errno || end_ms > UINT_MAX / 2048)
57 return "invalid timeout";
58 end_ms *= 1000;
59#if 0 /* even bash has no -t N.NNN support */
60 ts.tv_sec = bb_strtou(opt_t, &p, 10);
61 ts.tv_usec = 0;
62 /* EINVAL means number is ok, but not terminated by NUL */
63 if (*p == '.' && errno == EINVAL) {
64 char *p2;
65 if (*++p) {
66 int scale;
67 ts.tv_usec = bb_strtou(p, &p2, 10);
68 if (errno)
69 return "invalid timeout";
70 scale = p2 - p;
71 /* normalize to usec */
72 if (scale > 6)
73 return "invalid timeout";
74 while (scale++ < 6)
75 ts.tv_usec *= 10;
76 }
77 } else if (ts.tv_sec < 0 || errno) {
78 return "invalid timeout";
79 }
80 if (!(ts.tv_sec | ts.tv_usec)) { /* both are 0? */
81 return "invalid timeout";
82 }
83#endif /* if 0 */
84 }
85 fd = STDIN_FILENO;
86 if (opt_u) {
87 fd = bb_strtou(opt_u, NULL, 10);
88 if (fd < 0 || errno)
89 return "invalid file descriptor";
90 }
91
92 if (opt_p && isatty(fd)) {
93 fputs(opt_p, stderr);
94 fflush_all();
95 }
96
97 if (argv[0] == NULL)
98 argv = (char**)arg_REPLY;
99 if (ifs == NULL)
100 ifs = defifs;
101
102 if (nchars || (read_flags & BUILTIN_READ_SILENT)) {
103 tcgetattr(fd, &tty);
104 old_tty = tty;
105 if (nchars) {
106 tty.c_lflag &= ~ICANON;
107 tty.c_cc[VMIN] = nchars < 256 ? nchars : 255;
108 }
109 if (read_flags & BUILTIN_READ_SILENT) {
110 tty.c_lflag &= ~(ECHO | ECHOK | ECHONL);
111 }
112 /* This forces execution of "restoring" tcgetattr later */
113 read_flags |= BUILTIN_READ_SILENT;
114 /* if tcgetattr failed, tcsetattr will fail too.
115 * Ignoring, it's harmless. */
116 tcsetattr(fd, TCSANOW, &tty);
117 }
118
119 retval = (const char *)(uintptr_t)0;
120 startword = 1;
121 backslash = 0;
122 if (end_ms) /* NB: end_ms stays nonzero: */
123 end_ms = ((unsigned)monotonic_ms() + end_ms) | 1;
124 buffer = NULL;
125 bufpos = 0;
126 do {
127 char c;
128 const char *is_ifs;
129
130 if (end_ms) {
131 int timeout;
132 struct pollfd pfd[1];
133
134 pfd[0].fd = fd;
135 pfd[0].events = POLLIN;
136 timeout = end_ms - (unsigned)monotonic_ms();
137 if (timeout <= 0 /* already late? */
138 || safe_poll(pfd, 1, timeout) != 1 /* no? wait... */
139 ) { /* timed out! */
140 retval = (const char *)(uintptr_t)1;
141 goto ret;
142 }
143 }
144
145 if ((bufpos & 0xff) == 0)
146 buffer = xrealloc(buffer, bufpos + 0x100);
147 if (nonblock_safe_read(fd, &buffer[bufpos], 1) != 1) {
148 retval = (const char *)(uintptr_t)1;
149 break;
150 }
151 c = buffer[bufpos];
152 if (c == '\0')
153 continue;
154 if (backslash) {
155 backslash = 0;
156 if (c != '\n')
157 goto put;
158 continue;
159 }
160 if (!(read_flags & BUILTIN_READ_RAW) && c == '\\') {
161 backslash = 1;
162 continue;
163 }
164 if (c == '\n')
165 break;
166 /* $IFS splitting */
167/* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05 */
168 is_ifs = strchr(ifs, c);
169 if (startword && is_ifs) {
170 if (isspace(c))
171 continue;
172 /* it is a non-space ifs char */
173 startword--;
174 if (startword == 1) /* first one? */
175 continue; /* yes, it is not next word yet */
176 }
177 startword = 0;
178 if (argv[1] != NULL && is_ifs) {
179 buffer[bufpos] = '\0';
180 bufpos = 0;
181 setvar(*argv, buffer, 0);
182 argv++;
183 /* can we skip one non-space ifs char? (2: yes) */
184 startword = isspace(c) ? 2 : 1;
185 continue;
186 }
187 put:
188 bufpos++;
189 } while (--nchars);
190
191 /* Remove trailing space ifs chars */
192 while (--bufpos >= 0 && isspace(buffer[bufpos]) && strchr(ifs, buffer[bufpos]) != NULL)
193 continue;
194 buffer[bufpos + 1] = '\0';
195
196 setvar(*argv, buffer, 0);
197
198 while (*++argv != NULL)
199 setvar(*argv, "", 0);
200 ret:
201 free(buffer);
202 if (read_flags & BUILTIN_READ_SILENT)
203 tcsetattr(fd, TCSANOW, &old_tty);
204 return retval;
205}
diff --git a/shell/builtin_read.h b/shell/builtin_read.h
new file mode 100644
index 000000000..930d01428
--- /dev/null
+++ b/shell/builtin_read.h
@@ -0,0 +1,42 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Adapted from ash applet code
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kenneth Almquist.
7 *
8 * Copyright (c) 1989, 1991, 1993, 1994
9 * The Regents of the University of California. All rights reserved.
10 *
11 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
12 * was re-ported from NetBSD and debianized.
13 *
14 * Copyright (c) 2010 Denys Vlasenko
15 * Split from ash.c
16 *
17 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
18 */
19#ifndef SHELL_BUILTIN_READ_H
20#define SHELL_BUILTIN_READ_H 1
21
22PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
23
24enum {
25 BUILTIN_READ_SILENT = 1 << 0,
26 BUILTIN_READ_RAW = 1 << 1,
27};
28
29const char* FAST_FUNC
30builtin_read(void (*setvar)(const char *name, const char *val, int flags),
31 char **argv,
32 const char *ifs,
33 int read_flags,
34 const char *opt_n,
35 const char *opt_p,
36 const char *opt_t,
37 const char *opt_u
38);
39
40POP_SAVED_FUNCTION_VISIBILITY
41
42#endif
diff --git a/shell/match.c b/shell/match.c
index a7101ef7e..fb6a38ef1 100644
--- a/shell/match.c
+++ b/shell/match.c
@@ -1,16 +1,16 @@
1/* 1/*
2 * ##/%% variable matching code ripped out of ash shell for code sharing 2 * ##/%% variable matching code ripped out of ash shell for code sharing
3 * 3 *
4 * This code is derived from software contributed to Berkeley by
5 * Kenneth Almquist.
6 *
7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
8 *
4 * Copyright (c) 1989, 1991, 1993, 1994 9 * Copyright (c) 1989, 1991, 1993, 1994
5 * The Regents of the University of California. All rights reserved. 10 * The Regents of the University of California. All rights reserved.
6 * 11 *
7 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au> 12 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
8 * was re-ported from NetBSD and debianized. 13 * was re-ported from NetBSD and debianized.
9 *
10 * This code is derived from software contributed to Berkeley by
11 * Kenneth Almquist.
12 *
13 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
14 */ 14 */
15#ifdef STANDALONE 15#ifdef STANDALONE
16# include <stdbool.h> 16# include <stdbool.h>
diff --git a/shell/match.h b/shell/match.h
index 90597ee54..98ff8745a 100644
--- a/shell/match.h
+++ b/shell/match.h
@@ -1,5 +1,8 @@
1/* match.h - interface to shell ##/%% matching code */ 1/* match.h - interface to shell ##/%% matching code */
2 2
3#ifndef SHELL_MATCH_H
4#define SHELL_MATCH_H 1
5
3PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 6PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
4 7
5typedef char *(*scan_t)(char *string, char *match, bool match_at_left); 8typedef char *(*scan_t)(char *string, char *match, bool match_at_left);
@@ -24,3 +27,5 @@ static inline scan_t pick_scan(char op1, char op2, bool *match_at_left)
24} 27}
25 28
26POP_SAVED_FUNCTION_VISIBILITY 29POP_SAVED_FUNCTION_VISIBILITY
30
31#endif
diff --git a/shell/math.c b/shell/math.c
index fc20def62..76159b299 100644
--- a/shell/math.c
+++ b/shell/math.c
@@ -1,20 +1,17 @@
1/* 1/*
2 * arithmetic code ripped out of ash shell for code sharing 2 * arithmetic code ripped out of ash shell for code sharing
3 * 3 *
4 * This code is derived from software contributed to Berkeley by
5 * Kenneth Almquist.
6 *
7 * Original BSD copyright notice is retained at the end of this file.
8 *
4 * Copyright (c) 1989, 1991, 1993, 1994 9 * Copyright (c) 1989, 1991, 1993, 1994
5 * The Regents of the University of California. All rights reserved. 10 * The Regents of the University of California. All rights reserved.
6 * 11 *
7 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au> 12 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
8 * was re-ported from NetBSD and debianized. 13 * was re-ported from NetBSD and debianized.
9 * 14 *
10 * This code is derived from software contributed to Berkeley by
11 * Kenneth Almquist.
12 *
13 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
14 *
15 * Original BSD copyright notice is retained at the end of this file.
16 */
17/*
18 * rewrite arith.y to micro stack based cryptic algorithm by 15 * rewrite arith.y to micro stack based cryptic algorithm by
19 * Copyright (c) 2001 Aaron Lehmann <aaronl@vitelus.com> 16 * Copyright (c) 2001 Aaron Lehmann <aaronl@vitelus.com>
20 * 17 *
@@ -25,6 +22,8 @@
25 * used in busybox and size optimizations, 22 * used in busybox and size optimizations,
26 * rewrote arith (see notes to this), added locale support, 23 * rewrote arith (see notes to this), added locale support,
27 * rewrote dynamic variables. 24 * rewrote dynamic variables.
25 *
26 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
28 */ 27 */
29#include "libbb.h" 28#include "libbb.h"
30#include "math.h" 29#include "math.h"
diff --git a/shell/random.h b/shell/random.h
index e22a2e88b..08563402c 100644
--- a/shell/random.h
+++ b/shell/random.h
@@ -6,6 +6,10 @@
6 * 6 *
7 * Licensed under GPLv2, see file LICENSE in this tarball for details. 7 * Licensed under GPLv2, see file LICENSE in this tarball for details.
8 */ 8 */
9#ifndef SHELL_RANDOM_H
10#define SHELL_RANDOM_H 1
11
12PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
9 13
10typedef struct random_t { 14typedef struct random_t {
11 /* Random number generators */ 15 /* Random number generators */
@@ -23,3 +27,7 @@ typedef struct random_t {
23 ((rnd)->galois_LFSR = 0) 27 ((rnd)->galois_LFSR = 0)
24 28
25uint32_t next_random(random_t *rnd) FAST_FUNC; 29uint32_t next_random(random_t *rnd) FAST_FUNC;
30
31POP_SAVED_FUNCTION_VISIBILITY
32
33#endif
diff --git a/shell/shell_common.c b/shell/shell_common.c
new file mode 100644
index 000000000..99bb91c6f
--- /dev/null
+++ b/shell/shell_common.c
@@ -0,0 +1,26 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Adapted from ash applet code
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kenneth Almquist.
7 *
8 * Copyright (c) 1989, 1991, 1993, 1994
9 * The Regents of the University of California. All rights reserved.
10 *
11 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
12 * was re-ported from NetBSD and debianized.
13 *
14 * Copyright (c) 2010 Denys Vlasenko
15 * Split from ash.c
16 *
17 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
18 */
19#include "libbb.h"
20#include "shell_common.h"
21
22#if IFS_BROKEN
23const char defifsvar[] ALIGN1 = "IFS= \t\n";
24#else
25const char defifs[] ALIGN1 = " \t\n";
26#endif
diff --git a/shell/shell_common.h b/shell/shell_common.h
new file mode 100644
index 000000000..a9e9a2239
--- /dev/null
+++ b/shell/shell_common.h
@@ -0,0 +1,35 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Adapted from ash applet code
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kenneth Almquist.
7 *
8 * Copyright (c) 1989, 1991, 1993, 1994
9 * The Regents of the University of California. All rights reserved.
10 *
11 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
12 * was re-ported from NetBSD and debianized.
13 *
14 * Copyright (c) 2010 Denys Vlasenko
15 * Split from ash.c
16 *
17 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
18 */
19#ifndef SHELL_COMMON_H
20#define SHELL_COMMON_H 1
21
22PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
23
24#define IFS_BROKEN 1
25
26#if IFS_BROKEN
27extern const char defifsvar[]; /* "IFS= \t\n" */
28#define defifs (defifsvar + 4)
29#else
30extern const char defifs[]; /* " \t\n" */
31#endif
32
33POP_SAVED_FUNCTION_VISIBILITY
34
35#endif