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-09-14 11:04:20 +1000 |
| commit | fa6f44ea7205416837bc72bb9948ba376c2af7c5 (patch) | |
| tree | 5f6874f4fc6fa303f9c82ceb2213ab416bc43ec2 /shell | |
| parent | d104eddf3071815bc9586763efb63ed14ca72790 (diff) | |
| download | busybox-w32-fa6f44ea7205416837bc72bb9948ba376c2af7c5.tar.gz busybox-w32-fa6f44ea7205416837bc72bb9948ba376c2af7c5.tar.bz2 busybox-w32-fa6f44ea7205416837bc72bb9948ba376c2af7c5.zip | |
win32: ash: reimplement waitpid(-1)
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 1b448371d..31ad46aa7 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; |
