Deleted Added
full compact
proc_util.c (179185) proc_util.c (210688)
1/*-
1/*-
2 * Copyright (c) 2010 The FreeBSD Foundation
2 * Copyright (c) 2008 John Birrell (jb@freebsd.org)
3 * All rights reserved.
3 * Copyright (c) 2008 John Birrell (jb@freebsd.org)
4 * All rights reserved.
5 *
6 * Portions of this software were developed by Rui Paulo under sponsorship
7 * from the FreeBSD Foundation.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the

--- 6 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the

--- 6 unchanged lines hidden (view full) ---

22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
26 * $FreeBSD: head/lib/libproc/proc_util.c 179185 2008-05-22 02:09:21Z jb $
30 * $FreeBSD: head/lib/libproc/proc_util.c 210688 2010-07-31 16:10:20Z rpaulo $
27 */
28
31 */
32
29#include "_libproc.h"
30#include <errno.h>
31#include <unistd.h>
33#include <sys/types.h>
32#include <sys/ptrace.h>
33#include <sys/wait.h>
34#include <sys/ptrace.h>
35#include <sys/wait.h>
36#include <err.h>
37#include <errno.h>
38#include <unistd.h>
34#include <stdio.h>
39#include <stdio.h>
40#include <signal.h>
41#include <string.h>
42#include "_libproc.h"
35
36int
37proc_clearflags(struct proc_handle *phdl, int mask)
38{
43
44int
45proc_clearflags(struct proc_handle *phdl, int mask)
46{
47
39 if (phdl == NULL)
40 return (EINVAL);
41
42 phdl->flags &= ~mask;
43
44 return (0);
45}
46
48 if (phdl == NULL)
49 return (EINVAL);
50
51 phdl->flags &= ~mask;
52
53 return (0);
54}
55
56/*
57 * NB: we return -1 as the Solaris libproc Psetrun() function.
58 */
47int
48proc_continue(struct proc_handle *phdl)
49{
59int
60proc_continue(struct proc_handle *phdl)
61{
62
50 if (phdl == NULL)
63 if (phdl == NULL)
51 return (EINVAL);
64 return (-1);
52
53 if (ptrace(PT_CONTINUE, phdl->pid, (caddr_t)(uintptr_t) 1, 0) != 0)
65
66 if (ptrace(PT_CONTINUE, phdl->pid, (caddr_t)(uintptr_t) 1, 0) != 0)
54 return (errno);
67 return (-1);
55
56 phdl->status = PS_RUN;
57
58 return (0);
59}
60
61int
68
69 phdl->status = PS_RUN;
70
71 return (0);
72}
73
74int
62proc_detach(struct proc_handle *phdl)
75proc_detach(struct proc_handle *phdl, int reason)
63{
76{
77 int status;
78
64 if (phdl == NULL)
65 return (EINVAL);
79 if (phdl == NULL)
80 return (EINVAL);
81 if (reason == PRELEASE_KILL) {
82 kill(phdl->pid, SIGKILL);
83 return (0);
84 }
85 if (ptrace(PT_DETACH, phdl->pid, 0, 0) != 0 && errno == ESRCH)
86 return (0);
87 if (errno == EBUSY) {
88 kill(phdl->pid, SIGSTOP);
89 waitpid(phdl->pid, &status, WUNTRACED);
90 ptrace(PT_DETACH, phdl->pid, 0, 0);
91 kill(phdl->pid, SIGCONT);
92 return (0);
93 }
66
94
67 if (ptrace(PT_DETACH, phdl->pid, 0, 0) != 0)
68 return (errno);
69
70 return (0);
71}
72
73int
74proc_getflags(struct proc_handle *phdl)
75{
95 return (0);
96}
97
98int
99proc_getflags(struct proc_handle *phdl)
100{
101
76 if (phdl == NULL)
77 return (-1);
78
79 return(phdl->flags);
80}
81
82int
83proc_setflags(struct proc_handle *phdl, int mask)
84{
102 if (phdl == NULL)
103 return (-1);
104
105 return(phdl->flags);
106}
107
108int
109proc_setflags(struct proc_handle *phdl, int mask)
110{
111
85 if (phdl == NULL)
86 return (EINVAL);
87
88 phdl->flags |= mask;
89
90 return (0);
91}
92
93int
94proc_state(struct proc_handle *phdl)
95{
112 if (phdl == NULL)
113 return (EINVAL);
114
115 phdl->flags |= mask;
116
117 return (0);
118}
119
120int
121proc_state(struct proc_handle *phdl)
122{
123
96 if (phdl == NULL)
97 return (-1);
98
99 return (phdl->status);
100}
101
124 if (phdl == NULL)
125 return (-1);
126
127 return (phdl->status);
128}
129
102int
103proc_wait(struct proc_handle *phdl)
130pid_t
131proc_getpid(struct proc_handle *phdl)
104{
132{
105 int status = 0;
106 struct kevent kev;
107
108 if (phdl == NULL)
133
134 if (phdl == NULL)
109 return (EINVAL);
135 return (-1);
110
136
111 if (kevent(phdl->kq, NULL, 0, &kev, 1, NULL) <= 0)
112 return (0);
137 return (phdl->pid);
138}
113
139
114 switch (kev.filter) {
115 /* Child has exited */
116 case EVFILT_PROC: /* target has exited */
140int
141proc_wstatus(struct proc_handle *phdl)
142{
143 int status;
144
145 if (phdl == NULL)
146 return (-1);
147 if (waitpid(phdl->pid, &status, WUNTRACED) < 0)
148 return (-1);
149 if (WIFSTOPPED(status))
150 phdl->status = PS_STOP;
151 if (WIFEXITED(status) || WIFSIGNALED(status))
117 phdl->status = PS_UNDEAD;
152 phdl->status = PS_UNDEAD;
118 break;
119 default:
120 break;
121 }
153 phdl->wstat = status;
122
123 return (status);
124}
125
154
155 return (status);
156}
157
126pid_t
127proc_getpid(struct proc_handle *phdl)
158int
159proc_getwstat(struct proc_handle *phdl)
128{
160{
161
129 if (phdl == NULL)
130 return (-1);
131
162 if (phdl == NULL)
163 return (-1);
164
132 return (phdl->pid);
165 return (phdl->wstat);
133}
166}
167
168char *
169proc_signame(int sig, char *name, size_t namesz)
170{
171
172 strlcpy(name, strsignal(sig), namesz);
173
174 return (name);
175}
176
177int
178proc_read(struct proc_handle *phdl, char *buf, size_t size, size_t addr)
179{
180 struct ptrace_io_desc piod;
181
182 if (phdl == NULL)
183 return (-1);
184 piod.piod_op = PIOD_READ_D;
185 piod.piod_len = size;
186 piod.piod_addr = (void *)buf;
187 piod.piod_offs = (void *)addr;
188
189 if (ptrace(PT_IO, phdl->pid, (caddr_t)&piod, 0) < 0)
190 return (-1);
191 return (piod.piod_len);
192}
193
194const lwpstatus_t *
195proc_getlwpstatus(struct proc_handle *phdl)
196{
197 struct ptrace_lwpinfo lwpinfo;
198 lwpstatus_t *psp = &phdl->lwps;
199 siginfo_t *siginfo;
200
201 if (phdl == NULL)
202 return (NULL);
203 if (ptrace(PT_LWPINFO, phdl->pid, (caddr_t)&lwpinfo,sizeof(lwpinfo)) < 0)
204 return (NULL);
205 siginfo = &lwpinfo.pl_siginfo;
206 if (lwpinfo.pl_event == PL_EVENT_SIGNAL &&
207 (lwpinfo.pl_flags & PL_FLAG_SI) &&
208 siginfo->si_signo == SIGTRAP &&
209 (siginfo->si_code == TRAP_BRKPT ||
210 siginfo->si_code == TRAP_TRACE)) {
211 psp->pr_why = PR_FAULTED;
212 psp->pr_what = FLTBPT;
213 } else if (lwpinfo.pl_flags & PL_FLAG_SCE) {
214 psp->pr_why = PR_SYSENTRY;
215 } else if (lwpinfo.pl_flags & PL_FLAG_SCX) {
216 psp->pr_why = PR_SYSEXIT;
217 }
218
219 return (psp);
220}