aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2016-05-18 11:06:02 +0100
committerRon Yorston <rmy@pobox.com>2016-05-18 11:06:02 +0100
commitc7c05c8e5723ed833ed0e73d24d7f7c45169c6e9 (patch)
treeeba790e9f233e0649dba0887c064970cc3bb0b2d
parent4988f3c4cc3cb9e8b1ccb06e84768c177cb13385 (diff)
downloadbusybox-w32-c7c05c8e5723ed833ed0e73d24d7f7c45169c6e9.tar.gz
busybox-w32-c7c05c8e5723ed833ed0e73d24d7f7c45169c6e9.tar.bz2
busybox-w32-c7c05c8e5723ed833ed0e73d24d7f7c45169c6e9.zip
ash: fix use of pid/handle in waitpid_child
Previously spawn was returning a process handle which was treated as a pid in certain circumstances. This resulted in the following failing: find . -type f | sed xargs -n 1 sed -n '1 p' It should output the first line of each file but stopped after the first.
-rw-r--r--include/mingw.h1
-rw-r--r--shell/ash.c99
-rw-r--r--win32/process.c14
3 files changed, 79 insertions, 35 deletions
diff --git a/include/mingw.h b/include/mingw.h
index bfdf2cccd..efb17e137 100644
--- a/include/mingw.h
+++ b/include/mingw.h
@@ -450,6 +450,7 @@ DIR *mingw_opendir(const char *path);
450#define PRIuMAX "I64u" 450#define PRIuMAX "I64u"
451 451
452pid_t FAST_FUNC mingw_spawn(char **argv); 452pid_t FAST_FUNC mingw_spawn(char **argv);
453intptr_t FAST_FUNC mingw_spawn_proc(char **argv);
453int mingw_execv(const char *cmd, const char *const *argv); 454int mingw_execv(const char *cmd, const char *const *argv);
454int mingw_execvp(const char *cmd, const char *const *argv); 455int mingw_execvp(const char *cmd, const char *const *argv);
455int mingw_execve(const char *cmd, const char *const *argv, const char *const *envp); 456int mingw_execve(const char *cmd, const char *const *argv, const char *const *envp);
diff --git a/shell/ash.c b/shell/ash.c
index 340115c35..be5f3f6e4 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -3538,6 +3538,9 @@ unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
3538 */ 3538 */
3539struct procstat { 3539struct procstat {
3540 pid_t ps_pid; /* process id */ 3540 pid_t ps_pid; /* process id */
3541#if ENABLE_PLATFORM_MINGW32
3542 HANDLE ps_proc;
3543#endif
3541 int ps_status; /* last process status from wait() */ 3544 int ps_status; /* last process status from wait() */
3542 char *ps_cmd; /* text of command being run */ 3545 char *ps_cmd; /* text of command being run */
3543}; 3546};
@@ -4159,54 +4162,69 @@ static BOOL WINAPI ctrl_handler(DWORD dwCtrlType)
4159static pid_t 4162static pid_t
4160waitpid_child(int *status, int wait_flags) 4163waitpid_child(int *status, int wait_flags)
4161{ 4164{
4162 HANDLE *pidlist, *pidp; 4165 pid_t *pidlist;
4166 HANDLE *proclist;
4163 int pid_nr = 0; 4167 int pid_nr = 0;
4164 pid_t pid; 4168 pid_t pid;
4165 DWORD win_status, idx; 4169 DWORD win_status, idx;
4166 struct job *jb; 4170 struct job *jb;
4167 4171
4168 #define LOOP(stmt) \ 4172 for (jb = curjob; jb; jb = jb->prev_job) {
4169 for (jb = curjob; jb; jb = jb->prev_job) { \ 4173 if (jb->state != JOBDONE)
4170 struct procstat *ps, *psend; \ 4174 pid_nr += jb->nprocs;
4171 if (jb->state == JOBDONE) \ 4175 }
4172 continue; \ 4176 if ( pid_nr++ == 0 )
4173 ps = jb->ps; \ 4177 return -1;
4174 psend = ps + jb->nprocs; \ 4178
4175 while (ps < psend) { \ 4179 pidlist = ckmalloc(sizeof(*pidlist)*pid_nr);
4176 if (ps->ps_pid != -1) { \ 4180 proclist = ckmalloc(sizeof(*proclist)*pid_nr);
4177 stmt; \ 4181
4178 } \ 4182 pidlist[0] = -1;
4179 ps++; \ 4183 proclist[0] = hSIGINT;
4180 } \ 4184 pid_nr = 1;
4181 } 4185 for (jb = curjob; jb; jb = jb->prev_job) {
4182 4186 struct procstat *ps, *psend;
4183 LOOP(pid_nr++); 4187 if (jb->state == JOBDONE)
4184 if (!pid_nr) 4188 continue;
4189 ps = jb->ps;
4190 psend = ps + jb->nprocs;
4191 while (ps < psend) {
4192 if (ps->ps_pid != -1 && ps->ps_proc != NULL) {
4193 pidlist[pid_nr] = ps->ps_pid;
4194 proclist[pid_nr++] = ps->ps_proc;
4195 }
4196 ps++;
4197 }
4198 }
4199
4200 if (pid_nr == 1) {
4201 free(pidlist);
4202 free(proclist);
4185 return -1; 4203 return -1;
4186 pid_nr++; 4204 }
4187 pidp = pidlist = ckmalloc(sizeof(*pidlist)*pid_nr);
4188 *pidp++ = hSIGINT;
4189 LOOP(*pidp++ = (HANDLE)ps->ps_pid);
4190 #undef LOOP
4191 4205
4192 idx = WaitForMultipleObjects(pid_nr, pidlist, FALSE, 4206 idx = WaitForMultipleObjects(pid_nr, proclist, FALSE,
4193 wait_flags|WNOHANG ? 1 : INFINITE); 4207 wait_flags|WNOHANG ? 1 : INFINITE);
4194 if (idx >= pid_nr) { 4208 if (idx >= pid_nr) {
4195 free(pidlist); 4209 free(pidlist);
4210 free(proclist);
4196 return -1; 4211 return -1;
4197 } 4212 }
4198 if (!idx) { /* hSIGINT */ 4213 if (!idx) { /* hSIGINT */
4199 int i; 4214 int i;
4200 ResetEvent(hSIGINT); 4215 ResetEvent(hSIGINT);
4201 for (i = 1; i < pid_nr; i++) 4216 for (i = 1; i < pid_nr; i++)
4202 TerminateProcess(pidlist[i], 1); 4217 TerminateProcess(proclist[i], 1);
4218 pid = pidlist[1];
4203 free(pidlist); 4219 free(pidlist);
4220 free(proclist);
4204 *status = 260; /* terminated by a signal */ 4221 *status = 260; /* terminated by a signal */
4205 return pidlist[1]; 4222 return pid;
4206 } 4223 }
4207 GetExitCodeProcess(pidlist[idx], &win_status); 4224 GetExitCodeProcess(proclist[idx], &win_status);
4208 pid = (int)pidlist[idx]; 4225 pid = pidlist[idx];
4209 free(pidlist); 4226 free(pidlist);
4227 free(proclist);
4210 *status = (int)win_status; 4228 *status = (int)win_status;
4211 return pid; 4229 return pid;
4212} 4230}
@@ -4255,8 +4273,11 @@ dowait(int wait_flags, struct job *job)
4255 jobno(jp), pid, ps->ps_status, status)); 4273 jobno(jp), pid, ps->ps_status, status));
4256 ps->ps_status = status; 4274 ps->ps_status = status;
4257 thisjob = jp; 4275 thisjob = jp;
4258 if (ENABLE_PLATFORM_MINGW32) 4276 if (ENABLE_PLATFORM_MINGW32) {
4259 ps->ps_pid = -1; 4277 ps->ps_pid = -1;
4278 CloseHandle(ps->ps_proc);
4279 ps->ps_proc = NULL;
4280 }
4260 } 4281 }
4261 if (ps->ps_status == -1) 4282 if (ps->ps_status == -1)
4262 jobstate = JOBRUNNING; 4283 jobstate = JOBRUNNING;
@@ -5096,8 +5117,15 @@ forkchild(struct job *jp, union node *n, int mode)
5096#define forkparent(jp, n, mode, pid) forkparent(jp, mode, pid) 5117#define forkparent(jp, n, mode, pid) forkparent(jp, mode, pid)
5097#endif 5118#endif
5098static void 5119static void
5120#if !ENABLE_PLATFORM_MINGW32
5099forkparent(struct job *jp, union node *n, int mode, pid_t pid) 5121forkparent(struct job *jp, union node *n, int mode, pid_t pid)
5122#else
5123forkparent(struct job *jp, union node *n, int mode, HANDLE proc)
5124#endif
5100{ 5125{
5126#if ENABLE_PLATFORM_MINGW32
5127 pid_t pid = GetProcessId(proc);
5128#endif
5101 TRACE(("In parent shell: child = %d\n", pid)); 5129 TRACE(("In parent shell: child = %d\n", pid));
5102 if (!jp && !ENABLE_PLATFORM_MINGW32) { /* FIXME not quite understand this */ 5130 if (!jp && !ENABLE_PLATFORM_MINGW32) { /* FIXME not quite understand this */
5103 while (jobless && dowait(DOWAIT_NONBLOCK, NULL) > 0) 5131 while (jobless && dowait(DOWAIT_NONBLOCK, NULL) > 0)
@@ -5124,6 +5152,9 @@ forkparent(struct job *jp, union node *n, int mode, pid_t pid)
5124 if (jp) { 5152 if (jp) {
5125 struct procstat *ps = &jp->ps[jp->nprocs++]; 5153 struct procstat *ps = &jp->ps[jp->nprocs++];
5126 ps->ps_pid = pid; 5154 ps->ps_pid = pid;
5155#if ENABLE_PLATFORM_MINGW32
5156 ps->ps_proc = proc;
5157#endif
5127 ps->ps_status = -1; 5158 ps->ps_status = -1;
5128 ps->ps_cmd = nullstr; 5159 ps->ps_cmd = nullstr;
5129#if JOBS 5160#if JOBS
@@ -14000,20 +14031,20 @@ spawn_forkshell(struct job *jp, struct forkshell *fs, int mode)
14000 struct forkshell *new; 14031 struct forkshell *new;
14001 char buf[16]; 14032 char buf[16];
14002 const char *argv[] = { "sh", "--forkshell", NULL, NULL }; 14033 const char *argv[] = { "sh", "--forkshell", NULL, NULL };
14003 pid_t pid; 14034 intptr_t ret;
14004 14035
14005 new = forkshell_prepare(fs); 14036 new = forkshell_prepare(fs);
14006 sprintf(buf, "%x", (unsigned int)new->hMapFile); 14037 sprintf(buf, "%x", (unsigned int)new->hMapFile);
14007 argv[2] = buf; 14038 argv[2] = buf;
14008 pid = spawn(argv); 14039 ret = mingw_spawn_proc(argv);
14009 CloseHandle(new->hMapFile); 14040 CloseHandle(new->hMapFile);
14010 UnmapViewOfFile(new); 14041 UnmapViewOfFile(new);
14011 if (pid == -1) { 14042 if (ret == -1) {
14012 free(jp); 14043 free(jp);
14013 return -1; 14044 return -1;
14014 } 14045 }
14015 forkparent(jp, fs->node, mode, pid); 14046 forkparent(jp, fs->node, mode, (HANDLE)ret);
14016 return pid; 14047 return ret == -1 ? -1 : 0;
14017} 14048}
14018 14049
14019/* 14050/*
diff --git a/win32/process.c b/win32/process.c
index 8cd1dc28c..9a4b05597 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -332,7 +332,19 @@ mingw_spawn_1(int mode, const char *cmd, const char *const *argv, const char *co
332pid_t FAST_FUNC 332pid_t FAST_FUNC
333mingw_spawn(char **argv) 333mingw_spawn(char **argv)
334{ 334{
335 return mingw_spawn_1(P_NOWAIT, argv[0], (const char *const *)argv, (const char *const *)environ); 335 intptr_t ret;
336
337 ret = mingw_spawn_1(P_NOWAIT, argv[0], (const char *const *)argv,
338 (const char *const *)environ);
339
340 return ret == -1 ? -1 : GetProcessId((HANDLE)ret);
341}
342
343intptr_t FAST_FUNC
344mingw_spawn_proc(char **argv)
345{
346 return mingw_spawn_1(P_NOWAIT, argv[0], (const char *const *)argv,
347 (const char *const *)environ);
336} 348}
337 349
338int 350int