1639 lines · 41.3 KB · C
RawDownload
						goto end;					break;				}check_continued:				/*				 * It's running now, so it might later				 * exit, stop, or stop and then continue.				 */				flag = 1;				if (!unlikely(options & WCONTINUED))					continue;				retval = wait_task_continued(					p, (options & WNOWAIT),					infop, stat_addr, ru);				if (retval != 0) /* He released the lock.  */					goto end;				break;			}		}		if (!flag) {			list_for_each(_p, &tsk->ptrace_children) {				p = list_entry(_p, struct task_struct,						ptrace_list);				if (!eligible_child(pid, options, p))					continue;				flag = 1;				break;			}		}		if (options & __WNOTHREAD)			break;		tsk = next_thread(tsk);		if (tsk->signal != current->signal)			BUG();	} while (tsk != current); 	read_unlock(&tasklist_lock);	if (flag) {		retval = 0;		if (options & WNOHANG)			goto end;		retval = -ERESTARTSYS;		if (signal_pending(current))			goto end;		schedule();		goto repeat;	}	retval = -ECHILD;end:	current->state = TASK_RUNNING;	remove_wait_queue(&current->signal->wait_chldexit,&wait);	if (infop) {		if (retval > 0)		retval = 0;		else {			/*			 * For a WNOHANG return, clear out all the fields			 * we would set so the user can easily tell the			 * difference.			 */			if (!retval)				retval = put_user(0, &infop->si_signo);			if (!retval)				retval = put_user(0, &infop->si_errno);			if (!retval)				retval = put_user(0, &infop->si_code);			if (!retval)				retval = put_user(0, &infop->si_pid);			if (!retval)				retval = put_user(0, &infop->si_uid);			if (!retval)				retval = put_user(0, &infop->si_status);		}	}	return retval;} asmlinkage long sys_waitid(int which, pid_t pid,			   struct siginfo __user *infop, int options,			   struct rusage __user *ru){	long ret; 	if (options & ~(WNOHANG|WNOWAIT|WEXITED|WSTOPPED|WCONTINUED))		return -EINVAL;	if (!(options & (WEXITED|WSTOPPED|WCONTINUED)))		return -EINVAL; 	switch (which) {	case P_ALL:		pid = -1;		break;	case P_PID:		if (pid <= 0)			return -EINVAL;		break;	case P_PGID:		if (pid <= 0)			return -EINVAL;		pid = -pid;		break;	default:		return -EINVAL;	} 	ret = do_wait(pid, options, infop, NULL, ru); 	/* avoid REGPARM breakage on x86: */	prevent_tail_call(ret);	return ret;} asmlinkage long sys_wait4(pid_t pid, int __user *stat_addr,			  int options, struct rusage __user *ru){	long ret; 	if (options & ~(WNOHANG|WUNTRACED|WCONTINUED|			__WNOTHREAD|__WCLONE|__WALL))		return -EINVAL;	ret = do_wait(pid, options | WEXITED, NULL, stat_addr, ru); 	/* avoid REGPARM breakage on x86: */	prevent_tail_call(ret);	return ret;} #ifdef __ARCH_WANT_SYS_WAITPID /* * sys_waitpid() remains for compatibility. waitpid() should be * implemented by calling sys_wait4() from libc.a. */asmlinkage long sys_waitpid(pid_t pid, int __user *stat_addr, int options){	return sys_wait4(pid, stat_addr, options, NULL);} #endif

Lines 1501–1639 of 1639. Previous lines