diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2010-04-14 00:44:48 +0200 |
---|---|---|
committer | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2010-04-20 19:14:42 +0200 |
commit | f12b36df0561b8a2eeba2fab4a7bcd15093b2c92 (patch) | |
tree | 41672f321e2ce792ddbf8be81edaf0384fd7cab9 /shell | |
parent | c3bdb8b1a640c740ed6a2aacc0bd4ce0740809ab (diff) | |
download | busybox-w32-f12b36df0561b8a2eeba2fab4a7bcd15093b2c92.tar.gz busybox-w32-f12b36df0561b8a2eeba2fab4a7bcd15093b2c92.tar.bz2 busybox-w32-f12b36df0561b8a2eeba2fab4a7bcd15093b2c92.zip |
win32: ash: reimplement waitpid(-1)
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/shell/ash.c b/shell/ash.c index a54284155..40b4c421d 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -3889,6 +3889,53 @@ sprint_status(char *s, int status, int sigonly) | |||
3889 | return col; | 3889 | return col; |
3890 | } | 3890 | } |
3891 | 3891 | ||
3892 | #if ENABLE_PLATFORM_MINGW32 | ||
3893 | /* | ||
3894 | * Windows does not know about parent-child relationship | ||
3895 | * They don't support waitpid(-1) | ||
3896 | */ | ||
3897 | static pid_t | ||
3898 | waitpid_child(int *status) | ||
3899 | { | ||
3900 | HANDLE *pidlist, *pidp; | ||
3901 | int pid_nr = 0; | ||
3902 | pid_t pid; | ||
3903 | DWORD win_status, idx; | ||
3904 | struct job *jb; | ||
3905 | |||
3906 | #define LOOP(stmt) \ | ||
3907 | for (jb = curjob; jb; jb = jb->prev_job) { \ | ||
3908 | struct procstat *ps, *psend; \ | ||
3909 | if (jb->state == JOBDONE) \ | ||
3910 | continue; \ | ||
3911 | ps = jb->ps; \ | ||
3912 | psend = ps + jb->nprocs; \ | ||
3913 | while (ps < psend) { \ | ||
3914 | if (ps->ps_pid != -1) { \ | ||
3915 | stmt; \ | ||
3916 | } \ | ||
3917 | ps++; \ | ||
3918 | } \ | ||
3919 | } | ||
3920 | |||
3921 | LOOP(pid_nr++); | ||
3922 | pidp = pidlist = ckmalloc(sizeof(*pidlist)*pid_nr); | ||
3923 | LOOP(*pidp++ = (HANDLE)ps->ps_pid); | ||
3924 | #undef LOOP | ||
3925 | |||
3926 | idx = WaitForMultipleObjects(pid_nr, pidlist, FALSE, INFINITE); | ||
3927 | if (idx >= pid_nr) { | ||
3928 | free(pidlist); | ||
3929 | return -1; | ||
3930 | } | ||
3931 | GetExitCodeProcess(pidlist[idx], &win_status); | ||
3932 | pid = (int)pidlist[idx]; | ||
3933 | free(pidlist); | ||
3934 | *status = (int)win_status; | ||
3935 | return pid; | ||
3936 | } | ||
3937 | #endif | ||
3938 | |||
3892 | static int | 3939 | static int |
3893 | dowait(int wait_flags, struct job *job) | 3940 | dowait(int wait_flags, struct job *job) |
3894 | { | 3941 | { |
@@ -3905,7 +3952,11 @@ dowait(int wait_flags, struct job *job) | |||
3905 | * NB: _not_ safe_waitpid, we need to detect EINTR */ | 3952 | * NB: _not_ safe_waitpid, we need to detect EINTR */ |
3906 | if (doing_jobctl) | 3953 | if (doing_jobctl) |
3907 | wait_flags |= WUNTRACED; | 3954 | wait_flags |= WUNTRACED; |
3955 | #if ENABLE_PLATFORM_MINGW32 | ||
3956 | pid = waitpid_child(&status); | ||
3957 | #else | ||
3908 | pid = waitpid(-1, &status, wait_flags); | 3958 | pid = waitpid(-1, &status, wait_flags); |
3959 | #endif | ||
3909 | TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n", | 3960 | TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n", |
3910 | pid, status, errno, strerror(errno))); | 3961 | pid, status, errno, strerror(errno))); |
3911 | if (pid <= 0) | 3962 | if (pid <= 0) |
@@ -3928,6 +3979,8 @@ dowait(int wait_flags, struct job *job) | |||
3928 | jobno(jp), pid, ps->ps_status, status)); | 3979 | jobno(jp), pid, ps->ps_status, status)); |
3929 | ps->ps_status = status; | 3980 | ps->ps_status = status; |
3930 | thisjob = jp; | 3981 | thisjob = jp; |
3982 | if (ENABLE_PLATFORM_MINGW32) | ||
3983 | ps->ps_pid = -1; | ||
3931 | } | 3984 | } |
3932 | if (ps->ps_status == -1) | 3985 | if (ps->ps_status == -1) |
3933 | state = JOBRUNNING; | 3986 | state = JOBRUNNING; |