/* * Force the parent process (ppid) to wait for its child process (pid). */ static int reap(char *arg, pid_t *reap_pid, int *exit_status) { struct ps_prochandle *Pr; siginfo_t siginfo; psinfo_t psinfo; prusage_t usage; pid_t pid, ppid; time_t elapsed; int gret; /* * get the specified pid and the psinfo struct */ if ((pid = proc_arg_psinfo(arg, PR_ARG_PIDS, &psinfo, &gret)) == -1) { (void) fprintf(stderr, "%s: cannot examine %s: %s\n", command, arg, Pgrab_error(gret)); return (1); } if (psinfo.pr_nlwp != 0) { (void) fprintf(stderr, "%s: process not defunct: %d\n", command, (int)pid); return (1); } *exit_status = psinfo.pr_wstat; *reap_pid = psinfo.pr_pid; ppid = psinfo.pr_ppid; if (ppid == 1) { (void) fprintf(stderr, "%s: Failed to reap %d: the only " "non-defunct ancestor is 'init'\n", command, (int)pid); return (1); } if (proc_usage(pid, &usage, &gret) == 0) { elapsed = usage.pr_tstamp.tv_sec - usage.pr_term.tv_sec; } else { (void) fprintf(stderr, "%s: cannot examine %d: %s\n", command, (int)pid, Pgrab_error(gret)); return (1); } if ((Fflag == 0) && (elapsed < NOREAP_TIME)) { (void) fprintf(stderr, "%s: unsafe to reap %d; it has been " "defunct less than %d seconds\n", command, (int)pid, NOREAP_TIME); return (1); } if ((Pr = Pgrab(ppid, Fflag | PGRAB_NOSTOP, &gret)) == NULL) { (void) fprintf(stderr, "%s: cannot examine %d: %s\n", command, (int)ppid, Pgrab_error(gret)); return (1); } if ((Fflag == 0) && (Pstate(Pr) == PS_STOP)) { Prelease(Pr, 0); (void) fprintf(stderr, "%s: unsafe to reap %d; parent is " "stopped and may reap status upon restart\n", command, (int)pid); return (1); } /* * Pstop() will fail if the process to be stopped has become a zombie. * This means that we can say with certainty that the child of this * process has not changed parents (i.e. been reparented to init) once * the Pstop() succeeds. */ if (Pstop(Pr, 1000) != 0) { Prelease(Pr, 0); (void) fprintf(stderr, "%s: failed to stop %d: %s", command, (int)ppid, strerror(errno)); return (1); } if (pr_waitid(Pr, P_PID, pid, &siginfo, WEXITED|WNOHANG) != 0) { Prelease(Pr, 0); (void) fprintf(stderr, "%s: waitid() in process %d failed: %s", command, (int)ppid, strerror(errno)); return (1); } Prelease(Pr, 0); return (0); }
/* * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal * Method: suspend0 * Signature: ()V */ JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_suspend0 (JNIEnv *env, jobject this_obj) { jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID); // for now don't check return value. revisit this again. Pstop((struct ps_prochandle*) p_ps_prochandle, 1000); }