diff options
-rw-r--r-- | configs/mingw32_defconfig | 2 | ||||
-rw-r--r-- | configs/mingw64_defconfig | 2 | ||||
-rw-r--r-- | shell/ash.c | 51 |
3 files changed, 44 insertions, 11 deletions
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig index 195020151..d41899fdc 100644 --- a/configs/mingw32_defconfig +++ b/configs/mingw32_defconfig | |||
@@ -1131,7 +1131,7 @@ CONFIG_ASH_INTERNAL_GLOB=y | |||
1131 | CONFIG_ASH_BASH_COMPAT=y | 1131 | CONFIG_ASH_BASH_COMPAT=y |
1132 | # CONFIG_ASH_BASH_SOURCE_CURDIR is not set | 1132 | # CONFIG_ASH_BASH_SOURCE_CURDIR is not set |
1133 | CONFIG_ASH_BASH_NOT_FOUND_HOOK=y | 1133 | CONFIG_ASH_BASH_NOT_FOUND_HOOK=y |
1134 | # CONFIG_ASH_JOB_CONTROL is not set | 1134 | CONFIG_ASH_JOB_CONTROL=y |
1135 | CONFIG_ASH_ALIAS=y | 1135 | CONFIG_ASH_ALIAS=y |
1136 | CONFIG_ASH_RANDOM_SUPPORT=y | 1136 | CONFIG_ASH_RANDOM_SUPPORT=y |
1137 | CONFIG_ASH_EXPAND_PRMT=y | 1137 | CONFIG_ASH_EXPAND_PRMT=y |
diff --git a/configs/mingw64_defconfig b/configs/mingw64_defconfig index aa704fe75..449f16ae6 100644 --- a/configs/mingw64_defconfig +++ b/configs/mingw64_defconfig | |||
@@ -1131,7 +1131,7 @@ CONFIG_ASH_INTERNAL_GLOB=y | |||
1131 | CONFIG_ASH_BASH_COMPAT=y | 1131 | CONFIG_ASH_BASH_COMPAT=y |
1132 | # CONFIG_ASH_BASH_SOURCE_CURDIR is not set | 1132 | # CONFIG_ASH_BASH_SOURCE_CURDIR is not set |
1133 | CONFIG_ASH_BASH_NOT_FOUND_HOOK=y | 1133 | CONFIG_ASH_BASH_NOT_FOUND_HOOK=y |
1134 | # CONFIG_ASH_JOB_CONTROL is not set | 1134 | CONFIG_ASH_JOB_CONTROL=y |
1135 | CONFIG_ASH_ALIAS=y | 1135 | CONFIG_ASH_ALIAS=y |
1136 | CONFIG_ASH_RANDOM_SUPPORT=y | 1136 | CONFIG_ASH_RANDOM_SUPPORT=y |
1137 | CONFIG_ASH_EXPAND_PRMT=y | 1137 | CONFIG_ASH_EXPAND_PRMT=y |
diff --git a/shell/ash.c b/shell/ash.c index fafbeb86e..6be99864f 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * - command without ".exe" extension is still understood as executable | 24 | * - command without ".exe" extension is still understood as executable |
25 | * - shell scripts on the path are detected by the presence of '#!' | 25 | * - shell scripts on the path are detected by the presence of '#!' |
26 | * - both / and \ are supported in PATH. Usually you must use / | 26 | * - both / and \ are supported in PATH. Usually you must use / |
27 | * - job control doesn't work | 27 | * - job control doesn't work, though the jobs builtin is available |
28 | * - trap doesn't work for signals, only EXIT | 28 | * - trap doesn't work for signals, only EXIT |
29 | * - /dev/null is supported for redirection | 29 | * - /dev/null is supported for redirection |
30 | * - fake $PPID | 30 | * - fake $PPID |
@@ -212,7 +212,17 @@ | |||
212 | 212 | ||
213 | #define PROFILE 0 | 213 | #define PROFILE 0 |
214 | 214 | ||
215 | /* | ||
216 | * Only one of JOBS or JOBS_WIN32 is enabled at a time (or neither). | ||
217 | * JOBS_WIN32 doesn't enable job control, just some job-related features. | ||
218 | */ | ||
219 | #if ENABLE_PLATFORM_MINGW32 | ||
220 | #define JOBS_WIN32 ENABLE_ASH_JOB_CONTROL | ||
221 | #define JOBS 0 | ||
222 | #else | ||
223 | #define JOBS_WIN32 0 | ||
215 | #define JOBS ENABLE_ASH_JOB_CONTROL | 224 | #define JOBS ENABLE_ASH_JOB_CONTROL |
225 | #endif | ||
216 | 226 | ||
217 | #include <fnmatch.h> | 227 | #include <fnmatch.h> |
218 | #include <sys/times.h> | 228 | #include <sys/times.h> |
@@ -4112,10 +4122,13 @@ static int forkshell(struct job *, union node *, int); | |||
4112 | #endif | 4122 | #endif |
4113 | static int waitforjob(struct job *); | 4123 | static int waitforjob(struct job *); |
4114 | 4124 | ||
4115 | #if !JOBS | 4125 | #if !JOBS && !JOBS_WIN32 |
4116 | enum { doing_jobctl = 0 }; | 4126 | enum { doing_jobctl = 0 }; |
4117 | #define setjobctl(on) do {} while (0) | 4127 | #define setjobctl(on) do {} while (0) |
4118 | #else | 4128 | #elif JOBS_WIN32 |
4129 | static smallint doing_jobctl; //references:8 | ||
4130 | #define setjobctl(on) do { if (rootshell) doing_jobctl = on; } while (0) | ||
4131 | #else /* JOBS */ | ||
4119 | static smallint doing_jobctl; //references:8 | 4132 | static smallint doing_jobctl; //references:8 |
4120 | static void setjobctl(int); | 4133 | static void setjobctl(int); |
4121 | #endif | 4134 | #endif |
@@ -4404,7 +4417,7 @@ set_curjob(struct job *jp, unsigned mode) | |||
4404 | } | 4417 | } |
4405 | } | 4418 | } |
4406 | 4419 | ||
4407 | #if JOBS || DEBUG | 4420 | #if JOBS || JOBS_WIN32 || DEBUG |
4408 | static int | 4421 | static int |
4409 | jobno(const struct job *jp) | 4422 | jobno(const struct job *jp) |
4410 | { | 4423 | { |
@@ -4617,7 +4630,9 @@ setjobctl(int on) | |||
4617 | ttyfd = fd; | 4630 | ttyfd = fd; |
4618 | doing_jobctl = on; | 4631 | doing_jobctl = on; |
4619 | } | 4632 | } |
4633 | #endif | ||
4620 | 4634 | ||
4635 | #if JOBS || JOBS_WIN32 | ||
4621 | static int FAST_FUNC | 4636 | static int FAST_FUNC |
4622 | killcmd(int argc, char **argv) | 4637 | killcmd(int argc, char **argv) |
4623 | { | 4638 | { |
@@ -4647,8 +4662,10 @@ killcmd(int argc, char **argv) | |||
4647 | * sh -c 'true|sleep 1 & sleep 2; kill %1' | 4662 | * sh -c 'true|sleep 1 & sleep 2; kill %1' |
4648 | */ | 4663 | */ |
4649 | n = jp->nprocs; /* can't be 0 (I hope) */ | 4664 | n = jp->nprocs; /* can't be 0 (I hope) */ |
4665 | #if !ENABLE_PLATFORM_MINGW32 | ||
4650 | if (jp->jobctl) | 4666 | if (jp->jobctl) |
4651 | n = 1; | 4667 | n = 1; |
4668 | #endif | ||
4652 | dst = alloca(n * sizeof(int)*4); | 4669 | dst = alloca(n * sizeof(int)*4); |
4653 | argv[i] = dst; | 4670 | argv[i] = dst; |
4654 | for (j = 0; j < n; j++) { | 4671 | for (j = 0; j < n; j++) { |
@@ -4663,7 +4680,11 @@ killcmd(int argc, char **argv) | |||
4663 | * leading space. Needed to not confuse | 4680 | * leading space. Needed to not confuse |
4664 | * negative pids with "kill -SIGNAL_NO" syntax | 4681 | * negative pids with "kill -SIGNAL_NO" syntax |
4665 | */ | 4682 | */ |
4683 | #if !ENABLE_PLATFORM_MINGW32 | ||
4666 | dst += sprintf(dst, jp->jobctl ? " -%u" : " %u", (int)ps->ps_pid); | 4684 | dst += sprintf(dst, jp->jobctl ? " -%u" : " %u", (int)ps->ps_pid); |
4685 | #else | ||
4686 | dst += sprintf(dst, " -%u", (int)ps->ps_pid); | ||
4687 | #endif | ||
4667 | } | 4688 | } |
4668 | *dst = '\0'; | 4689 | *dst = '\0'; |
4669 | } | 4690 | } |
@@ -4671,7 +4692,9 @@ killcmd(int argc, char **argv) | |||
4671 | } | 4692 | } |
4672 | return kill_main(argc, argv); | 4693 | return kill_main(argc, argv); |
4673 | } | 4694 | } |
4695 | #endif | ||
4674 | 4696 | ||
4697 | #if JOBS | ||
4675 | static void | 4698 | static void |
4676 | showpipe(struct job *jp /*, FILE *out*/) | 4699 | showpipe(struct job *jp /*, FILE *out*/) |
4677 | { | 4700 | { |
@@ -5048,7 +5071,7 @@ dowait(int block, struct job *jp) | |||
5048 | #endif | 5071 | #endif |
5049 | } | 5072 | } |
5050 | 5073 | ||
5051 | #if JOBS | 5074 | #if JOBS || JOBS_WIN32 |
5052 | static void | 5075 | static void |
5053 | showjob(struct job *jp, int mode) | 5076 | showjob(struct job *jp, int mode) |
5054 | { | 5077 | { |
@@ -5085,8 +5108,10 @@ showjob(struct job *jp, int mode) | |||
5085 | col += sizeof("Running") - 1; | 5108 | col += sizeof("Running") - 1; |
5086 | } else { | 5109 | } else { |
5087 | int status = psend[-1].ps_status; | 5110 | int status = psend[-1].ps_status; |
5111 | #if !ENABLE_PLATFORM_MINGW32 | ||
5088 | if (jp->state == JOBSTOPPED) | 5112 | if (jp->state == JOBSTOPPED) |
5089 | status = jp->stopstatus; | 5113 | status = jp->stopstatus; |
5114 | #endif | ||
5090 | col += sprint_status48(s + col, status, 0); | 5115 | col += sprint_status48(s + col, status, 0); |
5091 | } | 5116 | } |
5092 | /* By now, "[JOBID]* [maybe PID] STATUS" is printed */ | 5117 | /* By now, "[JOBID]* [maybe PID] STATUS" is printed */ |
@@ -5107,12 +5132,16 @@ showjob(struct job *jp, int mode) | |||
5107 | if (mode & SHOW_PIDS) | 5132 | if (mode & SHOW_PIDS) |
5108 | col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->ps_pid) - 1; | 5133 | col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->ps_pid) - 1; |
5109 | start: | 5134 | start: |
5135 | #if !ENABLE_PLATFORM_MINGW32 | ||
5110 | fprintf(out, "%s%*c%s%s", | 5136 | fprintf(out, "%s%*c%s%s", |
5111 | s, | 5137 | s, |
5112 | 33 - col >= 0 ? 33 - col : 0, ' ', | 5138 | 33 - col >= 0 ? 33 - col : 0, ' ', |
5113 | ps == jp->ps ? "" : "| ", | 5139 | ps == jp->ps ? "" : "| ", |
5114 | ps->ps_cmd | 5140 | ps->ps_cmd |
5115 | ); | 5141 | ); |
5142 | #else | ||
5143 | fprintf(out, "%s", s); | ||
5144 | #endif | ||
5116 | } while (++ps != psend); | 5145 | } while (++ps != psend); |
5117 | newline_and_flush(out); | 5146 | newline_and_flush(out); |
5118 | 5147 | ||
@@ -5369,7 +5398,7 @@ makejob(/*union node *node,*/ int nprocs) | |||
5369 | break; | 5398 | break; |
5370 | if (jp->state != JOBDONE || !jp->waited) | 5399 | if (jp->state != JOBDONE || !jp->waited) |
5371 | continue; | 5400 | continue; |
5372 | #if JOBS | 5401 | #if JOBS || JOBS_WIN32 |
5373 | if (doing_jobctl) | 5402 | if (doing_jobctl) |
5374 | continue; | 5403 | continue; |
5375 | #endif | 5404 | #endif |
@@ -10997,7 +11026,7 @@ static const struct builtincmd builtintab[] = { | |||
10997 | #if MAX_HISTORY | 11026 | #if MAX_HISTORY |
10998 | { BUILTIN_NOSPEC "history" , historycmd }, | 11027 | { BUILTIN_NOSPEC "history" , historycmd }, |
10999 | #endif | 11028 | #endif |
11000 | #if JOBS | 11029 | #if JOBS || JOBS_WIN32 |
11001 | { BUILTIN_REGULAR "jobs" , jobscmd }, | 11030 | { BUILTIN_REGULAR "jobs" , jobscmd }, |
11002 | { BUILTIN_REGULAR "kill" , killcmd }, | 11031 | { BUILTIN_REGULAR "kill" , killcmd }, |
11003 | #endif | 11032 | #endif |
@@ -11039,7 +11068,7 @@ static const struct builtincmd builtintab[] = { | |||
11039 | /* [ */ 1 * ENABLE_ASH_TEST + \ | 11068 | /* [ */ 1 * ENABLE_ASH_TEST + \ |
11040 | /* [[ */ 1 * BASH_TEST2 + \ | 11069 | /* [[ */ 1 * BASH_TEST2 + \ |
11041 | /* alias */ 1 * ENABLE_ASH_ALIAS + \ | 11070 | /* alias */ 1 * ENABLE_ASH_ALIAS + \ |
11042 | /* bg */ 1 * ENABLE_ASH_JOB_CONTROL + \ | 11071 | /* bg */ 1 * JOBS + \ |
11043 | /* break cd cddir */ 3) | 11072 | /* break cd cddir */ 3) |
11044 | #define EVALCMD (COMMANDCMD + \ | 11073 | #define EVALCMD (COMMANDCMD + \ |
11045 | /* command */ 1 * ENABLE_ASH_CMDCMD + \ | 11074 | /* command */ 1 * ENABLE_ASH_CMDCMD + \ |
@@ -14365,7 +14394,7 @@ cmdloop(int top) | |||
14365 | int skip; | 14394 | int skip; |
14366 | 14395 | ||
14367 | setstackmark(&smark); | 14396 | setstackmark(&smark); |
14368 | #if JOBS | 14397 | #if JOBS || JOBS_WIN32 |
14369 | if (doing_jobctl) | 14398 | if (doing_jobctl) |
14370 | showjobs(SHOW_CHANGED|SHOW_STDERR); | 14399 | showjobs(SHOW_CHANGED|SHOW_STDERR); |
14371 | #endif | 14400 | #endif |
@@ -16735,6 +16764,10 @@ forkshell_init(const char *idstr) | |||
16735 | else { | 16764 | else { |
16736 | SetConsoleCtrlHandler(ctrl_handler, TRUE); | 16765 | SetConsoleCtrlHandler(ctrl_handler, TRUE); |
16737 | } | 16766 | } |
16767 | #if JOBS_WIN32 | ||
16768 | /* do job control only in root shell */ | ||
16769 | doing_jobctl = 0; | ||
16770 | #endif | ||
16738 | end: | 16771 | end: |
16739 | forkshell_child(fs); | 16772 | forkshell_child(fs); |
16740 | } | 16773 | } |