0
|
1 |
/*
|
|
2 |
* CDDL HEADER START
|
|
3 |
*
|
|
4 |
* The contents of this file are subject to the terms of the
|
2712
|
5 |
* Common Development and Distribution License (the "License").
|
|
6 |
* You may not use this file except in compliance with the License.
|
0
|
7 |
*
|
|
8 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
9 |
* or http://www.opensolaris.org/os/licensing.
|
|
10 |
* See the License for the specific language governing permissions
|
|
11 |
* and limitations under the License.
|
|
12 |
*
|
|
13 |
* When distributing Covered Code, include this CDDL HEADER in each
|
|
14 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
15 |
* If applicable, add the following below this CDDL HEADER, with the
|
|
16 |
* fields enclosed by brackets "[]" replaced with your own identifying
|
|
17 |
* information: Portions Copyright [yyyy] [name of copyright owner]
|
|
18 |
*
|
|
19 |
* CDDL HEADER END
|
|
20 |
*/
|
|
21 |
/*
|
3957
|
22 |
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
0
|
23 |
* Use is subject to license terms.
|
|
24 |
*/
|
|
25 |
|
|
26 |
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
27 |
|
|
28 |
#include <stdio.h>
|
|
29 |
#define __EXTENSIONS__
|
|
30 |
#include <string.h>
|
|
31 |
#undef __EXTENSIONS__
|
|
32 |
#include <signal.h>
|
|
33 |
#include <alloca.h>
|
|
34 |
#include <errno.h>
|
|
35 |
#include "libproc.h"
|
|
36 |
|
|
37 |
static const char *
|
|
38 |
rawfltname(int flt)
|
|
39 |
{
|
|
40 |
const char *name;
|
|
41 |
|
|
42 |
switch (flt) {
|
|
43 |
case FLTILL: name = "FLTILL"; break;
|
|
44 |
case FLTPRIV: name = "FLTPRIV"; break;
|
|
45 |
case FLTBPT: name = "FLTBPT"; break;
|
|
46 |
case FLTTRACE: name = "FLTTRACE"; break;
|
|
47 |
case FLTACCESS: name = "FLTACCESS"; break;
|
|
48 |
case FLTBOUNDS: name = "FLTBOUNDS"; break;
|
|
49 |
case FLTIOVF: name = "FLTIOVF"; break;
|
|
50 |
case FLTIZDIV: name = "FLTIZDIV"; break;
|
|
51 |
case FLTFPE: name = "FLTFPE"; break;
|
|
52 |
case FLTSTACK: name = "FLTSTACK"; break;
|
|
53 |
case FLTPAGE: name = "FLTPAGE"; break;
|
|
54 |
case FLTWATCH: name = "FLTWATCH"; break;
|
|
55 |
case FLTCPCOVF: name = "FLTCPCOVF"; break;
|
|
56 |
default: name = NULL; break;
|
|
57 |
}
|
|
58 |
|
|
59 |
return (name);
|
|
60 |
}
|
|
61 |
|
|
62 |
/*
|
|
63 |
* Return the name of a fault.
|
|
64 |
* Manufacture a name for unknown fault.
|
|
65 |
*/
|
|
66 |
char *
|
|
67 |
proc_fltname(int flt, char *buf, size_t bufsz)
|
|
68 |
{
|
|
69 |
const char *name = rawfltname(flt);
|
|
70 |
size_t len;
|
|
71 |
|
|
72 |
if (bufsz == 0) /* force a program failure */
|
|
73 |
return (NULL);
|
|
74 |
|
|
75 |
if (name != NULL) {
|
|
76 |
len = strlen(name);
|
|
77 |
(void) strncpy(buf, name, bufsz);
|
|
78 |
} else {
|
|
79 |
len = snprintf(buf, bufsz, "FLT#%d", flt);
|
|
80 |
}
|
|
81 |
|
|
82 |
if (len >= bufsz) /* ensure null-termination */
|
|
83 |
buf[bufsz-1] = '\0';
|
|
84 |
|
|
85 |
return (buf);
|
|
86 |
}
|
|
87 |
|
|
88 |
/*
|
|
89 |
* Return the name of a signal.
|
|
90 |
* Manufacture a name for unknown signal.
|
|
91 |
*/
|
|
92 |
char *
|
|
93 |
proc_signame(int sig, char *buf, size_t bufsz)
|
|
94 |
{
|
|
95 |
char name[SIG2STR_MAX+4];
|
|
96 |
size_t len;
|
|
97 |
|
|
98 |
if (bufsz == 0) /* force a program failure */
|
|
99 |
return (NULL);
|
|
100 |
|
|
101 |
/* sig2str() omits the leading "SIG" */
|
|
102 |
(void) strcpy(name, "SIG");
|
|
103 |
|
|
104 |
if (sig2str(sig, name+3) == 0) {
|
|
105 |
len = strlen(name);
|
|
106 |
(void) strncpy(buf, name, bufsz);
|
|
107 |
} else {
|
|
108 |
len = snprintf(buf, bufsz, "SIG#%d", sig);
|
|
109 |
}
|
|
110 |
|
|
111 |
if (len >= bufsz) /* ensure null-termination */
|
|
112 |
buf[bufsz-1] = '\0';
|
|
113 |
|
|
114 |
return (buf);
|
|
115 |
}
|
|
116 |
|
|
117 |
static const char *const systable[] = {
|
|
118 |
NULL, /* 0 */
|
|
119 |
"_exit", /* 1 */
|
|
120 |
"forkall", /* 2 */
|
|
121 |
"read", /* 3 */
|
|
122 |
"write", /* 4 */
|
|
123 |
"open", /* 5 */
|
|
124 |
"close", /* 6 */
|
|
125 |
"wait", /* 7 */
|
|
126 |
"creat", /* 8 */
|
|
127 |
"link", /* 9 */
|
|
128 |
"unlink", /* 10 */
|
|
129 |
"exec", /* 11 */
|
|
130 |
"chdir", /* 12 */
|
|
131 |
"time", /* 13 */
|
|
132 |
"mknod", /* 14 */
|
|
133 |
"chmod", /* 15 */
|
|
134 |
"chown", /* 16 */
|
|
135 |
"brk", /* 17 */
|
|
136 |
"stat", /* 18 */
|
|
137 |
"lseek", /* 19 */
|
|
138 |
"getpid", /* 20 */
|
|
139 |
"mount", /* 21 */
|
|
140 |
"umount", /* 22 */
|
|
141 |
"setuid", /* 23 */
|
|
142 |
"getuid", /* 24 */
|
|
143 |
"stime", /* 25 */
|
|
144 |
"ptrace", /* 26 */
|
|
145 |
"alarm", /* 27 */
|
|
146 |
"fstat", /* 28 */
|
|
147 |
"pause", /* 29 */
|
|
148 |
"utime", /* 30 */
|
|
149 |
"stty", /* 31 */
|
|
150 |
"gtty", /* 32 */
|
|
151 |
"access", /* 33 */
|
|
152 |
"nice", /* 34 */
|
|
153 |
"statfs", /* 35 */
|
|
154 |
"sync", /* 36 */
|
|
155 |
"kill", /* 37 */
|
|
156 |
"fstatfs", /* 38 */
|
|
157 |
"pgrpsys", /* 39 */
|
2712
|
158 |
"uucopystr", /* 40 */
|
0
|
159 |
"dup", /* 41 */
|
|
160 |
"pipe", /* 42 */
|
|
161 |
"times", /* 43 */
|
|
162 |
"profil", /* 44 */
|
|
163 |
"plock", /* 45 */
|
|
164 |
"setgid", /* 46 */
|
|
165 |
"getgid", /* 47 */
|
|
166 |
"signal", /* 48 */
|
|
167 |
"msgsys", /* 49 */
|
|
168 |
"sysi86", /* 50 */
|
|
169 |
"acct", /* 51 */
|
|
170 |
"shmsys", /* 52 */
|
|
171 |
"semsys", /* 53 */
|
|
172 |
"ioctl", /* 54 */
|
|
173 |
"uadmin", /* 55 */
|
|
174 |
NULL, /* 56 */
|
|
175 |
"utssys", /* 57 */
|
|
176 |
"fdsync", /* 58 */
|
|
177 |
"execve", /* 59 */
|
|
178 |
"umask", /* 60 */
|
|
179 |
"chroot", /* 61 */
|
|
180 |
"fcntl", /* 62 */
|
|
181 |
"ulimit", /* 63 */
|
|
182 |
|
|
183 |
/* The following 6 entries were reserved for the UNIX PC */
|
|
184 |
NULL, /* 64 */
|
|
185 |
NULL, /* 65 */
|
|
186 |
NULL, /* 66 */
|
|
187 |
NULL, /* 67 */
|
|
188 |
NULL, /* 68 */
|
|
189 |
NULL, /* 69 */
|
|
190 |
|
|
191 |
"tasksys", /* 70 */
|
|
192 |
"acctctl", /* 71 */
|
|
193 |
"exacctsys", /* 72 */
|
|
194 |
"getpagesizes", /* 73 */
|
|
195 |
"rctlsys", /* 74 */
|
|
196 |
"issetugid", /* 75 */
|
|
197 |
"fsat", /* 76 */
|
|
198 |
"lwp_park", /* 77 */
|
|
199 |
"sendfilev", /* 78 */
|
|
200 |
"rmdir", /* 79 */
|
|
201 |
"mkdir", /* 80 */
|
|
202 |
"getdents", /* 81 */
|
|
203 |
"privsys", /* 82 */
|
|
204 |
"ucredsys", /* 83 */
|
|
205 |
"sysfs", /* 84 */
|
|
206 |
"getmsg", /* 85 */
|
|
207 |
"putmsg", /* 86 */
|
|
208 |
"poll", /* 87 */
|
|
209 |
"lstat", /* 88 */
|
|
210 |
"symlink", /* 89 */
|
|
211 |
"readlink", /* 90 */
|
|
212 |
"setgroups", /* 91 */
|
|
213 |
"getgroups", /* 92 */
|
|
214 |
"fchmod", /* 93 */
|
|
215 |
"fchown", /* 94 */
|
|
216 |
"sigprocmask", /* 95 */
|
|
217 |
"sigsuspend", /* 96 */
|
|
218 |
"sigaltstack", /* 97 */
|
|
219 |
"sigaction", /* 98 */
|
|
220 |
"sigpending", /* 99 */
|
|
221 |
"context", /* 100 */
|
|
222 |
"evsys", /* 101 */
|
|
223 |
"evtrapret", /* 102 */
|
|
224 |
"statvfs", /* 103 */
|
|
225 |
"fstatvfs", /* 104 */
|
|
226 |
"getloadavg", /* 105 */
|
|
227 |
"nfssys", /* 106 */
|
|
228 |
"waitid", /* 107 */
|
|
229 |
"sigsendsys", /* 108 */
|
|
230 |
"hrtsys", /* 109 */
|
|
231 |
"acancel", /* 110 */
|
|
232 |
"async", /* 111 */
|
|
233 |
"priocntlsys", /* 112 */
|
|
234 |
"pathconf", /* 113 */
|
|
235 |
"mincore", /* 114 */
|
|
236 |
"mmap", /* 115 */
|
|
237 |
"mprotect", /* 116 */
|
|
238 |
"munmap", /* 117 */
|
|
239 |
"fpathconf", /* 118 */
|
|
240 |
"vfork", /* 119 */
|
|
241 |
"fchdir", /* 120 */
|
|
242 |
"readv", /* 121 */
|
|
243 |
"writev", /* 122 */
|
|
244 |
"xstat", /* 123 */
|
|
245 |
"lxstat", /* 124 */
|
|
246 |
"fxstat", /* 125 */
|
|
247 |
"xmknod", /* 126 */
|
|
248 |
"NULL", /* 127 */
|
|
249 |
"setrlimit", /* 128 */
|
|
250 |
"getrlimit", /* 129 */
|
|
251 |
"lchown", /* 130 */
|
|
252 |
"memcntl", /* 131 */
|
|
253 |
"getpmsg", /* 132 */
|
|
254 |
"putpmsg", /* 133 */
|
|
255 |
"rename", /* 134 */
|
|
256 |
"uname", /* 135 */
|
|
257 |
"setegid", /* 136 */
|
|
258 |
"sysconfig", /* 137 */
|
|
259 |
"adjtime", /* 138 */
|
|
260 |
"systeminfo", /* 139 */
|
3957
|
261 |
"sharefs", /* 140 */
|
0
|
262 |
"seteuid", /* 141 */
|
|
263 |
NULL, /* 142 */
|
|
264 |
"fork1", /* 143 */
|
|
265 |
"sigtimedwait", /* 144 */
|
|
266 |
"lwp_info", /* 145 */
|
|
267 |
"yield", /* 146 */
|
|
268 |
"lwp_sema_wait", /* 147 */
|
|
269 |
"lwp_sema_post", /* 148 */
|
|
270 |
"lwp_sema_trywait", /* 149 */
|
|
271 |
"lwp_detatch", /* 150 */
|
|
272 |
"corectl", /* 151 */
|
|
273 |
"modctl", /* 152 */
|
|
274 |
"fchroot", /* 153 */
|
|
275 |
"utimes", /* 154 */
|
|
276 |
"vhangup", /* 155 */
|
|
277 |
"gettimeofday", /* 156 */
|
|
278 |
"getitimer", /* 157 */
|
|
279 |
"setitimer", /* 158 */
|
|
280 |
"lwp_create", /* 159 */
|
|
281 |
"lwp_exit", /* 160 */
|
|
282 |
"lwp_suspend", /* 161 */
|
|
283 |
"lwp_continue", /* 162 */
|
|
284 |
"lwp_kill", /* 163 */
|
|
285 |
"lwp_self", /* 164 */
|
|
286 |
"lwp_sigmask", /* 165 */
|
|
287 |
"lwp_private", /* 166 */
|
|
288 |
"lwp_wait", /* 167 */
|
|
289 |
"lwp_mutex_unlock", /* 168 */
|
|
290 |
"lwp_mutex_lock", /* 169 */
|
|
291 |
"lwp_cond_wait", /* 170 */
|
|
292 |
"lwp_cond_signal", /* 171 */
|
|
293 |
"lwp_cond_broadcast", /* 172 */
|
|
294 |
"pread", /* 173 */
|
|
295 |
"pwrite", /* 174 */
|
|
296 |
"llseek", /* 175 */
|
|
297 |
"inst_sync", /* 176 */
|
2712
|
298 |
"brand", /* 177 */
|
0
|
299 |
"kaio", /* 178 */
|
|
300 |
"cpc", /* 179 */
|
|
301 |
"lgrpsys", /* 180 */
|
|
302 |
"rusagesys", /* 181 */
|
|
303 |
"portfs", /* 182 */
|
|
304 |
"pollsys", /* 183 */
|
|
305 |
NULL, /* 184 */
|
|
306 |
"acl", /* 185 */
|
|
307 |
"auditsys", /* 186 */
|
|
308 |
"processor_bind", /* 187 */
|
|
309 |
"processor_info", /* 188 */
|
|
310 |
"p_online", /* 189 */
|
|
311 |
"sigqueue", /* 190 */
|
|
312 |
"clock_gettime", /* 191 */
|
|
313 |
"clock_settime", /* 192 */
|
|
314 |
"clock_getres", /* 193 */
|
|
315 |
"timer_create", /* 194 */
|
|
316 |
"timer_delete", /* 195 */
|
|
317 |
"timer_settime", /* 196 */
|
|
318 |
"timer_gettime", /* 197 */
|
|
319 |
"timer_getoverrun", /* 198 */
|
|
320 |
"nanosleep", /* 199 */
|
|
321 |
"facl", /* 200 */
|
|
322 |
"door", /* 201 */
|
|
323 |
"setreuid", /* 202 */
|
|
324 |
"setregid", /* 203 */
|
|
325 |
"install_utrap", /* 204 */
|
|
326 |
"signotify", /* 205 */
|
|
327 |
"schedctl", /* 206 */
|
|
328 |
"pset", /* 207 */
|
|
329 |
"sparc_utrap_install", /* 208 */
|
|
330 |
"resolvepath", /* 209 */
|
|
331 |
"lwp_mutex_timedlock", /* 210 */
|
|
332 |
"lwp_sema_timedwait", /* 211 */
|
|
333 |
"lwp_rwlock_sys", /* 212 */
|
|
334 |
"getdents64", /* 213 */
|
|
335 |
"mmap64", /* 214 */
|
|
336 |
"stat64", /* 215 */
|
|
337 |
"lstat64", /* 216 */
|
|
338 |
"fstat64", /* 217 */
|
|
339 |
"statvfs64", /* 218 */
|
|
340 |
"fstatvfs64", /* 219 */
|
|
341 |
"setrlimit64", /* 220 */
|
|
342 |
"getrlimit64", /* 221 */
|
|
343 |
"pread64", /* 222 */
|
|
344 |
"pwrite64", /* 223 */
|
|
345 |
"creat64", /* 224 */
|
|
346 |
"open64", /* 225 */
|
|
347 |
"rpcmod", /* 226 */
|
|
348 |
"zone", /* 227 */
|
|
349 |
"autofssys", /* 228 */
|
|
350 |
"getcwd", /* 229 */
|
|
351 |
"so_socket", /* 230 */
|
|
352 |
"so_socketpair", /* 231 */
|
|
353 |
"bind", /* 232 */
|
|
354 |
"listen", /* 233 */
|
|
355 |
"accept", /* 234 */
|
|
356 |
"connect", /* 235 */
|
|
357 |
"shutdown", /* 236 */
|
|
358 |
"recv", /* 237 */
|
|
359 |
"recvfrom", /* 238 */
|
|
360 |
"recvmsg", /* 239 */
|
|
361 |
"send", /* 240 */
|
|
362 |
"sendmsg", /* 241 */
|
|
363 |
"sendto", /* 242 */
|
|
364 |
"getpeername", /* 243 */
|
|
365 |
"getsockname", /* 244 */
|
|
366 |
"getsockopt", /* 245 */
|
|
367 |
"setsockopt", /* 246 */
|
|
368 |
"sockconfig", /* 247 */
|
|
369 |
"ntp_gettime", /* 248 */
|
|
370 |
"ntp_adjtime", /* 249 */
|
|
371 |
"lwp_mutex_unlock", /* 250 */
|
|
372 |
"lwp_mutex_trylock", /* 251 */
|
|
373 |
"lwp_mutex_init", /* 252 */
|
|
374 |
"cladm", /* 253 */
|
2712
|
375 |
"uucopy", /* 254 */
|
0
|
376 |
"umount2" /* 255 */
|
|
377 |
};
|
|
378 |
|
|
379 |
/* SYSEND == max syscall number + 1 */
|
|
380 |
#define SYSEND (sizeof (systable) / sizeof (systable[0]))
|
|
381 |
|
|
382 |
/*
|
|
383 |
* Return the name of a system call.
|
|
384 |
* Manufacture a name for unknown system call.
|
|
385 |
*/
|
|
386 |
char *
|
|
387 |
proc_sysname(int sys, char *buf, size_t bufsz)
|
|
388 |
{
|
|
389 |
const char *name;
|
|
390 |
size_t len;
|
|
391 |
|
|
392 |
if (bufsz == 0) /* force a program failure */
|
|
393 |
return (NULL);
|
|
394 |
|
|
395 |
if (sys >= 0 && sys < SYSEND)
|
|
396 |
name = systable[sys];
|
|
397 |
else
|
|
398 |
name = NULL;
|
|
399 |
|
|
400 |
if (name != NULL) {
|
|
401 |
len = strlen(name);
|
|
402 |
(void) strncpy(buf, name, bufsz);
|
|
403 |
} else {
|
|
404 |
len = snprintf(buf, bufsz, "SYS#%d", sys);
|
|
405 |
}
|
|
406 |
|
|
407 |
if (len >= bufsz) /* ensure null-termination */
|
|
408 |
buf[bufsz-1] = '\0';
|
|
409 |
|
|
410 |
return (buf);
|
|
411 |
}
|
|
412 |
|
|
413 |
/*
|
|
414 |
* Convert a string representation of a fault to the corresponding number.
|
|
415 |
*/
|
|
416 |
int
|
|
417 |
proc_str2flt(const char *str, int *fltnum)
|
|
418 |
{
|
|
419 |
char *next;
|
|
420 |
int i;
|
|
421 |
|
|
422 |
i = strtol(str, &next, 0);
|
|
423 |
if (i > 0 && i <= PRMAXFAULT && *next == '\0') {
|
|
424 |
*fltnum = i;
|
|
425 |
return (0);
|
|
426 |
}
|
|
427 |
|
|
428 |
for (i = 1; i <= PRMAXFAULT; i++) {
|
|
429 |
const char *s = rawfltname(i);
|
|
430 |
|
|
431 |
if (s && (strcasecmp(s, str) == 0 ||
|
|
432 |
strcasecmp(s + 3, str) == 0)) {
|
|
433 |
*fltnum = i;
|
|
434 |
return (0);
|
|
435 |
}
|
|
436 |
}
|
|
437 |
|
|
438 |
return (-1);
|
|
439 |
}
|
|
440 |
|
|
441 |
/*
|
|
442 |
* Convert a string representation of a signal to the signal number. This
|
|
443 |
* functionality is already available in libc, but the interface doesn't
|
|
444 |
* optionally accept a "SIG" prefix. We strip that first, and then call libc.
|
|
445 |
*/
|
|
446 |
int
|
|
447 |
proc_str2sig(const char *str, int *signum)
|
|
448 |
{
|
|
449 |
if (strncasecmp(str, "SIG", 3) == 0)
|
|
450 |
str += 3; /* skip prefix */
|
|
451 |
|
|
452 |
return (str2sig(str, signum));
|
|
453 |
}
|
|
454 |
|
|
455 |
/*
|
|
456 |
* Convert a string representation of a system call to the corresponding number.
|
|
457 |
* We do this by performing a simple linear search of the table above.
|
|
458 |
*/
|
|
459 |
int
|
|
460 |
proc_str2sys(const char *str, int *sysnum)
|
|
461 |
{
|
|
462 |
char *next;
|
|
463 |
int i;
|
|
464 |
|
|
465 |
i = strtol(str, &next, 0);
|
|
466 |
if (i > 0 && i <= PRMAXSYS && *next == '\0') {
|
|
467 |
*sysnum = i;
|
|
468 |
return (0);
|
|
469 |
}
|
|
470 |
|
|
471 |
for (i = 1; i < SYSEND; i++) {
|
|
472 |
if (systable[i] != NULL && strcmp(systable[i], str) == 0) {
|
|
473 |
*sysnum = i;
|
|
474 |
return (0);
|
|
475 |
}
|
|
476 |
}
|
|
477 |
|
|
478 |
return (-1);
|
|
479 |
}
|
|
480 |
|
|
481 |
/*
|
|
482 |
* Convert a fltset_t to a string representation consisting of canonical
|
|
483 |
* machine fault names separated by the given delimeter string. If
|
|
484 |
* m is non-zero (TRUE), set members are printed. If m is zero (FALSE), set
|
|
485 |
* non-members are printed. If the specified buf is too small to hold the
|
|
486 |
* complete formatted set, NULL is returned; otherwise buf is returned.
|
|
487 |
*/
|
|
488 |
char *
|
|
489 |
proc_fltset2str(const fltset_t *set, const char *delim, int m,
|
|
490 |
char *buf, size_t len)
|
|
491 |
{
|
|
492 |
char name[FLT2STR_MAX], *p = buf;
|
|
493 |
size_t n;
|
|
494 |
int i;
|
|
495 |
|
|
496 |
if (buf == NULL || len < 1) {
|
|
497 |
errno = EINVAL;
|
|
498 |
return (NULL);
|
|
499 |
}
|
|
500 |
|
|
501 |
buf[0] = '\0'; /* Set first byte to \0 */
|
|
502 |
|
|
503 |
for (i = 1; i <= PRMAXFAULT; i++) {
|
|
504 |
if ((prismember(set, i) != 0) ^ (m == 0)) {
|
|
505 |
(void) proc_fltname(i, name, sizeof (name));
|
|
506 |
|
|
507 |
if (buf[0] != '\0')
|
|
508 |
n = snprintf(p, len, "%s%s", delim, name);
|
|
509 |
else
|
|
510 |
n = snprintf(p, len, "%s", name);
|
|
511 |
|
|
512 |
if (n != strlen(p)) {
|
|
513 |
errno = ENAMETOOLONG; /* Output was truncated */
|
|
514 |
return (NULL);
|
|
515 |
}
|
|
516 |
len -= n;
|
|
517 |
p += n;
|
|
518 |
}
|
|
519 |
}
|
|
520 |
return (buf);
|
|
521 |
}
|
|
522 |
|
|
523 |
/*
|
|
524 |
* Convert a sigset_t to a string representation consisting of canonical signal
|
|
525 |
* names (without the SIG prefix). Parameters and return values analogous to
|
|
526 |
* proc_fltset2str().
|
|
527 |
*/
|
|
528 |
char *
|
|
529 |
proc_sigset2str(const sigset_t *set, const char *delim, int m,
|
|
530 |
char *buf, size_t len)
|
|
531 |
{
|
|
532 |
char name[SIG2STR_MAX], *p = buf;
|
|
533 |
size_t n;
|
|
534 |
int i;
|
|
535 |
|
|
536 |
if (buf == NULL || len < 1) {
|
|
537 |
errno = EINVAL;
|
|
538 |
return (NULL);
|
|
539 |
}
|
|
540 |
|
|
541 |
m = (m != 0); /* Make sure m is 0 or 1 */
|
|
542 |
buf[0] = '\0'; /* Set first byte to \0 */
|
|
543 |
|
|
544 |
/*
|
|
545 |
* Unlike proc_fltset2str() and proc_sysset2str(), we don't loop
|
|
546 |
* until i <= NSIG here, because sigismember() rejects i == NSIG.
|
|
547 |
*/
|
|
548 |
for (i = 1; i < NSIG; i++) {
|
|
549 |
if (sigismember(set, i) == m) {
|
|
550 |
(void) sig2str(i, name);
|
|
551 |
|
|
552 |
if (buf[0] != '\0')
|
|
553 |
n = snprintf(p, len, "%s%s", delim, name);
|
|
554 |
else
|
|
555 |
n = snprintf(p, len, "%s", name);
|
|
556 |
|
|
557 |
if (n != strlen(p)) {
|
|
558 |
errno = ENAMETOOLONG; /* Output was truncated */
|
|
559 |
return (NULL);
|
|
560 |
}
|
|
561 |
|
|
562 |
len -= n;
|
|
563 |
p += n;
|
|
564 |
}
|
|
565 |
}
|
|
566 |
|
|
567 |
return (buf);
|
|
568 |
}
|
|
569 |
|
|
570 |
/*
|
|
571 |
* Convert a sysset_t to a string representation consisting of canonical system
|
|
572 |
* call names. Parameters and return values analogous to proc_fltset2str().
|
|
573 |
*/
|
|
574 |
char *
|
|
575 |
proc_sysset2str(const sysset_t *set, const char *delim, int m,
|
|
576 |
char *buf, size_t len)
|
|
577 |
{
|
|
578 |
char name[SYS2STR_MAX], *p = buf;
|
|
579 |
size_t n;
|
|
580 |
int i;
|
|
581 |
|
|
582 |
if (buf == NULL || len < 1) {
|
|
583 |
errno = EINVAL;
|
|
584 |
return (NULL);
|
|
585 |
}
|
|
586 |
|
|
587 |
buf[0] = '\0'; /* Set first byte to \0 */
|
|
588 |
|
|
589 |
for (i = 1; i <= PRMAXSYS; i++) {
|
|
590 |
if ((prismember(set, i) != 0) ^ (m == 0)) {
|
|
591 |
(void) proc_sysname(i, name, sizeof (name));
|
|
592 |
|
|
593 |
if (buf[0] != '\0')
|
|
594 |
n = snprintf(p, len, "%s%s", delim, name);
|
|
595 |
else
|
|
596 |
n = snprintf(p, len, "%s", name);
|
|
597 |
|
|
598 |
if (n != strlen(p)) {
|
|
599 |
errno = ENAMETOOLONG; /* Output was truncated */
|
|
600 |
return (NULL);
|
|
601 |
}
|
|
602 |
len -= n;
|
|
603 |
p += n;
|
|
604 |
}
|
|
605 |
}
|
|
606 |
return (buf);
|
|
607 |
}
|
|
608 |
|
|
609 |
/*
|
|
610 |
* Convert a string representation of a fault set (names separated by
|
|
611 |
* one or more of the given delimeters) to a fltset_t.
|
|
612 |
* If m is non-zero (TRUE), members of the string representation are set.
|
|
613 |
* If m is zero (FALSE), non-members of the string representation are set.
|
|
614 |
* This function returns NULL for success. Otherwise it returns a pointer
|
|
615 |
* to the token of the string that couldn't be identified as a string
|
|
616 |
* representation of a fault.
|
|
617 |
*/
|
|
618 |
char *
|
|
619 |
proc_str2fltset(const char *s, const char *delim, int m, fltset_t *set)
|
|
620 |
{
|
|
621 |
char *p, *q, *t = alloca(strlen(s) + 1);
|
|
622 |
int flt;
|
|
623 |
|
|
624 |
if (m) {
|
|
625 |
premptyset(set);
|
|
626 |
} else {
|
|
627 |
prfillset(set);
|
|
628 |
}
|
|
629 |
|
|
630 |
(void) strcpy(t, s);
|
|
631 |
|
|
632 |
for (p = strtok_r(t, delim, &q); p != NULL;
|
|
633 |
p = strtok_r(NULL, delim, &q)) {
|
|
634 |
if (proc_str2flt(p, &flt) == -1) {
|
|
635 |
errno = EINVAL;
|
|
636 |
return ((char *)s + (p - t));
|
|
637 |
}
|
|
638 |
if (m)
|
|
639 |
praddset(set, flt);
|
|
640 |
else
|
|
641 |
prdelset(set, flt);
|
|
642 |
}
|
|
643 |
return (NULL);
|
|
644 |
}
|
|
645 |
|
|
646 |
/*
|
|
647 |
* Convert a string representation of a signal set (names with or without the
|
|
648 |
* SIG prefix separated by one or more of the given delimeters) to a sigset_t.
|
|
649 |
* Parameters and return values analogous to proc_str2fltset().
|
|
650 |
*/
|
|
651 |
char *
|
|
652 |
proc_str2sigset(const char *s, const char *delim, int m, sigset_t *set)
|
|
653 |
{
|
|
654 |
char *p, *q, *t = alloca(strlen(s) + 1);
|
|
655 |
int sig;
|
|
656 |
|
|
657 |
if (m) {
|
|
658 |
premptyset(set);
|
|
659 |
} else {
|
|
660 |
prfillset(set);
|
|
661 |
}
|
|
662 |
|
|
663 |
(void) strcpy(t, s);
|
|
664 |
|
|
665 |
for (p = strtok_r(t, delim, &q); p != NULL;
|
|
666 |
p = strtok_r(NULL, delim, &q)) {
|
|
667 |
if (proc_str2sig(p, &sig) == -1) {
|
|
668 |
errno = EINVAL;
|
|
669 |
return ((char *)s + (p - t));
|
|
670 |
}
|
|
671 |
if (m)
|
|
672 |
praddset(set, sig);
|
|
673 |
else
|
|
674 |
prdelset(set, sig);
|
|
675 |
}
|
|
676 |
return (NULL);
|
|
677 |
}
|
|
678 |
|
|
679 |
/*
|
|
680 |
* Convert a string representation of a system call set (names separated by
|
|
681 |
* one or more of the given delimeters) to a sysset_t. Parameters and return
|
|
682 |
* values analogous to proc_str2fltset().
|
|
683 |
*/
|
|
684 |
char *
|
|
685 |
proc_str2sysset(const char *s, const char *delim, int m, sysset_t *set)
|
|
686 |
{
|
|
687 |
char *p, *q, *t = alloca(strlen(s) + 1);
|
|
688 |
int sys;
|
|
689 |
|
|
690 |
if (m) {
|
|
691 |
premptyset(set);
|
|
692 |
} else {
|
|
693 |
prfillset(set);
|
|
694 |
}
|
|
695 |
|
|
696 |
(void) strcpy(t, s);
|
|
697 |
|
|
698 |
for (p = strtok_r(t, delim, &q); p != NULL;
|
|
699 |
p = strtok_r(NULL, delim, &q)) {
|
|
700 |
if (proc_str2sys(p, &sys) == -1) {
|
|
701 |
errno = EINVAL;
|
|
702 |
return ((char *)s + (p - t));
|
|
703 |
}
|
|
704 |
if (m)
|
|
705 |
praddset(set, sys);
|
|
706 |
else
|
|
707 |
prdelset(set, sys);
|
|
708 |
}
|
|
709 |
return (NULL);
|
|
710 |
}
|