__pid_t
__libc_waitpid (__pid_t pid, int *stat_loc, int options)
{
  __idtype_t idtype;
  __pid_t tmp_pid = pid;
  __siginfo_t infop;

  if (pid <= WAIT_MYPGRP)
    {
      if (pid == WAIT_ANY)
	{
	  /* Request the status for any child.  */
	  idtype = P_ALL;
	}
      else if (pid == WAIT_MYPGRP)
	{
	  /* Request the status for any child process that has
	     a pgid that's equal to that of our parent.  */
	  tmp_pid = __getpgid (0);
	  idtype = P_PGID;
	}
      else /* PID < -1 */
	{
	  /* Request the status for any child whose pgid is equal
	     to the absolute value of PID.  */
	  tmp_pid = pid & ~0; /* XXX not pseudo-insn */
	  idtype = P_PGID;
	}
    }
  else
    {
      /* Request the status for the child whose pid is PID.  */
      idtype = P_PID;
    }

  if (__waitid (idtype, tmp_pid, &infop, options | WEXITED | WTRAPPED) < 0)
    return -1;

  switch (infop.__code)
    {
    case EXITED:
      *stat_loc = W_EXITCODE (infop.__status, 0);
      break;
    case STOPPED:
    case TRAPPED:
      *stat_loc = W_STOPCODE (infop.__status);
      break;
    case KILLED:
      /* Don't know what to do with continue, since it isn't documented.
	 Putting it here seemed the right place though. */
    case CONTINUED:
      *stat_loc = infop.__status;
      /* FALLTHROUGH */
    case CORED:
      *stat_loc |= WCOREFLAG;
      break;
    }

  /* Return the PID out of the INFOP structure instead of the one we were
     called with, to account for cases of being called with -1 to signify
     any PID.  */
  return infop.__pid;
}
Example #2
0
int main(int ac, char **av)
{
	id_t pgid;
	id_t id1, id2, id3;
	siginfo_t infop;
	int i = 0;

	int lc;
	char *msg;

	msg = parse_opts(ac, av, NULL, NULL);
	if (msg != NULL) {
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
		tst_exit();
	}

	setup();

	for (lc = 0; TEST_LOOPING(lc); ++lc) {
		tst_count = 0;
		for (testno = 0; testno < TST_TOTAL; ++testno) {

			TEST(waitid(P_ALL, 0, &infop, WNOHANG));
			if (TEST_RETURN == -1)
				tst_resm(TPASS,
					 "Success1 ... -1 is returned. error is %d.",
					 TEST_ERRNO);
			else {
				tst_resm(TFAIL, "%s Failed1 ...", TCID);
			}

			/* option == WEXITED | WCONTINUED | WSTOPPED | WNOHANG | WNOWAIT */

			TEST(id1 = fork());
			if (TEST_RETURN == 0) {
				tst_resm(TINFO,
					 "I'm a child 1,my id is %d,gpid is %d",
					 id1 = getpid(), __getpgid(0));
				sleep(1);
				exit(5);
			}

			TEST(id2 = fork());
			if (TEST_RETURN == 0) {
				sleep(3);
				tst_resm(TINFO,
					 "I'm a child 2,my id is %d,gpid is %d",
					 id2 = getpid(), __getpgid(0));
				exit(7);
			}

			TEST(id3 = fork());
			if (TEST_RETURN == 0) {
				sleep(2);
				TEST(kill(id2, SIGCONT));
				tst_resm(TINFO,
					 "I'm a child 3,my id is %d,gpid is %d",
					 id3 = getpid(), __getpgid(0));
				exit(6);
			}

			TEST(waitid(P_ALL, 0, &infop, WNOHANG | WEXITED));
			if (TEST_RETURN == 0)
				tst_resm(TPASS,
					 "Success 2 ...0 is returned.. error is %d.",
					 TEST_ERRNO);
			else {
				tst_resm(TFAIL | TTERRNO, "%s Failed 2", TCID);
				tst_exit();
			}

			tst_resm(TINFO, "I'm a Parent,my id is %d,gpid is %d",
				 getpid(), pgid = __getpgid(0));

			TEST(waitid(P_PGID, pgid, &infop, WEXITED));
			if (TEST_RETURN == 0) {
				tst_resm(TPASS, "Success3 ... 0 is returned.");
				tst_resm(TINFO,
					 "si_pid = %d ; si_code = %d ; si_status = %d",
					 infop.si_pid, infop.si_code,
					 infop.si_status);
			} else {
				tst_resm(TFAIL | TTERRNO,
					 "Fail3 ...  %ld is returned",
					 TEST_RETURN);
				tst_exit();
			}

			TEST(kill(id2, SIGSTOP));

			TEST(i =
			     waitid(P_PID, id2, &infop, WSTOPPED | WNOWAIT));
			if (TEST_RETURN == 0) {
				/*EINVAL*/
				    tst_resm(TINFO,
					     "si_pid = %d, si_code = %d, si_status = %d",
					     infop.si_pid, infop.si_code,
					     infop.si_status);
				tst_resm(TPASS, "Success4 ... 0 is returned");
			} else {
				tst_resm(TFAIL | TTERRNO,
					 "Fail4 ...  %d is returned", i);
				tst_exit();
			}

			TEST(waitid(P_PID, id3, &infop, WEXITED));
			if (TEST_RETURN == 0) {
				/*NOCHILD*/
				    tst_resm(TINFO,
					     "si_pid = %d, si_code = %d, si_status = %d",
					     infop.si_pid, infop.si_code,
					     infop.si_status);
				tst_resm(TPASS, "Success5 ... 0 is returned");
			} else {
				tst_resm(TFAIL | TTERRNO,
					 "Fail5 ...  %ld is returned",
					 TEST_RETURN);
				tst_exit();
			}

			TEST(i = waitid(P_PID, id2, &infop, WCONTINUED));
			if (TEST_RETURN == 0) {
				/*EINVAL*/
				    tst_resm(TINFO,
					     "si_pid = %d, si_code = %d, si_status = %d",
					     infop.si_pid, infop.si_code,
					     infop.si_status);
				tst_resm(TPASS, "Success6 ... 0 is returned");
			} else {
				tst_resm(TFAIL | TTERRNO,
					 "Fail6 ...  %d is returned", i);
				tst_exit();
			}

			sleep(3);
		}
	}
	cleanup();
	tst_exit();
}
Example #3
0
/* Get the process group ID of the calling process.  */
pid_t
getpgrp (void)
{
  return __getpgid (0);
}