aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2020-02-25 10:06:11 +0000
committerRon Yorston <rmy@pobox.com>2020-02-25 10:06:11 +0000
commite2a5b8e5e936891142cb630d145e67882711fd13 (patch)
tree94f685ed6e14582e7d0dfd140699082315f959f4 /shell/ash.c
parent35da75bde8885d1922701a36baa61bc8b01f14d4 (diff)
parentc2058ec98cf3f6722be4436cae07a386e3c7b48d (diff)
downloadbusybox-w32-e2a5b8e5e936891142cb630d145e67882711fd13.tar.gz
busybox-w32-e2a5b8e5e936891142cb630d145e67882711fd13.tar.bz2
busybox-w32-e2a5b8e5e936891142cb630d145e67882711fd13.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c110
1 files changed, 56 insertions, 54 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 252061dae..690796740 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -1842,15 +1842,16 @@ popstackmark(struct stackmark *mark)
1842 * part of the block that has been used. 1842 * part of the block that has been used.
1843 */ 1843 */
1844static void 1844static void
1845growstackblock(void) 1845growstackblock(size_t min)
1846{ 1846{
1847 size_t newlen; 1847 size_t newlen;
1848 1848
1849 newlen = g_stacknleft * 2; 1849 newlen = g_stacknleft * 2;
1850 if (newlen < g_stacknleft) 1850 if (newlen < g_stacknleft)
1851 ash_msg_and_raise_error(bb_msg_memory_exhausted); 1851 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1852 if (newlen < 128) 1852 min = SHELL_ALIGN(min | 128);
1853 newlen += 128; 1853 if (newlen < min)
1854 newlen += min;
1854 1855
1855 if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) { 1856 if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) {
1856 struct stack_block *sp; 1857 struct stack_block *sp;
@@ -1900,16 +1901,15 @@ static void *
1900growstackstr(void) 1901growstackstr(void)
1901{ 1902{
1902 size_t len = stackblocksize(); 1903 size_t len = stackblocksize();
1903 growstackblock(); 1904 growstackblock(0);
1904 return (char *)stackblock() + len; 1905 return (char *)stackblock() + len;
1905} 1906}
1906 1907
1907static char * 1908static char *
1908growstackto(size_t len) 1909growstackto(size_t len)
1909{ 1910{
1910 while (stackblocksize() < len) 1911 if (stackblocksize() < len)
1911 growstackblock(); 1912 growstackblock(len);
1912
1913 return stackblock(); 1913 return stackblock();
1914} 1914}
1915 1915
@@ -5962,29 +5962,36 @@ stoppedjobs(void)
5962 * the pipe without forking. 5962 * the pipe without forking.
5963 */ 5963 */
5964/* openhere needs this forward reference */ 5964/* openhere needs this forward reference */
5965static void expandhere(union node *arg, int fd); 5965static void expandhere(union node *arg);
5966static int 5966static int
5967openhere(union node *redir) 5967openhere(union node *redir)
5968{ 5968{
5969 char *p;
5969 int pip[2]; 5970 int pip[2];
5970 size_t len = 0; 5971 size_t len = 0;
5971 IF_PLATFORM_MINGW32(struct forkshell fs); 5972 IF_PLATFORM_MINGW32(struct forkshell fs);
5972 5973
5973 if (pipe(pip) < 0) 5974 if (pipe(pip) < 0)
5974 ash_msg_and_raise_perror("can't create pipe"); 5975 ash_msg_and_raise_perror("can't create pipe");
5975 if (redir->type == NHERE) { 5976
5976 len = strlen(redir->nhere.doc->narg.text); 5977 p = redir->nhere.doc->narg.text;
5977 if (len <= PIPE_BUF) { 5978 if (redir->type == NXHERE) {
5978 full_write(pip[1], redir->nhere.doc->narg.text, len); 5979 expandhere(redir->nhere.doc);
5979 goto out; 5980 p = stackblock();
5980 }
5981 } 5981 }
5982
5983 len = strlen(p);
5984 if (len <= PIPE_BUF) {
5985 xwrite(pip[1], p, len);
5986 goto out;
5987 }
5988
5982#if ENABLE_PLATFORM_MINGW32 5989#if ENABLE_PLATFORM_MINGW32
5983 memset(&fs, 0, sizeof(fs)); 5990 memset(&fs, 0, sizeof(fs));
5984 fs.fpid = FS_OPENHERE; 5991 fs.fpid = FS_OPENHERE;
5985 fs.n = redir;
5986 fs.fd[0] = pip[0]; 5992 fs.fd[0] = pip[0];
5987 fs.fd[1] = pip[1]; 5993 fs.fd[1] = pip[1];
5994 fs.path = p;
5988 spawn_forkshell(&fs, NULL, NULL, FORK_NOJOB); 5995 spawn_forkshell(&fs, NULL, NULL, FORK_NOJOB);
5989#else 5996#else
5990 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { 5997 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
@@ -5995,10 +6002,7 @@ openhere(union node *redir)
5995 ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN); 6002 ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN);
5996 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN); 6003 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
5997 signal(SIGPIPE, SIG_DFL); 6004 signal(SIGPIPE, SIG_DFL);
5998 if (redir->type == NHERE) 6005 xwrite(pip[1], p, len);
5999 full_write(pip[1], redir->nhere.doc->narg.text, len);
6000 else /* NXHERE */
6001 expandhere(redir->nhere.doc, pip[1]);
6002 _exit(EXIT_SUCCESS); 6006 _exit(EXIT_SUCCESS);
6003 } 6007 }
6004#endif 6008#endif
@@ -6602,26 +6606,6 @@ static struct ifsregion *ifslastp;
6602static struct arglist exparg; 6606static struct arglist exparg;
6603 6607
6604/* 6608/*
6605 * Our own itoa().
6606 * cvtnum() is used even if math support is off (to prepare $? values and such).
6607 */
6608static int
6609cvtnum(arith_t num)
6610{
6611 int len;
6612
6613 /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
6614 len = sizeof(arith_t) * 3;
6615 /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
6616 if (sizeof(arith_t) < 4) len += 2;
6617
6618 expdest = makestrspace(len, expdest);
6619 len = fmtstr(expdest, len, ARITH_FMT, num);
6620 STADJUST(len, expdest);
6621 return len;
6622}
6623
6624/*
6625 * Break the argument string into pieces based upon IFS and add the 6609 * Break the argument string into pieces based upon IFS and add the
6626 * strings to the argument list. The regions of the string to be 6610 * strings to the argument list. The regions of the string to be
6627 * searched for IFS characters have been stored by recordregion. 6611 * searched for IFS characters have been stored by recordregion.
@@ -6878,16 +6862,18 @@ preglob(const char *pattern, int flag)
6878/* 6862/*
6879 * Put a string on the stack. 6863 * Put a string on the stack.
6880 */ 6864 */
6881static void 6865static size_t
6882memtodest(const char *p, size_t len, int flags) 6866memtodest(const char *p, size_t len, int flags)
6883{ 6867{
6884 int syntax = flags & EXP_QUOTED ? DQSYNTAX : BASESYNTAX; 6868 int syntax = flags & EXP_QUOTED ? DQSYNTAX : BASESYNTAX;
6885 char *q; 6869 char *q;
6870 char *s;
6886 6871
6887 if (!len) 6872 if (!len)
6888 return; 6873 return 0;
6889 6874
6890 q = makestrspace(len * 2, expdest); 6875 q = makestrspace(len * 2, expdest);
6876 s = q;
6891 6877
6892 do { 6878 do {
6893 unsigned char c = *p++; 6879 unsigned char c = *p++;
@@ -6906,6 +6892,7 @@ memtodest(const char *p, size_t len, int flags)
6906 } while (--len); 6892 } while (--len);
6907 6893
6908 expdest = q; 6894 expdest = q;
6895 return q - s;
6909} 6896}
6910 6897
6911static size_t 6898static size_t
@@ -6917,6 +6904,22 @@ strtodest(const char *p, int flags)
6917} 6904}
6918 6905
6919/* 6906/*
6907 * Our own itoa().
6908 * cvtnum() is used even if math support is off (to prepare $? values and such).
6909 */
6910static int
6911cvtnum(arith_t num, int flags)
6912{
6913 /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
6914 /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
6915 int len = (sizeof(arith_t) >= 4) ? sizeof(arith_t) * 3 : sizeof(arith_t) * 3 + 2;
6916 char buf[len];
6917
6918 len = fmtstr(buf, len, ARITH_FMT, num);
6919 return memtodest(buf, len, flags);
6920}
6921
6922/*
6920 * Record the fact that we have to scan this region of the 6923 * Record the fact that we have to scan this region of the
6921 * string for IFS characters. 6924 * string for IFS characters.
6922 */ 6925 */
@@ -7225,7 +7228,7 @@ expari(int flag)
7225 if (flag & QUOTES_ESC) 7228 if (flag & QUOTES_ESC)
7226 rmescapes(p + 1, 0, NULL); 7229 rmescapes(p + 1, 0, NULL);
7227 7230
7228 len = cvtnum(ash_arith(p + 1)); 7231 len = cvtnum(ash_arith(p + 1), flag);
7229 7232
7230 if (!(flag & EXP_QUOTED)) 7233 if (!(flag & EXP_QUOTED))
7231 recordregion(begoff, begoff + len, 0); 7234 recordregion(begoff, begoff + len, 0);
@@ -7870,7 +7873,7 @@ varvalue(char *name, int varflags, int flags, int quoted)
7870 if (num == 0) 7873 if (num == 0)
7871 return -1; 7874 return -1;
7872 numvar: 7875 numvar:
7873 len = cvtnum(num); 7876 len = cvtnum(num, flags);
7874 goto check_1char_name; 7877 goto check_1char_name;
7875 case '-': 7878 case '-':
7876 expdest = makestrspace(NOPTS, expdest); 7879 expdest = makestrspace(NOPTS, expdest);
@@ -8036,7 +8039,7 @@ evalvar(char *p, int flag)
8036 varunset(p, var, 0, 0); 8039 varunset(p, var, 0, 0);
8037 8040
8038 if (subtype == VSLENGTH) { 8041 if (subtype == VSLENGTH) {
8039 cvtnum(varlen > 0 ? varlen : 0); 8042 cvtnum(varlen > 0 ? varlen : 0, flag);
8040 goto record; 8043 goto record;
8041 } 8044 }
8042 8045
@@ -8567,10 +8570,9 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
8567 * Expand shell variables and backquotes inside a here document. 8570 * Expand shell variables and backquotes inside a here document.
8568 */ 8571 */
8569static void 8572static void
8570expandhere(union node *arg, int fd) 8573expandhere(union node *arg)
8571{ 8574{
8572 expandarg(arg, (struct arglist *)NULL, EXP_QUOTED); 8575 expandarg(arg, (struct arglist *)NULL, EXP_QUOTED);
8573 full_write(fd, stackblock(), expdest - (char *)stackblock());
8574} 8576}
8575 8577
8576/* 8578/*
@@ -12331,7 +12333,7 @@ list(int nlflag)
12331 12333
12332 n1 = NULL; 12334 n1 = NULL;
12333 for (;;) { 12335 for (;;) {
12334 switch (peektoken()) { 12336 switch (readtoken()) {
12335 case TNL: 12337 case TNL:
12336 if (!(nlflag & 1)) 12338 if (!(nlflag & 1))
12337 break; 12339 break;
@@ -12342,9 +12344,12 @@ list(int nlflag)
12342 if (!n1 && (nlflag & 1)) 12344 if (!n1 && (nlflag & 1))
12343 n1 = NODE_EOF; 12345 n1 = NODE_EOF;
12344 parseheredoc(); 12346 parseheredoc();
12347 tokpushback++;
12348 lasttoken = TEOF;
12345 return n1; 12349 return n1;
12346 } 12350 }
12347 12351
12352 tokpushback++;
12348 checkkwd = CHKNL | CHKKWD | CHKALIAS; 12353 checkkwd = CHKNL | CHKKWD | CHKALIAS;
12349 if (nlflag == 2 && ((1 << peektoken()) & tokendlist)) 12354 if (nlflag == 2 && ((1 << peektoken()) & tokendlist))
12350 return n1; 12355 return n1;
@@ -13601,9 +13606,9 @@ parsebackq: {
13601 if (readtoken() != TRP) 13606 if (readtoken() != TRP)
13602 raise_error_unexpected_syntax(TRP); 13607 raise_error_unexpected_syntax(TRP);
13603 setinputstring(nullstr); 13608 setinputstring(nullstr);
13604 parseheredoc();
13605 } 13609 }
13606 13610
13611 parseheredoc();
13607 heredoclist = saveheredoclist; 13612 heredoclist = saveheredoclist;
13608 13613
13609 (*nlpp)->n = n; 13614 (*nlpp)->n = n;
@@ -15473,7 +15478,8 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
15473static void 15478static void
15474forkshell_openhere(struct forkshell *fs) 15479forkshell_openhere(struct forkshell *fs)
15475{ 15480{
15476 union node *redir = fs->n; 15481 const char *p = fs->path;
15482 size_t len = strlen(p);
15477 int pip[2]; 15483 int pip[2];
15478 15484
15479 pip[0] = fs->fd[0]; 15485 pip[0] = fs->fd[0];
@@ -15487,11 +15493,7 @@ forkshell_openhere(struct forkshell *fs)
15487 ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN); 15493 ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN);
15488 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN); 15494 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
15489 signal(SIGPIPE, SIG_DFL); 15495 signal(SIGPIPE, SIG_DFL);
15490 if (redir->type == NHERE) { 15496 xwrite(pip[1], p, len);
15491 size_t len = strlen(redir->nhere.doc->narg.text);
15492 full_write(pip[1], redir->nhere.doc->narg.text, len);
15493 } else /* NXHERE */
15494 expandhere(redir->nhere.doc, pip[1]);
15495 _exit(EXIT_SUCCESS); 15497 _exit(EXIT_SUCCESS);
15496} 15498}
15497 15499