1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <unistd.h> 32 #include <fcntl.h> 33 #include <string.h> 34 #include <errno.h> 35 #include <sys/types.h> 36 #include <signal.h> 37 #include <libproc.h> 38 39 static int start(char *); 40 41 static char *command; 42 43 int 44 main(int argc, char **argv) 45 { 46 int rc = 0; 47 48 if ((command = strrchr(argv[0], '/')) != NULL) 49 command++; 50 else 51 command = argv[0]; 52 53 if (argc <= 1) { 54 (void) fprintf(stderr, "usage:\t%s pid ...\n", command); 55 (void) fprintf(stderr, " (set stopped processes running)\n"); 56 return (2); 57 } 58 59 while (--argc > 0) 60 rc += start(*++argv); 61 62 return (rc); 63 } 64 65 static int 66 start(char *arg) 67 { 68 struct ps_prochandle *P; 69 int gcode; 70 71 if ((P = proc_arg_grab(arg, PR_ARG_PIDS, 72 PGRAB_FORCE | PGRAB_RETAIN | PGRAB_NOSTOP, &gcode)) == NULL) { 73 (void) fprintf(stderr, "%s: cannot control %s: %s\n", 74 command, arg, Pgrab_error(gcode)); 75 return (1); 76 } 77 78 /* 79 * If the victim is stopped because of a job control signal, we 80 * need to send it SIGCONT to get it moving again, otherwise 81 * the agent will not be able to run, and so will not be able to 82 * exit the process. 83 */ 84 (void) kill(Pstatus(P)->pr_pid, SIGCONT); 85 86 /* 87 * if the agent already exists, Pcreate_agent will adopt the 88 * extant agent so that we can destroy it 89 */ 90 if (Pstatus(P)->pr_lwp.pr_flags & PR_AGENT) { 91 if (Pcreate_agent(P) != 0) { 92 (void) fprintf(stderr, 93 "%s: cannot remove agent from %s: %s\n", 94 command, arg, strerror(errno)); 95 96 Prelease(P, 0); 97 return (1); 98 } 99 100 Pdestroy_agent(P); 101 } 102 103 /* 104 * Prelease could change the tracing flags or leave the victim hung 105 * so we set the process running and free the handle by hand. 106 */ 107 (void) Psetrun(P, 0, 0); 108 Pfree(P); 109 110 return (0); 111 } 112