4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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.
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]
23 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2015, Joyent, Inc. All rights reserved.
28 #define __EXTENSIONS__
41 case FLTILL
: name
= "FLTILL"; break;
42 case FLTPRIV
: name
= "FLTPRIV"; break;
43 case FLTBPT
: name
= "FLTBPT"; break;
44 case FLTTRACE
: name
= "FLTTRACE"; break;
45 case FLTACCESS
: name
= "FLTACCESS"; break;
46 case FLTBOUNDS
: name
= "FLTBOUNDS"; break;
47 case FLTIOVF
: name
= "FLTIOVF"; break;
48 case FLTIZDIV
: name
= "FLTIZDIV"; break;
49 case FLTFPE
: name
= "FLTFPE"; break;
50 case FLTSTACK
: name
= "FLTSTACK"; break;
51 case FLTPAGE
: name
= "FLTPAGE"; break;
52 case FLTWATCH
: name
= "FLTWATCH"; break;
53 case FLTCPCOVF
: name
= "FLTCPCOVF"; break;
54 default: name
= NULL
; break;
61 * Return the name of a fault.
62 * Manufacture a name for unknown fault.
65 proc_fltname(int flt
, char *buf
, size_t bufsz
)
67 const char *name
= rawfltname(flt
);
70 if (bufsz
== 0) /* force a program failure */
75 (void) strncpy(buf
, name
, bufsz
);
77 len
= snprintf(buf
, bufsz
, "FLT#%d", flt
);
80 if (len
>= bufsz
) /* ensure null-termination */
87 * Return the name of a signal.
88 * Manufacture a name for unknown signal.
91 proc_signame(int sig
, char *buf
, size_t bufsz
)
93 char name
[SIG2STR_MAX
+4];
96 if (bufsz
== 0) /* force a program failure */
99 /* sig2str() omits the leading "SIG" */
100 (void) strcpy(name
, "SIG");
102 if (sig2str(sig
, name
+3) == 0) {
104 (void) strncpy(buf
, name
, bufsz
);
106 len
= snprintf(buf
, bufsz
, "SIG#%d", sig
);
109 if (len
>= bufsz
) /* ensure null-termination */
115 static const char *const systable
[] = {
127 "symlinkat", /* 11 */
138 "readlinkat", /* 22 */
156 "uucopystr", /* 40 */
161 "faccessat", /* 45 */
183 "fstatat64", /* 67 */
188 "exacctsys", /* 72 */
189 "getpagesizes", /* 73 */
191 "issetugid", /* 75 */
194 "sendfilev", /* 78 */
207 "setgroups", /* 91 */
208 "getgroups", /* 92 */
211 "sigprocmask", /* 95 */
212 "sigsuspend", /* 96 */
213 "sigaltstack", /* 97 */
214 "sigaction", /* 98 */
215 "sigpending", /* 99 */
217 "fchmodat", /* 101 */
220 "fstatvfs", /* 104 */
221 "getloadavg", /* 105 */
224 "sigsendsys", /* 108 */
228 "priocntlsys", /* 112 */
229 "pathconf", /* 113 */
232 "mprotect", /* 116 */
234 "fpathconf", /* 118 */
242 "getrandom", /* 126 */
244 "setrlimit", /* 128 */
245 "getrlimit", /* 129 */
253 "sysconfig", /* 137 */
255 "systeminfo", /* 139 */
260 "sigtimedwait", /* 144 */
261 "lwp_info", /* 145 */
264 "lwp_sema_post", /* 148 */
265 "lwp_sema_trywait", /* 149 */
266 "lwp_detatch", /* 150 */
272 "gettimeofday", /* 156 */
273 "getitimer", /* 157 */
274 "setitimer", /* 158 */
275 "lwp_create", /* 159 */
276 "lwp_exit", /* 160 */
277 "lwp_suspend", /* 161 */
278 "lwp_continue", /* 162 */
279 "lwp_kill", /* 163 */
280 "lwp_self", /* 164 */
281 "lwp_sigmask", /* 165 */
282 "lwp_private", /* 166 */
283 "lwp_wait", /* 167 */
284 "lwp_mutex_wakeup", /* 168 */
286 "lwp_cond_wait", /* 170 */
287 "lwp_cond_signal", /* 171 */
288 "lwp_cond_broadcast", /* 172 */
292 "inst_sync", /* 176 */
297 "rusagesys", /* 181 */
300 "labelsys", /* 184 */
302 "auditsys", /* 186 */
303 "processor_bind", /* 187 */
304 "processor_info", /* 188 */
305 "p_online", /* 189 */
306 "sigqueue", /* 190 */
307 "clock_gettime", /* 191 */
308 "clock_settime", /* 192 */
309 "clock_getres", /* 193 */
310 "timer_create", /* 194 */
311 "timer_delete", /* 195 */
312 "timer_settime", /* 196 */
313 "timer_gettime", /* 197 */
314 "timer_getoverrun", /* 198 */
315 "nanosleep", /* 199 */
318 "setreuid", /* 202 */
319 "setregid", /* 203 */
320 "install_utrap", /* 204 */
321 "signotify", /* 205 */
322 "schedctl", /* 206 */
324 "sparc_utrap_install", /* 208 */
325 "resolvepath", /* 209 */
326 "lwp_mutex_timedlock", /* 210 */
327 "lwp_sema_timedwait", /* 211 */
328 "lwp_rwlock_sys", /* 212 */
329 "getdents64", /* 213 */
334 "statvfs64", /* 218 */
335 "fstatvfs64", /* 219 */
336 "setrlimit64", /* 220 */
337 "getrlimit64", /* 221 */
339 "pwrite64", /* 223 */
344 "autofssys", /* 228 */
346 "so_socket", /* 230 */
347 "so_socketpair", /* 231 */
352 "shutdown", /* 236 */
354 "recvfrom", /* 238 */
359 "getpeername", /* 243 */
360 "getsockname", /* 244 */
361 "getsockopt", /* 245 */
362 "setsockopt", /* 246 */
363 "sockconfig", /* 247 */
364 "ntp_gettime", /* 248 */
365 "ntp_adjtime", /* 249 */
366 "lwp_mutex_unlock", /* 250 */
367 "lwp_mutex_trylock", /* 251 */
368 "lwp_mutex_register", /* 252 */
374 /* SYSEND == max syscall number + 1 */
375 #define SYSEND (sizeof (systable) / sizeof (systable[0]))
378 * Return the name of a system call.
379 * Manufacture a name for unknown system call.
382 proc_sysname(int sys
, char *buf
, size_t bufsz
)
387 if (bufsz
== 0) /* force a program failure */
390 if (sys
>= 0 && sys
< SYSEND
)
391 name
= systable
[sys
];
397 (void) strncpy(buf
, name
, bufsz
);
399 len
= snprintf(buf
, bufsz
, "SYS#%d", sys
);
402 if (len
>= bufsz
) /* ensure null-termination */
409 * Convert a string representation of a fault to the corresponding number.
412 proc_str2flt(const char *str
, int *fltnum
)
417 i
= strtol(str
, &next
, 0);
418 if (i
> 0 && i
<= PRMAXFAULT
&& *next
== '\0') {
423 for (i
= 1; i
<= PRMAXFAULT
; i
++) {
424 const char *s
= rawfltname(i
);
426 if (s
&& (strcasecmp(s
, str
) == 0 ||
427 strcasecmp(s
+ 3, str
) == 0)) {
437 * Convert a string representation of a signal to the signal number. This
438 * functionality is already available in libc, but the interface doesn't
439 * optionally accept a "SIG" prefix. We strip that first, and then call libc.
442 proc_str2sig(const char *str
, int *signum
)
444 if (strncasecmp(str
, "SIG", 3) == 0)
445 str
+= 3; /* skip prefix */
447 return (str2sig(str
, signum
));
451 * Convert a string representation of a system call to the corresponding number.
452 * We do this by performing a simple linear search of the table above.
455 proc_str2sys(const char *str
, int *sysnum
)
460 i
= strtol(str
, &next
, 0);
461 if (i
> 0 && i
<= PRMAXSYS
&& *next
== '\0') {
466 for (i
= 1; i
< SYSEND
; i
++) {
467 if (systable
[i
] != NULL
&& strcmp(systable
[i
], str
) == 0) {
477 * Convert a fltset_t to a string representation consisting of canonical
478 * machine fault names separated by the given delimeter string. If
479 * m is non-zero (TRUE), set members are printed. If m is zero (FALSE), set
480 * non-members are printed. If the specified buf is too small to hold the
481 * complete formatted set, NULL is returned; otherwise buf is returned.
484 proc_fltset2str(const fltset_t
*set
, const char *delim
, int m
,
485 char *buf
, size_t len
)
487 char name
[FLT2STR_MAX
], *p
= buf
;
491 if (buf
== NULL
|| len
< 1) {
496 buf
[0] = '\0'; /* Set first byte to \0 */
498 for (i
= 1; i
<= PRMAXFAULT
; i
++) {
499 if ((prismember(set
, i
) != 0) ^ (m
== 0)) {
500 (void) proc_fltname(i
, name
, sizeof (name
));
503 n
= snprintf(p
, len
, "%s%s", delim
, name
);
505 n
= snprintf(p
, len
, "%s", name
);
507 if (n
!= strlen(p
)) {
508 errno
= ENAMETOOLONG
; /* Output was truncated */
519 * Convert a sigset_t to a string representation consisting of canonical signal
520 * names (without the SIG prefix). Parameters and return values analogous to
524 proc_sigset2str(const sigset_t
*set
, const char *delim
, int m
,
525 char *buf
, size_t len
)
527 char name
[SIG2STR_MAX
], *p
= buf
;
531 if (buf
== NULL
|| len
< 1) {
536 m
= (m
!= 0); /* Make sure m is 0 or 1 */
537 buf
[0] = '\0'; /* Set first byte to \0 */
540 * Unlike proc_fltset2str() and proc_sysset2str(), we don't loop
541 * until i <= NSIG here, because sigismember() rejects i == NSIG.
543 for (i
= 1; i
< NSIG
; i
++) {
544 if (sigismember(set
, i
) == m
) {
545 (void) sig2str(i
, name
);
548 n
= snprintf(p
, len
, "%s%s", delim
, name
);
550 n
= snprintf(p
, len
, "%s", name
);
552 if (n
!= strlen(p
)) {
553 errno
= ENAMETOOLONG
; /* Output was truncated */
566 * Convert a sysset_t to a string representation consisting of canonical system
567 * call names. Parameters and return values analogous to proc_fltset2str().
570 proc_sysset2str(const sysset_t
*set
, const char *delim
, int m
,
571 char *buf
, size_t len
)
573 char name
[SYS2STR_MAX
], *p
= buf
;
577 if (buf
== NULL
|| len
< 1) {
582 buf
[0] = '\0'; /* Set first byte to \0 */
584 for (i
= 1; i
<= PRMAXSYS
; i
++) {
585 if ((prismember(set
, i
) != 0) ^ (m
== 0)) {
586 (void) proc_sysname(i
, name
, sizeof (name
));
589 n
= snprintf(p
, len
, "%s%s", delim
, name
);
591 n
= snprintf(p
, len
, "%s", name
);
593 if (n
!= strlen(p
)) {
594 errno
= ENAMETOOLONG
; /* Output was truncated */
605 * Convert a string representation of a fault set (names separated by
606 * one or more of the given delimeters) to a fltset_t.
607 * If m is non-zero (TRUE), members of the string representation are set.
608 * If m is zero (FALSE), non-members of the string representation are set.
609 * This function returns NULL for success. Otherwise it returns a pointer
610 * to the token of the string that couldn't be identified as a string
611 * representation of a fault.
614 proc_str2fltset(const char *s
, const char *delim
, int m
, fltset_t
*set
)
627 for (p
= strtok_r(t
, delim
, &q
); p
!= NULL
;
628 p
= strtok_r(NULL
, delim
, &q
)) {
629 if (proc_str2flt(p
, &flt
) == -1) {
631 return ((char *)s
+ (p
- t
));
642 * Convert a string representation of a signal set (names with or without the
643 * SIG prefix separated by one or more of the given delimeters) to a sigset_t.
644 * Parameters and return values analogous to proc_str2fltset().
647 proc_str2sigset(const char *s
, const char *delim
, int m
, sigset_t
*set
)
660 for (p
= strtok_r(t
, delim
, &q
); p
!= NULL
;
661 p
= strtok_r(NULL
, delim
, &q
)) {
662 if (proc_str2sig(p
, &sig
) == -1) {
664 return ((char *)s
+ (p
- t
));
675 * Convert a string representation of a system call set (names separated by
676 * one or more of the given delimeters) to a sysset_t. Parameters and return
677 * values analogous to proc_str2fltset().
680 proc_str2sysset(const char *s
, const char *delim
, int m
, sysset_t
*set
)
693 for (p
= strtok_r(t
, delim
, &q
); p
!= NULL
;
694 p
= strtok_r(NULL
, delim
, &q
)) {
695 if (proc_str2sys(p
, &sys
) == -1) {
697 return ((char *)s
+ (p
- t
));