struct ps_prochandle * dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv) { dt_proc_hash_t *dph = dtp->dt_procs; dt_proc_t *dpr; int err; if ((dpr = dt_zalloc(dtp, sizeof (dt_proc_t))) == NULL) return (NULL); /* errno is set for us */ (void) pthread_mutex_init(&dpr->dpr_lock, NULL); (void) pthread_cond_init(&dpr->dpr_cv, NULL); if ((dpr->dpr_proc = Pcreate(file, argv, &err, NULL, 0, dtp->dt_arch)) == NULL) { return (dt_proc_error(dtp, dpr, "failed to execute %s: %s\n", file, Pcreate_error(err))); } dpr->dpr_hdl = dtp; dpr->dpr_pid = Pstatus(dpr->dpr_proc)->pr_pid; (void) Punsetflags(dpr->dpr_proc, PR_RLC); (void) Psetflags(dpr->dpr_proc, PR_KLC); if (dt_proc_create_thread(dtp, dpr, dtp->dt_prcmode) != 0) return (NULL); /* dt_proc_error() has been called for us */ dpr->dpr_hash = dph->dph_hash[dpr->dpr_pid & (dph->dph_hashlen - 1)]; dph->dph_hash[dpr->dpr_pid & (dph->dph_hashlen - 1)] = dpr; dt_list_prepend(&dph->dph_lrulist, dpr); dt_dprintf("created pid %d\n", (int)dpr->dpr_pid); dpr->dpr_refs++; return (dpr->dpr_proc); }
int main(int argc, char **argv) { int opt, exit; pid_t pid; struct siginfo info; int status; int gret; struct ps_prochandle *Pr; if ((command = strrchr(argv[0], '/')) != NULL) command++; else command = argv[0]; while ((opt = getopt(argc, argv, "Fhmp:")) != EOF) { switch (opt) { case 'F': /* force grabbing (no O_EXCL) */ Fflag = PGRAB_FORCE; break; case 'm': /* microstate accounting */ mflag = 1; break; case 'p': pflag = 1; pidarg = optarg; break; default: errflg = 1; break; } } argc -= optind; argv += optind; if (((pidarg != NULL) ^ (argc < 1)) || errflg) { (void) fprintf(stderr, "usage:\t%s [-mh] [-p pidlist | command [ args ... ]]\n", command); (void) fprintf(stderr, " (time a command using microstate accounting)\n"); return (1); } if (pflag) { char *pp; exit = 0; (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); pp = strtok(pidarg, ", "); if (pp == NULL) { (void) fprintf(stderr, "%s: invalid argument for -p\n", command); return (1); } exit = ptime_pid(pp); while ((pp = strtok(NULL, ", ")) != NULL) { exit |= ptime_pid(pp); } return (exit); } if ((Pr = Pcreate(argv[0], &argv[0], &gret, NULL, 0)) == NULL) { (void) fprintf(stderr, "%s: failed to exec %s: %s\n", command, argv[0], Pcreate_error(gret)); return (1); } if (Psetrun(Pr, 0, 0) == -1) { (void) fprintf(stderr, "%s: failed to set running %s: " "%s\n", command, argv[0], strerror(errno)); return (1); } pid = Pstatus(Pr)->pr_pid; (void) sprintf(procname, "%d", (int)pid); /* for perr() */ (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); (void) waitid(P_PID, pid, &info, WEXITED | WNOWAIT); (void) look(pid); (void) waitpid(pid, &status, 0); if (WIFEXITED(status)) return (WEXITSTATUS(status)); if (WIFSIGNALED(status)) { int sig = WTERMSIG(status); char name[SIG2STR_MAX]; (void) fprintf(stderr, "%s: command terminated " "abnormally by %s\n", command, proc_signame(sig, name, sizeof (name))); } return (status | WCOREFLG); /* see time(1) */ }