diff options
author | Ron Yorston <rmy@pobox.com> | 2020-02-25 10:06:11 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2020-02-25 10:06:11 +0000 |
commit | e2a5b8e5e936891142cb630d145e67882711fd13 (patch) | |
tree | 94f685ed6e14582e7d0dfd140699082315f959f4 /shell/ash.c | |
parent | 35da75bde8885d1922701a36baa61bc8b01f14d4 (diff) | |
parent | c2058ec98cf3f6722be4436cae07a386e3c7b48d (diff) | |
download | busybox-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.c | 110 |
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 | */ |
1844 | static void | 1844 | static void |
1845 | growstackblock(void) | 1845 | growstackblock(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 * | |||
1900 | growstackstr(void) | 1901 | growstackstr(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 | ||
1907 | static char * | 1908 | static char * |
1908 | growstackto(size_t len) | 1909 | growstackto(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 */ |
5965 | static void expandhere(union node *arg, int fd); | 5965 | static void expandhere(union node *arg); |
5966 | static int | 5966 | static int |
5967 | openhere(union node *redir) | 5967 | openhere(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; | |||
6602 | static struct arglist exparg; | 6606 | static 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 | */ | ||
6608 | static int | ||
6609 | cvtnum(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 | */ |
6881 | static void | 6865 | static size_t |
6882 | memtodest(const char *p, size_t len, int flags) | 6866 | memtodest(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 | ||
6911 | static size_t | 6898 | static 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 | */ | ||
6910 | static int | ||
6911 | cvtnum(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 | */ |
8569 | static void | 8572 | static void |
8570 | expandhere(union node *arg, int fd) | 8573 | expandhere(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) | |||
15473 | static void | 15478 | static void |
15474 | forkshell_openhere(struct forkshell *fs) | 15479 | forkshell_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 | ||