aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2014-04-29 20:25:23 +0100
committerRon Yorston <rmy@pobox.com>2014-04-29 20:25:23 +0100
commitd323477244a4d32eb1297d7a4329beab3e8c5e80 (patch)
tree8c61956105fe87a1ee2890d46800355993fada58 /shell
parent5286ae8711099897298d264ae830adabe9dcb998 (diff)
downloadbusybox-w32-d323477244a4d32eb1297d7a4329beab3e8c5e80.tar.gz
busybox-w32-d323477244a4d32eb1297d7a4329beab3e8c5e80.tar.bz2
busybox-w32-d323477244a4d32eb1297d7a4329beab3e8c5e80.zip
ash: tidy up MinGW forkshell
Move some MinGW-specific code into sections at the top and bottom of the file. Exclude some code that isn't used in the MinGW port.
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c249
1 files changed, 129 insertions, 120 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 3dc666fbb..0d88d4108 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -241,6 +241,24 @@ struct forkshell {
241 struct strlist *strlist; 241 struct strlist *strlist;
242 pid_t pid; 242 pid_t pid;
243}; 243};
244
245static void forkshell_openhere(struct forkshell *fs);
246static void forkshell_evalbackcmd(struct forkshell *fs);
247static void forkshell_evalsubshell(struct forkshell *fs);
248static void forkshell_evalpipe(struct forkshell *fs);
249static void forkshell_shellexec(struct forkshell *fs);
250
251static const forkpoint_fn forkpoints[] = {
252 forkshell_openhere,
253 forkshell_evalbackcmd,
254 forkshell_evalsubshell,
255 forkshell_evalpipe,
256 forkshell_shellexec,
257 NULL
258};
259
260static struct forkshell* forkshell_prepare(struct forkshell *fs);
261static void forkshell_init(const char *idstr);
244static void sticky_free(void *p); 262static void sticky_free(void *p);
245#define free(p) sticky_free(p) 263#define free(p) sticky_free(p)
246static int spawn_forkshell(struct job *jp, struct forkshell *fs, int mode); 264static int spawn_forkshell(struct job *jp, struct forkshell *fs, int mode);
@@ -3526,7 +3544,9 @@ struct job {
3526}; 3544};
3527 3545
3528static struct job *makejob(/*union node *,*/ int); 3546static struct job *makejob(/*union node *,*/ int);
3547#if !ENABLE_PLATFORM_MINGW32
3529static int forkshell(struct job *, union node *, int); 3548static int forkshell(struct job *, union node *, int);
3549#endif
3530static int waitforjob(struct job *); 3550static int waitforjob(struct job *);
3531 3551
3532#if !JOBS 3552#if !JOBS
@@ -4911,6 +4931,7 @@ commandtext(union node *n)
4911 * 4931 *
4912 * Called with interrupts off. 4932 * Called with interrupts off.
4913 */ 4933 */
4934#if !ENABLE_PLATFORM_MINGW32
4914/* 4935/*
4915 * Clear traps on a fork. 4936 * Clear traps on a fork.
4916 */ 4937 */
@@ -5059,6 +5080,7 @@ forkchild(struct job *jp, union node *n, int mode)
5059 freejob(jp); 5080 freejob(jp);
5060 jobless = 0; 5081 jobless = 0;
5061} 5082}
5083#endif
5062 5084
5063/* Called after fork(), in parent */ 5085/* Called after fork(), in parent */
5064#if !JOBS 5086#if !JOBS
@@ -5102,14 +5124,13 @@ forkparent(struct job *jp, union node *n, int mode, pid_t pid)
5102 } 5124 }
5103} 5125}
5104 5126
5127#if !ENABLE_PLATFORM_MINGW32
5105static int 5128static int
5106forkshell(struct job *jp, union node *n, int mode) 5129forkshell(struct job *jp, union node *n, int mode)
5107{ 5130{
5108 int pid; 5131 int pid;
5109 5132
5110 TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode)); 5133 TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode));
5111 if (ENABLE_PLATFORM_MINGW32)
5112 return -1;
5113 5134
5114 pid = fork(); 5135 pid = fork();
5115 if (pid < 0) { 5136 if (pid < 0) {
@@ -5126,6 +5147,7 @@ forkshell(struct job *jp, union node *n, int mode)
5126 } 5147 }
5127 return pid; 5148 return pid;
5128} 5149}
5150#endif
5129 5151
5130/* 5152/*
5131 * Wait for job to finish. 5153 * Wait for job to finish.
@@ -5313,33 +5335,6 @@ noclobberopen(const char *fname)
5313 */ 5335 */
5314/* openhere needs this forward reference */ 5336/* openhere needs this forward reference */
5315static void expandhere(union node *arg, int fd); 5337static void expandhere(union node *arg, int fd);
5316#if ENABLE_PLATFORM_MINGW32
5317static void
5318forkshell_openhere(struct forkshell *fs)
5319{
5320 union node *redir = fs->n;
5321 int pip[2];
5322
5323 pip[0] = fs->fd[0];
5324 pip[1] = fs->fd[1];
5325
5326 TRACE(("ash: subshell: %s\n",__PRETTY_FUNCTION__));
5327
5328 close(pip[0]);
5329 ignoresig(SIGINT); //signal(SIGINT, SIG_IGN);
5330 ignoresig(SIGQUIT); //signal(SIGQUIT, SIG_IGN);
5331 ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN);
5332 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
5333 signal(SIGPIPE, SIG_DFL);
5334 if (redir->type == NHERE) {
5335 size_t len = strlen(redir->nhere.doc->narg.text);
5336 full_write(pip[1], redir->nhere.doc->narg.text, len);
5337 } else /* NXHERE */
5338 expandhere(redir->nhere.doc, pip[1]);
5339 _exit(EXIT_SUCCESS);
5340}
5341#endif
5342
5343static int 5338static int
5344openhere(union node *redir) 5339openhere(union node *redir)
5345{ 5340{
@@ -5365,7 +5360,7 @@ openhere(union node *redir)
5365 fs.fd[1] = pip[1]; 5360 fs.fd[1] = pip[1];
5366 if (spawn_forkshell(NULL, &fs, FORK_NOJOB) < 0) 5361 if (spawn_forkshell(NULL, &fs, FORK_NOJOB) < 0)
5367 ash_msg_and_raise_error("unable to spawn shell"); 5362 ash_msg_and_raise_error("unable to spawn shell");
5368#endif 5363#else
5369 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { 5364 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
5370 /* child */ 5365 /* child */
5371 close(pip[0]); 5366 close(pip[0]);
@@ -5380,6 +5375,7 @@ openhere(union node *redir)
5380 expandhere(redir->nhere.doc, pip[1]); 5375 expandhere(redir->nhere.doc, pip[1]);
5381 _exit(EXIT_SUCCESS); 5376 _exit(EXIT_SUCCESS);
5382 } 5377 }
5378#endif
5383 out: 5379 out:
5384 close(pip[1]); 5380 close(pip[1]);
5385 return pip[0]; 5381 return pip[0];
@@ -6150,25 +6146,6 @@ static uint8_t back_exitstatus; /* exit status of backquoted command */
6150#define EV_EXIT 01 /* exit after evaluating tree */ 6146#define EV_EXIT 01 /* exit after evaluating tree */
6151static void evaltree(union node *, int); 6147static void evaltree(union node *, int);
6152 6148
6153#if ENABLE_PLATFORM_MINGW32
6154static void
6155forkshell_evalbackcmd(struct forkshell *fs)
6156{
6157 union node *n = fs->n;
6158 int pip[2] = {fs->fd[0], fs->fd[1]};
6159
6160 FORCE_INT_ON;
6161 close(pip[0]);
6162 if (pip[1] != 1) {
6163 /*close(1);*/
6164 copyfd(pip[1], 1 | COPYFD_EXACT);
6165 close(pip[1]);
6166 }
6167 eflag = 0;
6168 evaltree(n, EV_EXIT); /* actually evaltreenr... */
6169 /* NOTREACHED */
6170}
6171#endif
6172static void FAST_FUNC 6149static void FAST_FUNC
6173evalbackcmd(union node *n, struct backcmd *result) 6150evalbackcmd(union node *n, struct backcmd *result)
6174{ 6151{
@@ -6199,7 +6176,7 @@ evalbackcmd(union node *n, struct backcmd *result)
6199 result->fs.fd[1] = pip[1]; 6176 result->fs.fd[1] = pip[1];
6200 if (spawn_forkshell(jp, &result->fs, FORK_NOJOB) < 0) 6177 if (spawn_forkshell(jp, &result->fs, FORK_NOJOB) < 0)
6201 ash_msg_and_raise_error("unable to spawn shell"); 6178 ash_msg_and_raise_error("unable to spawn shell");
6202#endif 6179#else
6203 if (forkshell(jp, n, FORK_NOJOB) == 0) { 6180 if (forkshell(jp, n, FORK_NOJOB) == 0) {
6204 FORCE_INT_ON; 6181 FORCE_INT_ON;
6205 close(pip[0]); 6182 close(pip[0]);
@@ -6212,6 +6189,7 @@ evalbackcmd(union node *n, struct backcmd *result)
6212 evaltree(n, EV_EXIT); /* actually evaltreenr... */ 6189 evaltree(n, EV_EXIT); /* actually evaltreenr... */
6213 /* NOTREACHED */ 6190 /* NOTREACHED */
6214 } 6191 }
6192#endif
6215 close(pip[1]); 6193 close(pip[1]);
6216 result->fd = pip[0]; 6194 result->fd = pip[0];
6217 result->jp = jp; 6195 result->jp = jp;
@@ -9001,22 +8979,6 @@ evalcase(union node *n, int flags)
9001/* 8979/*
9002 * Kick off a subshell to evaluate a tree. 8980 * Kick off a subshell to evaluate a tree.
9003 */ 8981 */
9004#if ENABLE_PLATFORM_MINGW32
9005static void
9006forkshell_evalsubshell(struct forkshell *fs)
9007{
9008 union node *n = fs->n;
9009 int flags = fs->flags;
9010
9011 TRACE(("ash: subshell: %s\n",__PRETTY_FUNCTION__));
9012 INT_ON;
9013 flags |= EV_EXIT;
9014 expredir(n->nredir.redirect);
9015 redirect(n->nredir.redirect, 0);
9016 evaltreenr(n->nredir.n, flags);
9017 /* never returns */
9018}
9019#endif
9020static void 8982static void
9021evalsubshell(union node *n, int flags) 8983evalsubshell(union node *n, int flags)
9022{ 8984{
@@ -9037,13 +8999,15 @@ evalsubshell(union node *n, int flags)
9037 fs.flags = flags; 8999 fs.flags = flags;
9038 if (spawn_forkshell(jp, &fs, backgnd) < 0) 9000 if (spawn_forkshell(jp, &fs, backgnd) < 0)
9039 ash_msg_and_raise_error("unable to spawn shell"); 9001 ash_msg_and_raise_error("unable to spawn shell");
9040#endif 9002 if ( 0 ) {
9003#else
9041 if (forkshell(jp, n, backgnd) == 0) { 9004 if (forkshell(jp, n, backgnd) == 0) {
9042 /* child */ 9005 /* child */
9043 INT_ON; 9006 INT_ON;
9044 flags |= EV_EXIT; 9007 flags |= EV_EXIT;
9045 if (backgnd) 9008 if (backgnd)
9046 flags &= ~EV_TESTED; 9009 flags &= ~EV_TESTED;
9010#endif
9047 nofork: 9011 nofork:
9048 redirect(n->nredir.redirect, 0); 9012 redirect(n->nredir.redirect, 0);
9049 evaltreenr(n->nredir.n, flags); 9013 evaltreenr(n->nredir.n, flags);
@@ -9126,31 +9090,6 @@ expredir(union node *n)
9126 * of the shell, which make the last process in a pipeline the parent 9090 * of the shell, which make the last process in a pipeline the parent
9127 * of all the rest.) 9091 * of all the rest.)
9128 */ 9092 */
9129#if ENABLE_PLATFORM_MINGW32
9130static void
9131forkshell_evalpipe(struct forkshell *fs)
9132{
9133 union node *n = fs->n;
9134 int flags = fs->flags;
9135 int prevfd = fs->fd[2];
9136 int pip[2] = {fs->fd[0], fs->fd[1]};
9137
9138 TRACE(("ash: subshell: %s\n",__PRETTY_FUNCTION__));
9139 INT_ON;
9140 if (pip[1] >= 0) {
9141 close(pip[0]);
9142 }
9143 if (prevfd > 0) {
9144 dup2(prevfd, 0);
9145 close(prevfd);
9146 }
9147 if (pip[1] > 1) {
9148 dup2(pip[1], 1);
9149 close(pip[1]);
9150 }
9151 evaltreenr(n, flags);
9152}
9153#endif
9154static void 9093static void
9155evalpipe(union node *n, int flags) 9094evalpipe(union node *n, int flags)
9156{ 9095{
@@ -9188,7 +9127,7 @@ evalpipe(union node *n, int flags)
9188 fs.fd[2] = prevfd; 9127 fs.fd[2] = prevfd;
9189 if (spawn_forkshell(jp, &fs, n->npipe.pipe_backgnd) < 0) 9128 if (spawn_forkshell(jp, &fs, n->npipe.pipe_backgnd) < 0)
9190 ash_msg_and_raise_error("unable to spawn shell"); 9129 ash_msg_and_raise_error("unable to spawn shell");
9191#endif 9130#else
9192 if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) { 9131 if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) {
9193 INT_ON; 9132 INT_ON;
9194 if (pip[1] >= 0) { 9133 if (pip[1] >= 0) {
@@ -9205,6 +9144,7 @@ evalpipe(union node *n, int flags)
9205 evaltreenr(lp->n, flags); 9144 evaltreenr(lp->n, flags);
9206 /* never returns */ 9145 /* never returns */
9207 } 9146 }
9147#endif
9208 if (prevfd >= 0) 9148 if (prevfd >= 0)
9209 close(prevfd); 9149 close(prevfd);
9210 prevfd = pip[0]; 9150 prevfd = pip[0];
@@ -9664,19 +9604,6 @@ bltincmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9664 return back_exitstatus; 9604 return back_exitstatus;
9665} 9605}
9666 9606
9667#if ENABLE_PLATFORM_MINGW32
9668static void
9669forkshell_shellexec(struct forkshell *fs)
9670{
9671 int idx = fs->fd[0];
9672 struct strlist *varlist = fs->strlist;
9673 char **argv = fs->argv;
9674 char *path = fs->string;
9675
9676 listsetvar(varlist, VEXPORT|VSTACK);
9677 shellexec(argv, path, idx);
9678}
9679#endif
9680static void 9607static void
9681evalcommand(union node *cmd, int flags) 9608evalcommand(union node *cmd, int flags)
9682{ 9609{
@@ -10444,6 +10371,7 @@ popallfiles(void)
10444 popfile(); 10371 popfile();
10445} 10372}
10446 10373
10374#if !ENABLE_PLATFORM_MINGW32
10447/* 10375/*
10448 * Close the file(s) that the shell is reading commands from. Called 10376 * Close the file(s) that the shell is reading commands from. Called
10449 * after a fork is done. 10377 * after a fork is done.
@@ -10457,6 +10385,7 @@ closescript(void)
10457 g_parsefile->pf_fd = 0; 10385 g_parsefile->pf_fd = 0;
10458 } 10386 }
10459} 10387}
10388#endif
10460 10389
10461/* 10390/*
10462 * Like setinputfile, but takes an open file descriptor. Call this with 10391 * Like setinputfile, but takes an open file descriptor. Call this with
@@ -13735,20 +13664,6 @@ static short profile_buf[16384];
13735extern int etext(); 13664extern int etext();
13736#endif 13665#endif
13737 13666
13738#if ENABLE_PLATFORM_MINGW32
13739static const forkpoint_fn forkpoints[] = {
13740 forkshell_openhere,
13741 forkshell_evalbackcmd,
13742 forkshell_evalsubshell,
13743 forkshell_evalpipe,
13744 forkshell_shellexec,
13745 NULL
13746};
13747
13748static struct forkshell* forkshell_prepare(struct forkshell *fs);
13749static void forkshell_init(const char *idstr);
13750#endif
13751
13752/* 13667/*
13753 * Main routine. We initialize things, parse the arguments, execute 13668 * Main routine. We initialize things, parse the arguments, execute
13754 * profiles if we're a login shell, and then call cmdloop to execute 13669 * profiles if we're a login shell, and then call cmdloop to execute
@@ -13926,6 +13841,100 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
13926} 13841}
13927 13842
13928#if ENABLE_PLATFORM_MINGW32 13843#if ENABLE_PLATFORM_MINGW32
13844static void
13845forkshell_openhere(struct forkshell *fs)
13846{
13847 union node *redir = fs->n;
13848 int pip[2];
13849
13850 pip[0] = fs->fd[0];
13851 pip[1] = fs->fd[1];
13852
13853 TRACE(("ash: subshell: %s\n",__PRETTY_FUNCTION__));
13854
13855 close(pip[0]);
13856 ignoresig(SIGINT); //signal(SIGINT, SIG_IGN);
13857 ignoresig(SIGQUIT); //signal(SIGQUIT, SIG_IGN);
13858 ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN);
13859 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
13860 signal(SIGPIPE, SIG_DFL);
13861 if (redir->type == NHERE) {
13862 size_t len = strlen(redir->nhere.doc->narg.text);
13863 full_write(pip[1], redir->nhere.doc->narg.text, len);
13864 } else /* NXHERE */
13865 expandhere(redir->nhere.doc, pip[1]);
13866 _exit(EXIT_SUCCESS);
13867}
13868
13869static void
13870forkshell_evalbackcmd(struct forkshell *fs)
13871{
13872 union node *n = fs->n;
13873 int pip[2] = {fs->fd[0], fs->fd[1]};
13874
13875 FORCE_INT_ON;
13876 close(pip[0]);
13877 if (pip[1] != 1) {
13878 /*close(1);*/
13879 copyfd(pip[1], 1 | COPYFD_EXACT);
13880 close(pip[1]);
13881 }
13882 eflag = 0;
13883 evaltree(n, EV_EXIT); /* actually evaltreenr... */
13884 /* NOTREACHED */
13885}
13886
13887static void
13888forkshell_evalsubshell(struct forkshell *fs)
13889{
13890 union node *n = fs->n;
13891 int flags = fs->flags;
13892
13893 TRACE(("ash: subshell: %s\n",__PRETTY_FUNCTION__));
13894 INT_ON;
13895 flags |= EV_EXIT;
13896 expredir(n->nredir.redirect);
13897 redirect(n->nredir.redirect, 0);
13898 evaltreenr(n->nredir.n, flags);
13899 /* never returns */
13900}
13901
13902static void
13903forkshell_evalpipe(struct forkshell *fs)
13904{
13905 union node *n = fs->n;
13906 int flags = fs->flags;
13907 int prevfd = fs->fd[2];
13908 int pip[2] = {fs->fd[0], fs->fd[1]};
13909
13910 TRACE(("ash: subshell: %s\n",__PRETTY_FUNCTION__));
13911 INT_ON;
13912 if (pip[1] >= 0) {
13913 close(pip[0]);
13914 }
13915 if (prevfd > 0) {
13916 dup2(prevfd, 0);
13917 close(prevfd);
13918 }
13919 if (pip[1] > 1) {
13920 dup2(pip[1], 1);
13921 close(pip[1]);
13922 }
13923 evaltreenr(n, flags);
13924}
13925
13926static void
13927forkshell_shellexec(struct forkshell *fs)
13928{
13929 int idx = fs->fd[0];
13930 struct strlist *varlist = fs->strlist;
13931 char **argv = fs->argv;
13932 char *path = fs->string;
13933
13934 listsetvar(varlist, VEXPORT|VSTACK);
13935 shellexec(argv, path, idx);
13936}
13937
13929/* 13938/*
13930 * Reset the pointers to the builtin environment variables in the hash 13939 * Reset the pointers to the builtin environment variables in the hash
13931 * table to point to varinit rather than the bogus copy created during 13940 * table to point to varinit rather than the bogus copy created during