summaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-04-02 09:24:14 +0100
committerRon Yorston <rmy@pobox.com>2018-04-02 09:24:14 +0100
commit34a68d327b42c3c700e84cd475496985782290b1 (patch)
tree99bfe59cca420d26f01e81a7f41763f71b44d22c /shell/ash.c
parentaff3c5bd7b6bdcfb97f63153ab839c5f55f16a12 (diff)
parente84212f8346741a2d4a04b40639c44fe519cf5a7 (diff)
downloadbusybox-w32-34a68d327b42c3c700e84cd475496985782290b1.tar.gz
busybox-w32-34a68d327b42c3c700e84cd475496985782290b1.tar.bz2
busybox-w32-34a68d327b42c3c700e84cd475496985782290b1.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c102
1 files changed, 49 insertions, 53 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 2ab46576c..7448b668a 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -282,6 +282,12 @@ typedef long arith_t;
282# define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__ 282# define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
283#endif 283#endif
284 284
285#ifndef F_DUPFD_CLOEXEC
286# define F_DUPFD_CLOEXEC F_DUPFD
287#endif
288#ifndef O_CLOEXEC
289# define O_CLOEXEC 0
290#endif
285#ifndef PIPE_BUF 291#ifndef PIPE_BUF
286# define PIPE_BUF 4096 /* amount of buffering in a pipe */ 292# define PIPE_BUF 4096 /* amount of buffering in a pipe */
287#endif 293#endif
@@ -4196,12 +4202,13 @@ setjobctl(int on)
4196 goto out; 4202 goto out;
4197 } 4203 }
4198 /* fd is a tty at this point */ 4204 /* fd is a tty at this point */
4199 fd = fcntl(fd, F_DUPFD, 10); 4205 fd = fcntl(fd, F_DUPFD_CLOEXEC, 10);
4200 if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, don't */ 4206 if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, don't */
4201 close(ofd); 4207 close(ofd);
4202 if (fd < 0) 4208 if (fd < 0)
4203 goto out; /* F_DUPFD failed */ 4209 goto out; /* F_DUPFD failed */
4204 close_on_exec_on(fd); 4210 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
4211 close_on_exec_on(fd);
4205 while (1) { /* while we are in the background */ 4212 while (1) { /* while we are in the background */
4206 pgrp = tcgetpgrp(fd); 4213 pgrp = tcgetpgrp(fd);
4207 if (pgrp < 0) { 4214 if (pgrp < 0) {
@@ -5791,13 +5798,14 @@ savefd(int from)
5791 int newfd; 5798 int newfd;
5792 int err; 5799 int err;
5793 5800
5794 newfd = fcntl(from, F_DUPFD, 10); 5801 newfd = fcntl(from, F_DUPFD_CLOEXEC, 10);
5795 err = newfd < 0 ? errno : 0; 5802 err = newfd < 0 ? errno : 0;
5796 if (err != EBADF) { 5803 if (err != EBADF) {
5797 if (err) 5804 if (err)
5798 ash_msg_and_raise_perror("%d", from); 5805 ash_msg_and_raise_perror("%d", from);
5799 close(from); 5806 close(from);
5800 fcntl(newfd, F_SETFD, FD_CLOEXEC); 5807 if (F_DUPFD_CLOEXEC == F_DUPFD)
5808 close_on_exec_on(newfd);
5801 } 5809 }
5802 5810
5803 return newfd; 5811 return newfd;
@@ -5815,12 +5823,15 @@ dup2_or_raise(int from, int to)
5815 return newfd; 5823 return newfd;
5816} 5824}
5817static int 5825static int
5818fcntl_F_DUPFD(int fd, int avoid_fd) 5826dup_CLOEXEC(int fd, int avoid_fd)
5819{ 5827{
5820 int newfd; 5828 int newfd;
5821 repeat: 5829 repeat:
5822 newfd = fcntl(fd, F_DUPFD, avoid_fd + 1); 5830 newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
5823 if (newfd < 0) { 5831 if (newfd >= 0) {
5832 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
5833 close_on_exec_on(newfd);
5834 } else { /* newfd < 0 */
5824 if (errno == EBUSY) 5835 if (errno == EBUSY)
5825 goto repeat; 5836 goto repeat;
5826 if (errno == EINTR) 5837 if (errno == EINTR)
@@ -5833,7 +5844,7 @@ xdup_CLOEXEC_and_close(int fd, int avoid_fd)
5833{ 5844{
5834 int newfd; 5845 int newfd;
5835 repeat: 5846 repeat:
5836 newfd = fcntl(fd, F_DUPFD, avoid_fd + 1); 5847 newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
5837 if (newfd < 0) { 5848 if (newfd < 0) {
5838 if (errno == EBUSY) 5849 if (errno == EBUSY)
5839 goto repeat; 5850 goto repeat;
@@ -5844,7 +5855,8 @@ xdup_CLOEXEC_and_close(int fd, int avoid_fd)
5844 return fd; 5855 return fd;
5845 ash_msg_and_raise_perror("%d", newfd); 5856 ash_msg_and_raise_perror("%d", newfd);
5846 } 5857 }
5847 fcntl(newfd, F_SETFD, FD_CLOEXEC); 5858 if (F_DUPFD_CLOEXEC == F_DUPFD)
5859 close_on_exec_on(newfd);
5848 close(fd); 5860 close(fd);
5849 return newfd; 5861 return newfd;
5850} 5862}
@@ -5936,7 +5948,7 @@ save_fd_on_redirect(int fd, int avoid_fd, struct redirtab *sq)
5936 for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) { 5948 for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) {
5937 /* If we collide with an already moved fd... */ 5949 /* If we collide with an already moved fd... */
5938 if (fd == sq->two_fd[i].moved_to) { 5950 if (fd == sq->two_fd[i].moved_to) {
5939 new_fd = fcntl_F_DUPFD(fd, avoid_fd); 5951 new_fd = dup_CLOEXEC(fd, avoid_fd);
5940 sq->two_fd[i].moved_to = new_fd; 5952 sq->two_fd[i].moved_to = new_fd;
5941 TRACE(("redirect_fd %d: already busy, moving to %d\n", fd, new_fd)); 5953 TRACE(("redirect_fd %d: already busy, moving to %d\n", fd, new_fd));
5942 if (new_fd < 0) /* what? */ 5954 if (new_fd < 0) /* what? */
@@ -5951,7 +5963,7 @@ save_fd_on_redirect(int fd, int avoid_fd, struct redirtab *sq)
5951 } 5963 }
5952 5964
5953 /* If this fd is open, we move and remember it; if it's closed, new_fd = CLOSED (-1) */ 5965 /* If this fd is open, we move and remember it; if it's closed, new_fd = CLOSED (-1) */
5954 new_fd = fcntl_F_DUPFD(fd, avoid_fd); 5966 new_fd = dup_CLOEXEC(fd, avoid_fd);
5955 TRACE(("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, new_fd)); 5967 TRACE(("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, new_fd));
5956 if (new_fd < 0) { 5968 if (new_fd < 0) {
5957 if (errno != EBADF) 5969 if (errno != EBADF)
@@ -7559,7 +7571,7 @@ varvalue(char *name, int varflags, int flags, int *quotedp)
7559 case '-': 7571 case '-':
7560 expdest = makestrspace(NOPTS, expdest); 7572 expdest = makestrspace(NOPTS, expdest);
7561 for (i = NOPTS - 1; i >= 0; i--) { 7573 for (i = NOPTS - 1; i >= 0; i--) {
7562 if (optlist[i]) { 7574 if (optlist[i] && optletters(i)) {
7563 USTPUTC(optletters(i), expdest); 7575 USTPUTC(optletters(i), expdest);
7564 len++; 7576 len++;
7565 } 7577 }
@@ -7806,13 +7818,13 @@ hasmeta(const char *p)
7806 p = strpbrk(p, chars); 7818 p = strpbrk(p, chars);
7807 if (!p) 7819 if (!p)
7808 break; 7820 break;
7809 switch ((unsigned char) *p) { 7821 switch ((unsigned char)*p) {
7810 case CTLQUOTEMARK: 7822 case CTLQUOTEMARK:
7811 for (;;) { 7823 for (;;) {
7812 p++; 7824 p++;
7813 if (*p == CTLQUOTEMARK) 7825 if ((unsigned char)*p == CTLQUOTEMARK)
7814 break; 7826 break;
7815 if (*p == CTLESC) 7827 if ((unsigned char)*p == CTLESC)
7816 p++; 7828 p++;
7817 if (*p == '\0') /* huh? */ 7829 if (*p == '\0') /* huh? */
7818 return 0; 7830 return 0;
@@ -11262,7 +11274,7 @@ setinputfile(const char *fname, int flags)
11262 int fd; 11274 int fd;
11263 11275
11264 INT_OFF; 11276 INT_OFF;
11265 fd = open(fname, O_RDONLY); 11277 fd = open(fname, O_RDONLY | O_CLOEXEC);
11266 if (fd < 0) { 11278 if (fd < 0) {
11267 if (flags & INPUT_NOFILE_OK) 11279 if (flags & INPUT_NOFILE_OK)
11268 goto out; 11280 goto out;
@@ -11271,8 +11283,9 @@ setinputfile(const char *fname, int flags)
11271 } 11283 }
11272 if (fd < 10) 11284 if (fd < 10)
11273 fd = savefd(fd); 11285 fd = savefd(fd);
11274 else 11286 else if (O_CLOEXEC == 0) /* old libc */
11275 close_on_exec_on(fd); 11287 close_on_exec_on(fd);
11288
11276 setinputfd(fd, flags & INPUT_PUSH_FILE); 11289 setinputfd(fd, flags & INPUT_PUSH_FILE);
11277 out: 11290 out:
11278 INT_ON; 11291 INT_ON;
@@ -12595,6 +12608,12 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
12595 break; 12608 break;
12596#endif 12609#endif
12597 case CBQUOTE: /* '`' */ 12610 case CBQUOTE: /* '`' */
12611 if (checkkwd & CHKEOFMARK) {
12612 quotef = 1;
12613 USTPUTC('`', out);
12614 break;
12615 }
12616
12598 PARSEBACKQOLD(); 12617 PARSEBACKQOLD();
12599 break; 12618 break;
12600 case CENDFILE: 12619 case CENDFILE:
@@ -12727,7 +12746,7 @@ parseredir: {
12727 np = stzalloc(sizeof(struct nfile)); 12746 np = stzalloc(sizeof(struct nfile));
12728 if (c == '>') { 12747 if (c == '>') {
12729 np->nfile.fd = 1; 12748 np->nfile.fd = 1;
12730 c = pgetc(); 12749 c = pgetc_eatbnl();
12731 if (c == '>') 12750 if (c == '>')
12732 np->type = NAPPEND; 12751 np->type = NAPPEND;
12733 else if (c == '|') 12752 else if (c == '|')
@@ -12749,7 +12768,7 @@ parseredir: {
12749#endif 12768#endif
12750 else { /* c == '<' */ 12769 else { /* c == '<' */
12751 /*np->nfile.fd = 0; - stzalloc did it */ 12770 /*np->nfile.fd = 0; - stzalloc did it */
12752 c = pgetc(); 12771 c = pgetc_eatbnl();
12753 switch (c) { 12772 switch (c) {
12754 case '<': 12773 case '<':
12755 if (sizeof(struct nfile) != sizeof(struct nhere)) { 12774 if (sizeof(struct nfile) != sizeof(struct nhere)) {
@@ -12759,7 +12778,7 @@ parseredir: {
12759 np->type = NHERE; 12778 np->type = NHERE;
12760 heredoc = stzalloc(sizeof(struct heredoc)); 12779 heredoc = stzalloc(sizeof(struct heredoc));
12761 heredoc->here = np; 12780 heredoc->here = np;
12762 c = pgetc(); 12781 c = pgetc_eatbnl();
12763 if (c == '-') { 12782 if (c == '-') {
12764 heredoc->striptabs = 1; 12783 heredoc->striptabs = 1;
12765 } else { 12784 } else {
@@ -12989,23 +13008,13 @@ parsebackq: {
12989 int pc; 13008 int pc;
12990 13009
12991 setprompt_if(needprompt, 2); 13010 setprompt_if(needprompt, 2);
12992 pc = pgetc(); 13011 pc = pgetc_eatbnl();
12993 switch (pc) { 13012 switch (pc) {
12994 case '`': 13013 case '`':
12995 goto done; 13014 goto done;
12996 13015
12997 case '\\': 13016 case '\\':
12998 pc = pgetc(); 13017 pc = pgetc(); /* or pgetc_eatbnl()? why (example)? */
12999 if (pc == '\n') {
13000 nlprompt();
13001 /*
13002 * If eating a newline, avoid putting
13003 * the newline into the new character
13004 * stream (via the STPUTC after the
13005 * switch).
13006 */
13007 continue;
13008 }
13009 if (pc != '\\' && pc != '`' && pc != '$' 13018 if (pc != '\\' && pc != '`' && pc != '$'
13010 && (!dblquote || pc != '"') 13019 && (!dblquote || pc != '"')
13011 ) { 13020 ) {
@@ -13137,7 +13146,7 @@ xxreadtoken(void)
13137 } 13146 }
13138 setprompt_if(needprompt, 2); 13147 setprompt_if(needprompt, 2);
13139 for (;;) { /* until token or start of word found */ 13148 for (;;) { /* until token or start of word found */
13140 c = pgetc(); 13149 c = pgetc_eatbnl();
13141 if (c == ' ' || c == '\t' IF_ASH_ALIAS( || c == PEOA)) 13150 if (c == ' ' || c == '\t' IF_ASH_ALIAS( || c == PEOA))
13142 continue; 13151 continue;
13143 13152
@@ -13146,11 +13155,7 @@ xxreadtoken(void)
13146 continue; 13155 continue;
13147 pungetc(); 13156 pungetc();
13148 } else if (c == '\\') { 13157 } else if (c == '\\') {
13149 if (pgetc() != '\n') { 13158 break; /* return readtoken1(...) */
13150 pungetc();
13151 break; /* return readtoken1(...) */
13152 }
13153 nlprompt();
13154 } else { 13159 } else {
13155 const char *p; 13160 const char *p;
13156 13161
@@ -13165,7 +13170,7 @@ xxreadtoken(void)
13165 break; /* return readtoken1(...) */ 13170 break; /* return readtoken1(...) */
13166 13171
13167 if ((int)(p - xxreadtoken_chars) >= xxreadtoken_singles) { 13172 if ((int)(p - xxreadtoken_chars) >= xxreadtoken_singles) {
13168 int cc = pgetc(); 13173 int cc = pgetc_eatbnl();
13169 if (cc == c) { /* double occurrence? */ 13174 if (cc == c) { /* double occurrence? */
13170 p += xxreadtoken_doubles + 1; 13175 p += xxreadtoken_doubles + 1;
13171 } else { 13176 } else {
@@ -13197,7 +13202,7 @@ xxreadtoken(void)
13197 } 13202 }
13198 setprompt_if(needprompt, 2); 13203 setprompt_if(needprompt, 2);
13199 for (;;) { /* until token or start of word found */ 13204 for (;;) { /* until token or start of word found */
13200 c = pgetc(); 13205 c = pgetc_eatbnl();
13201 switch (c) { 13206 switch (c) {
13202 case ' ': case '\t': 13207 case ' ': case '\t':
13203 IF_ASH_ALIAS(case PEOA:) 13208 IF_ASH_ALIAS(case PEOA:)
@@ -13207,30 +13212,23 @@ xxreadtoken(void)
13207 continue; 13212 continue;
13208 pungetc(); 13213 pungetc();
13209 continue; 13214 continue;
13210 case '\\':
13211 if (pgetc() == '\n') {
13212 nlprompt();
13213 continue;
13214 }
13215 pungetc();
13216 goto breakloop;
13217 case '\n': 13215 case '\n':
13218 nlnoprompt(); 13216 nlnoprompt();
13219 RETURN(TNL); 13217 RETURN(TNL);
13220 case PEOF: 13218 case PEOF:
13221 RETURN(TEOF); 13219 RETURN(TEOF);
13222 case '&': 13220 case '&':
13223 if (pgetc() == '&') 13221 if (pgetc_eatbnl() == '&')
13224 RETURN(TAND); 13222 RETURN(TAND);
13225 pungetc(); 13223 pungetc();
13226 RETURN(TBACKGND); 13224 RETURN(TBACKGND);
13227 case '|': 13225 case '|':
13228 if (pgetc() == '|') 13226 if (pgetc_eatbnl() == '|')
13229 RETURN(TOR); 13227 RETURN(TOR);
13230 pungetc(); 13228 pungetc();
13231 RETURN(TPIPE); 13229 RETURN(TPIPE);
13232 case ';': 13230 case ';':
13233 if (pgetc() == ';') 13231 if (pgetc_eatbnl() == ';')
13234 RETURN(TENDCASE); 13232 RETURN(TENDCASE);
13235 pungetc(); 13233 pungetc();
13236 RETURN(TSEMI); 13234 RETURN(TSEMI);
@@ -13238,11 +13236,9 @@ xxreadtoken(void)
13238 RETURN(TLP); 13236 RETURN(TLP);
13239 case ')': 13237 case ')':
13240 RETURN(TRP); 13238 RETURN(TRP);
13241 default:
13242 goto breakloop;
13243 } 13239 }
13240 break;
13244 } 13241 }
13245 breakloop:
13246 return readtoken1(c, BASESYNTAX, (char *)NULL, 0); 13242 return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
13247#undef RETURN 13243#undef RETURN
13248} 13244}