PSARC 2009/377 In-kernel pfexec implementation.
PSARC 2009/378 Basic File Privileges
PSARC 2010/072 RBAC update: user attrs from profiles
4912090 pfzsh(1) should exist
4912093 pfbash(1) should exist
4912096 pftcsh(1) should exist
6440298 Expand the basic privilege set in order to restrict file access
6859862 Move pfexec into the kernel
6919171 cred_t sidesteps kmem_debug; we need to be able to detect bad hold/free when they occur
6923721 The new SYS_SMB privilege is not backward compatible
6937562 autofs doesn't remove its door when the zone shuts down
6937727 Zones stuck on deathrow; netstack_zone keeps a credential reference to the zone
6940159 Implement PSARC 2010/072
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#define _SYSCALL32 /* make 32-bit compat headers visible */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <termio.h>
#include <stddef.h>
#include <limits.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/ulimit.h>
#include <sys/utsname.h>
#include <sys/kstat.h>
#include <sys/modctl.h>
#include <sys/acl.h>
#include <stropts.h>
#include <sys/isa_defs.h>
#include <sys/systeminfo.h>
#include <sys/cladm.h>
#include <sys/lwp.h>
#include <bsm/audit.h>
#include <libproc.h>
#include <priv.h>
#include <sys/aio.h>
#include <sys/aiocb.h>
#include <sys/corectl.h>
#include <sys/cpc_impl.h>
#include <sys/priocntl.h>
#include <sys/tspriocntl.h>
#include <sys/iapriocntl.h>
#include <sys/rtpriocntl.h>
#include <sys/fsspriocntl.h>
#include <sys/fxpriocntl.h>
#include <netdb.h>
#include <nss_dbdefs.h>
#include <sys/socketvar.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/sctp.h>
#include <net/route.h>
#include <sys/utrap.h>
#include <sys/lgrp_user.h>
#include <sys/door.h>
#include <sys/tsol/tndb.h>
#include <sys/rctl.h>
#include <sys/rctl_impl.h>
#include <sys/fork.h>
#include <sys/task.h>
#include "ramdata.h"
#include "print.h"
#include "proto.h"
#include "systable.h"
void grow(private_t *, int nbyte);
#define GROW(nb) if (pri->sys_leng + (nb) >= pri->sys_ssize) grow(pri, (nb))
/*ARGSUSED*/
void
prt_nov(private_t *pri, int raw, long val) /* print nothing */
{
}
/*ARGSUSED*/
void
prt_dec(private_t *pri, int raw, long val) /* print as decimal */
{
GROW(24);
if (data_model == PR_MODEL_ILP32)
pri->sys_leng += sprintf(pri->sys_string + pri->sys_leng,
"%d", (int)val);
else
pri->sys_leng += sprintf(pri->sys_string + pri->sys_leng,
"%ld", val);
}
/*ARGSUSED*/
void
prt_uns(private_t *pri, int raw, long val) /* print as unsigned decimal */
{
GROW(24);
if (data_model == PR_MODEL_ILP32)
pri->sys_leng += sprintf(pri->sys_string + pri->sys_leng,
"%u", (int)val);
else
pri->sys_leng += sprintf(pri->sys_string + pri->sys_leng,
"%lu", val);
}
/* print as unsigned decimal, except for -1 */
void
prt_un1(private_t *pri, int raw, long val)
{
if ((int)val == -1)
prt_dec(pri, raw, val);
else
prt_uns(pri, raw, val);
}
/*ARGSUSED*/
void
prt_oct(private_t *pri, int raw, long val) /* print as octal */
{
GROW(24);
if (data_model == PR_MODEL_ILP32)
pri->sys_leng += sprintf(pri->sys_string + pri->sys_leng,
"%#o", (int)val);
else
pri->sys_leng += sprintf(pri->sys_string + pri->sys_leng,
"%#lo", val);
}
/*ARGSUSED*/
void
prt_hex(private_t *pri, int raw, long val) /* print as hexadecimal */
{
GROW(20);
if (data_model == PR_MODEL_ILP32)
pri->sys_leng += sprintf(pri->sys_string + pri->sys_leng,
"0x%.8X", (int)val);
else
pri->sys_leng += sprintf(pri->sys_string + pri->sys_leng,
"0x%.8lX", val);
}
/* print as hexadecimal (half size) */
/*ARGSUSED*/
void
prt_hhx(private_t *pri, int raw, long val)
{
GROW(20);
if (data_model == PR_MODEL_ILP32)
pri->sys_leng += sprintf(pri->sys_string + pri->sys_leng,
"0x%.4X", (int)val);
else
pri->sys_leng += sprintf(pri->sys_string + pri->sys_leng,
"0x%.4lX", val);
}
/* print as decimal if small, else hexadecimal */
/*ARGSUSED*/
void
prt_dex(private_t *pri, int raw, long val)
{
if (val & 0xff000000)
prt_hex(pri, 0, val);
else
prt_dec(pri, 0, val);
}
/* print long long offset */
/*ARGSUSED*/
void
prt_llo(private_t *pri, int raw, long val1, long val2)
{
int hival;
int loval;
#ifdef _LONG_LONG_LTOH
hival = (int)val2;
loval = (int)val1;
#else
hival = (int)val1;
loval = (int)val2;
#endif
if (hival == 0) {
prt_dex(pri, 0, loval);
} else {
GROW(18);
pri->sys_leng +=
sprintf(pri->sys_string + pri->sys_leng, "0x%.8X%.8X",
hival, loval);
}
}
void
escape_string(private_t *pri, const char *s)
{
/*
* We want to avoid outputting unprintable characters that may
* destroy the user's terminal. So we do one pass to find any
* unprintable characters, size the array appropriately, and
* then walk each character by hand. Those that are unprintable
* are replaced by a hex escape (\xNN). We also escape quotes for
* completeness.
*/
int i, unprintable, quotes;
size_t len = strlen(s);
for (i = 0, unprintable = 0, quotes = 0; i < len; i++) {
if (!isprint(s[i]))
unprintable++;
if (s[i] == '"')
quotes++;
}
GROW(len + 3 * unprintable + quotes + 2);
pri->sys_string[pri->sys_leng++] = '"';
for (i = 0; i < len; i++) {
if (s[i] == '"')
pri->sys_string[pri->sys_leng++] = '\\';
if (isprint(s[i])) {
pri->sys_string[pri->sys_leng++] = s[i];
} else {
pri->sys_leng += sprintf(pri->sys_string +
pri->sys_leng, "\\x%02x", (uint8_t)s[i]);
}
}
pri->sys_string[pri->sys_leng++] = '"';
}
void
prt_stg(private_t *pri, int raw, long val) /* print as string */
{
char *s = raw? NULL : fetchstring(pri, (long)val, PATH_MAX);
if (s == NULL)
prt_hex(pri, 0, val);
else
escape_string(pri, s);
}
/* print as string returned from syscall */
void
prt_rst(private_t *pri, int raw, long val)
{
char *s = (raw || pri->Errno)? NULL :
fetchstring(pri, (long)val, PATH_MAX);
if (s == NULL)
prt_hex(pri, 0, val);
else {
GROW((int)strlen(s) + 2);
pri->sys_leng += snprintf(pri->sys_string + pri->sys_leng,
pri->sys_ssize - pri->sys_leng, "\"%s\"", s);
}
}
/* print contents of readlink() buffer */
void
prt_rlk(private_t *pri, int raw, long val)
{
char *s = (raw || pri->Errno || pri->Rval1 <= 0)? NULL :
fetchstring(pri, (long)val,
(pri->Rval1 > PATH_MAX)? PATH_MAX : (int)pri->Rval1);
if (s == NULL)
prt_hex(pri, 0, val);
else {
GROW((int)strlen(s) + 2);
pri->sys_leng += snprintf(pri->sys_string + pri->sys_leng,
pri->sys_ssize - pri->sys_leng, "\"%s\"", s);
}
}
void
prt_ioc(private_t *pri, int raw, long val) /* print ioctl code */
{
const char *s = raw? NULL : ioctlname(pri, (int)val);
if (s == NULL)
prt_hex(pri, 0, val);
else
outstring(pri, s);
}
void
prt_ioa(private_t *pri, int raw, long val) /* print ioctl argument */
{
const char *s;
/* cheating -- look at the ioctl() code */
switch (pri->sys_args[1]) {
/* kstat ioctl()s */
case KSTAT_IOC_READ:
case KSTAT_IOC_WRITE:
#ifdef _LP64
if (data_model == PR_MODEL_ILP32)
prt_stg(pri, raw,
val + offsetof(kstat32_t, ks_name[0]));
else
#endif
prt_stg(pri, raw,
val + offsetof(kstat_t, ks_name[0]));
break;
/* streams ioctl()s */
case I_LOOK:
prt_rst(pri, raw, val);
break;
case I_PUSH:
case I_FIND:
prt_stg(pri, raw, val);
break;
case I_LINK:
case I_UNLINK:
case I_SENDFD:
prt_dec(pri, 0, val);
break;
case I_SRDOPT:
if (raw || (s = strrdopt(val)) == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
break;
case I_SETSIG:
if (raw || (s = strevents(pri, val)) == NULL)
prt_hex(pri, 0, val);
else
outstring(pri, s);
break;
case I_FLUSH:
if (raw || (s = strflush(val)) == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
break;
/* tty ioctl()s */
case TCSBRK:
case TCXONC:
case TCFLSH:
case TCDSET:
prt_dec(pri, 0, val);
break;
default:
prt_hex(pri, 0, val);
break;
}
}
void
prt_fcn(private_t *pri, int raw, long val) /* print fcntl code */
{
const char *s = raw? NULL : fcntlname(val);
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_s86(private_t *pri, int raw, long val) /* print sysi86 code */
{
const char *s = raw? NULL : si86name(val);
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_uts(private_t *pri, int raw, long val) /* print utssys code */
{
const char *s = raw? NULL : utscode(val);
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_msc(private_t *pri, int raw, long val) /* print msgsys command */
{
const char *s = raw? NULL : msgcmd(val);
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_msf(private_t *pri, int raw, long val) /* print msgsys flags */
{
const char *s = raw? NULL : msgflags(pri, (int)val);
if (s == NULL)
prt_oct(pri, 0, val);
else
outstring(pri, s);
}
void
prt_smc(private_t *pri, int raw, long val) /* print semsys command */
{
const char *s = raw? NULL : semcmd(val);
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_sef(private_t *pri, int raw, long val) /* print semsys flags */
{
const char *s = raw? NULL : semflags(pri, (int)val);
if (s == NULL)
prt_oct(pri, 0, val);
else
outstring(pri, s);
}
void
prt_shc(private_t *pri, int raw, long val) /* print shmsys command */
{
const char *s = raw? NULL : shmcmd(val);
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_shf(private_t *pri, int raw, long val) /* print shmsys flags */
{
const char *s = raw? NULL : shmflags(pri, (int)val);
if (s == NULL)
prt_oct(pri, 0, val);
else
outstring(pri, s);
}
void
prt_sfs(private_t *pri, int raw, long val) /* print sysfs code */
{
const char *s = raw? NULL : sfsname(val);
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_opn(private_t *pri, int raw, long val) /* print open code */
{
const char *s = raw? NULL : openarg(pri, val);
if (s == NULL)
prt_oct(pri, 0, val);
else
outstring(pri, s);
}
void
prt_sig(private_t *pri, int raw, long val) /* print signal name */
{
const char *s = raw? NULL : signame(pri, (int)val);
if (s == NULL)
prt_hex(pri, 0, val);
else
outstring(pri, s);
}
void
prt_smf(private_t *pri, int raw, long val) /* print streams message flags */
{
switch (val) {
case 0:
prt_dec(pri, 0, val);
break;
case RS_HIPRI:
if (raw)
prt_hhx(pri, 0, val);
else
outstring(pri, "RS_HIPRI");
break;
default:
prt_hhx(pri, 0, val);
break;
}
}
void
prt_mtf(private_t *pri, int raw, long val) /* print mount flags */
{
const char *s = raw? NULL : mountflags(pri, val);
if (s == NULL)
prt_hex(pri, 0, val);
else
outstring(pri, s);
}
void
prt_mft(private_t *pri, int raw, long val) /* print mount file system type */
{
if (val >= 0 && val < 256)
prt_dec(pri, 0, val);
else if (raw)
prt_hex(pri, 0, val);
else
prt_stg(pri, raw, val);
}
#define ISREAD(code) \
((code) == SYS_read || (code) == SYS_pread || (code) == SYS_pread64 || \
(code) == SYS_recv || (code) == SYS_recvfrom)
#define ISWRITE(code) \
((code) == SYS_write || (code) == SYS_pwrite || \
(code) == SYS_pwrite64 || (code) == SYS_send || (code) == SYS_sendto)
/* print contents of read() or write() I/O buffer */
void
prt_iob(private_t *pri, int raw, long val)
{
const lwpstatus_t *Lsp = pri->lwpstat;
int syscall = Lsp->pr_what;
int fdp1 = pri->sys_args[0] + 1;
ssize_t nbyte = ISWRITE(syscall)? pri->sys_args[2] :
(pri->Errno? 0 : pri->Rval1);
int elsewhere = FALSE; /* TRUE iff dumped elsewhere */
char buffer[IOBSIZE];
pri->iob_buf[0] = '\0';
if (Lsp->pr_why == PR_SYSEXIT && nbyte > IOBSIZE) {
if (ISREAD(syscall))
elsewhere = prismember(&readfd, fdp1);
else
elsewhere = prismember(&writefd, fdp1);
}
if (nbyte <= 0 || elsewhere)
prt_hex(pri, 0, val);
else {
int nb = nbyte > IOBSIZE? IOBSIZE : (int)nbyte;
if (Pread(Proc, buffer, (size_t)nb, (long)val) != nb)
prt_hex(pri, 0, val);
else {
pri->iob_buf[0] = '"';
showbytes(buffer, nb, pri->iob_buf + 1);
(void) strlcat(pri->iob_buf,
(nb == nbyte)?
(const char *)"\"" : (const char *)"\"..",
sizeof (pri->iob_buf));
if (raw)
prt_hex(pri, 0, val);
else
outstring(pri, pri->iob_buf);
}
}
}
#undef ISREAD
#undef ISWRITE
void
prt_idt(private_t *pri, int raw, long val) /* print idtype_t, waitid() arg */
{
const char *s = raw? NULL : idtype_enum(pri, val);
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_wop(private_t *pri, int raw, long val) /* print waitid() options */
{
const char *s = raw? NULL : woptions(pri, (int)val);
if (s == NULL)
prt_oct(pri, 0, val);
else
outstring(pri, s);
}
void
prt_whn(private_t *pri, int raw, long val) /* print lseek() whence argument */
{
const char *s = raw? NULL : whencearg(val);
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
/*ARGSUSED*/
void
prt_spm(private_t *pri, int raw, long val) /* print sigprocmask argument */
{
const char *s = NULL;
if (!raw) {
switch (val) {
case SIG_BLOCK: s = "SIG_BLOCK"; break;
case SIG_UNBLOCK: s = "SIG_UNBLOCK"; break;
case SIG_SETMASK: s = "SIG_SETMASK"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
const char *
mmap_protect(private_t *pri, long arg)
{
char *str = pri->code_buf;
if (arg & ~(PROT_READ|PROT_WRITE|PROT_EXEC))
return ((char *)NULL);
if (arg == PROT_NONE)
return ("PROT_NONE");
*str = '\0';
if (arg & PROT_READ)
(void) strlcat(str, "|PROT_READ", sizeof (pri->code_buf));
if (arg & PROT_WRITE)
(void) strlcat(str, "|PROT_WRITE", sizeof (pri->code_buf));
if (arg & PROT_EXEC)
(void) strlcat(str, "|PROT_EXEC", sizeof (pri->code_buf));
return ((const char *)(str + 1));
}
const char *
mmap_type(private_t *pri, long arg)
{
char *str = pri->code_buf;
size_t used;
#define CBSIZE sizeof (pri->code_buf)
switch (arg & MAP_TYPE) {
case MAP_SHARED:
used = strlcpy(str, "MAP_SHARED", CBSIZE);
break;
case MAP_PRIVATE:
used = strlcpy(str, "MAP_PRIVATE", CBSIZE);
break;
default:
used = snprintf(str, CBSIZE, "%ld", arg&MAP_TYPE);
break;
}
arg &= ~(_MAP_NEW|MAP_TYPE);
if (arg & ~(MAP_FIXED|MAP_RENAME|MAP_NORESERVE|MAP_ANON|MAP_ALIGN|
MAP_TEXT|MAP_INITDATA))
(void) snprintf(str + used, sizeof (pri->code_buf) - used,
"|0x%lX", arg);
else {
if (arg & MAP_FIXED)
(void) strlcat(str, "|MAP_FIXED", CBSIZE);
if (arg & MAP_RENAME)
(void) strlcat(str, "|MAP_RENAME", CBSIZE);
if (arg & MAP_NORESERVE)
(void) strlcat(str, "|MAP_NORESERVE", CBSIZE);
if (arg & MAP_ANON)
(void) strlcat(str, "|MAP_ANON", CBSIZE);
if (arg & MAP_ALIGN)
(void) strlcat(str, "|MAP_ALIGN", CBSIZE);
if (arg & MAP_TEXT)
(void) strlcat(str, "|MAP_TEXT", CBSIZE);
if (arg & MAP_INITDATA)
(void) strlcat(str, "|MAP_INITDATA", CBSIZE);
}
return ((const char *)str);
#undef CBSIZE
}
void
prt_mpr(private_t *pri, int raw, long val) /* print mmap()/mprotect() flags */
{
const char *s = raw? NULL : mmap_protect(pri, val);
if (s == NULL)
prt_hhx(pri, 0, val);
else
outstring(pri, s);
}
void
prt_mty(private_t *pri, int raw, long val) /* print mmap() mapping type flags */
{
const char *s = raw? NULL : mmap_type(pri, val);
if (s == NULL)
prt_hhx(pri, 0, val);
else
outstring(pri, s);
}
void
prt_mob(private_t *pri, int raw, long val) /* print mmapobj() flags */
{
if (val == 0)
prt_dec(pri, 0, val);
else if (raw || (val & ~(MMOBJ_PADDING|MMOBJ_INTERPRET)) != 0)
prt_hhx(pri, 0, val);
else {
#define CBSIZE sizeof (pri->code_buf)
char *s = pri->code_buf;
*s = '\0';
if (val & MMOBJ_PADDING)
(void) strlcat(s, "|MMOBJ_PADDING", CBSIZE);
if (val & MMOBJ_INTERPRET)
(void) strlcat(s, "|MMOBJ_INTERPRET", CBSIZE);
outstring(pri, s + 1);
#undef CBSIZE
}
}
/*ARGSUSED*/
void
prt_mcf(private_t *pri, int raw, long val) /* print memcntl() function */
{
const char *s = NULL;
if (!raw) {
switch (val) {
case MC_SYNC: s = "MC_SYNC"; break;
case MC_LOCK: s = "MC_LOCK"; break;
case MC_UNLOCK: s = "MC_UNLOCK"; break;
case MC_ADVISE: s = "MC_ADVISE"; break;
case MC_LOCKAS: s = "MC_LOCKAS"; break;
case MC_UNLOCKAS: s = "MC_UNLOCKAS"; break;
case MC_HAT_ADVISE: s = "MC_HAT_ADVISE"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_mad(private_t *pri, int raw, long val) /* print madvise() argument */
{
const char *s = NULL;
if (!raw) {
switch (val) {
case MADV_NORMAL: s = "MADV_NORMAL"; break;
case MADV_RANDOM: s = "MADV_RANDOM"; break;
case MADV_SEQUENTIAL: s = "MADV_SEQUENTIAL"; break;
case MADV_WILLNEED: s = "MADV_WILLNEED"; break;
case MADV_DONTNEED: s = "MADV_DONTNEED"; break;
case MADV_FREE: s = "MADV_FREE"; break;
case MADV_ACCESS_DEFAULT: s = "MADV_ACCESS_DEFAULT"; break;
case MADV_ACCESS_LWP: s = "MADV_ACCESS_LWP"; break;
case MADV_ACCESS_MANY: s = "MADV_ACCESS_MANY"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_mc4(private_t *pri, int raw, long val) /* print memcntl() (4th) argument */
{
if (val == 0)
prt_dec(pri, 0, val);
else if (raw)
prt_hhx(pri, 0, val);
else {
char *s = NULL;
#define CBSIZE sizeof (pri->code_buf)
/* cheating -- look at memcntl func */
switch (pri->sys_args[2]) {
case MC_ADVISE:
prt_mad(pri, 0, val);
return;
case MC_SYNC:
if ((val & ~(MS_SYNC|MS_ASYNC|MS_INVALIDATE)) == 0) {
*(s = pri->code_buf) = '\0';
if (val & MS_SYNC)
(void) strlcat(s, "|MS_SYNC", CBSIZE);
if (val & MS_ASYNC)
(void) strlcat(s, "|MS_ASYNC", CBSIZE);
if (val & MS_INVALIDATE)
(void) strlcat(s, "|MS_INVALIDATE",
CBSIZE);
}
break;
case MC_LOCKAS:
case MC_UNLOCKAS:
if ((val & ~(MCL_CURRENT|MCL_FUTURE)) == 0) {
*(s = pri->code_buf) = '\0';
if (val & MCL_CURRENT)
(void) strlcat(s, "|MCL_CURRENT",
CBSIZE);
if (val & MCL_FUTURE)
(void) strlcat(s, "|MCL_FUTURE",
CBSIZE);
}
break;
}
#undef CBSIZE
if (s == NULL || *s == '\0')
prt_hhx(pri, 0, val);
else
outstring(pri, ++s);
}
}
void
prt_mc5(private_t *pri, int raw, long val) /* print memcntl() (5th) argument */
{
char *s;
#define CBSIZE sizeof (pri->code_buf)
if (val == 0)
prt_dec(pri, 0, val);
else if (raw || (val & ~VALID_ATTR))
prt_hhx(pri, 0, val);
else {
s = pri->code_buf;
*s = '\0';
if (val & SHARED)
(void) strlcat(s, "|SHARED", CBSIZE);
if (val & PRIVATE)
(void) strlcat(s, "|PRIVATE", CBSIZE);
if (val & PROT_READ)
(void) strlcat(s, "|PROT_READ", CBSIZE);
if (val & PROT_WRITE)
(void) strlcat(s, "|PROT_WRITE", CBSIZE);
if (val & PROT_EXEC)
(void) strlcat(s, "|PROT_EXEC", CBSIZE);
if (*s == '\0')
prt_hhx(pri, 0, val);
else
outstring(pri, ++s);
}
#undef CBSIZE
}
void
prt_ulm(private_t *pri, int raw, long val) /* print ulimit() argument */
{
const char *s = NULL;
if (!raw) {
switch (val) {
case UL_GFILLIM: s = "UL_GFILLIM"; break;
case UL_SFILLIM: s = "UL_SFILLIM"; break;
case UL_GMEMLIM: s = "UL_GMEMLIM"; break;
case UL_GDESLIM: s = "UL_GDESLIM"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_rlm(private_t *pri, int raw, long val) /* print get/setrlimit() argument */
{
const char *s = NULL;
if (!raw) {
switch (val) {
case RLIMIT_CPU: s = "RLIMIT_CPU"; break;
case RLIMIT_FSIZE: s = "RLIMIT_FSIZE"; break;
case RLIMIT_DATA: s = "RLIMIT_DATA"; break;
case RLIMIT_STACK: s = "RLIMIT_STACK"; break;
case RLIMIT_CORE: s = "RLIMIT_CORE"; break;
case RLIMIT_NOFILE: s = "RLIMIT_NOFILE"; break;
case RLIMIT_VMEM: s = "RLIMIT_VMEM"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_cnf(private_t *pri, int raw, long val) /* print sysconfig code */
{
const char *s = raw? NULL : sconfname(val);
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_inf(private_t *pri, int raw, long val) /* print sysinfo code */
{
const char *s = NULL;
if (!raw) {
switch (val) {
case SI_SYSNAME: s = "SI_SYSNAME"; break;
case SI_HOSTNAME: s = "SI_HOSTNAME"; break;
case SI_RELEASE: s = "SI_RELEASE"; break;
case SI_VERSION: s = "SI_VERSION"; break;
case SI_MACHINE: s = "SI_MACHINE"; break;
case SI_ARCHITECTURE: s = "SI_ARCHITECTURE"; break;
case SI_ARCHITECTURE_32:s = "SI_ARCHITECTURE_32"; break;
case SI_ARCHITECTURE_64:s = "SI_ARCHITECTURE_64"; break;
case SI_ARCHITECTURE_K: s = "SI_ARCHITECTURE_K"; break;
case SI_HW_SERIAL: s = "SI_HW_SERIAL"; break;
case SI_HW_PROVIDER: s = "SI_HW_PROVIDER"; break;
case SI_SRPC_DOMAIN: s = "SI_SRPC_DOMAIN"; break;
case SI_SET_HOSTNAME: s = "SI_SET_HOSTNAME"; break;
case SI_SET_SRPC_DOMAIN: s = "SI_SET_SRPC_DOMAIN"; break;
case SI_PLATFORM: s = "SI_PLATFORM"; break;
case SI_ISALIST: s = "SI_ISALIST"; break;
case SI_DHCP_CACHE: s = "SI_DHCP_CACHE"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_ptc(private_t *pri, int raw, long val) /* print pathconf code */
{
const char *s = raw? NULL : pathconfname(val);
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_fui(private_t *pri, int raw, long val) /* print fusers() input argument */
{
const char *s = raw? NULL : fuiname(val);
if (s == NULL)
prt_hhx(pri, 0, val);
else
outstring(pri, s);
}
void
prt_lwf(private_t *pri, int raw, long val) /* print lwp_create() flags */
{
char *s;
if (val == 0)
prt_dec(pri, 0, val);
else if (raw ||
(val & ~(LWP_DAEMON|LWP_DETACHED|LWP_SUSPENDED)))
prt_hhx(pri, 0, val);
else {
#define CBSIZE sizeof (pri->code_buf)
s = pri->code_buf;
*s = '\0';
if (val & LWP_DAEMON)
(void) strlcat(s, "|LWP_DAEMON", CBSIZE);
if (val & LWP_DETACHED)
(void) strlcat(s, "|LWP_DETACHED", CBSIZE);
if (val & LWP_SUSPENDED)
(void) strlcat(s, "|LWP_SUSPENDED", CBSIZE);
outstring(pri, ++s);
#undef CBSIZE
}
}
void
prt_itm(private_t *pri, int raw, long val) /* print [get|set]itimer() arg */
{
const char *s = NULL;
if (!raw) {
switch (val) {
case ITIMER_REAL: s = "ITIMER_REAL"; break;
case ITIMER_VIRTUAL: s = "ITIMER_VIRTUAL"; break;
case ITIMER_PROF: s = "ITIMER_PROF"; break;
#ifdef ITIMER_REALPROF
case ITIMER_REALPROF: s = "ITIMER_REALPROF"; break;
#endif
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_mod(private_t *pri, int raw, long val) /* print modctl() code */
{
const char *s = NULL;
if (!raw) {
switch (val) {
case MODLOAD: s = "MODLOAD"; break;
case MODUNLOAD: s = "MODUNLOAD"; break;
case MODINFO: s = "MODINFO"; break;
case MODRESERVED: s = "MODRESERVED"; break;
case MODSETMINIROOT: s = "MODSETMINIROOT"; break;
case MODADDMAJBIND: s = "MODADDMAJBIND"; break;
case MODGETPATH: s = "MODGETPATH"; break;
case MODGETPATHLEN: s = "MODGETPATHLEN"; break;
case MODREADSYSBIND: s = "MODREADSYSBIND"; break;
case MODGETMAJBIND: s = "MODGETMAJBIND"; break;
case MODGETNAME: s = "MODGETNAME"; break;
case MODSIZEOF_DEVID: s = "MODSIZEOF_DEVID"; break;
case MODGETDEVID: s = "MODGETDEVID"; break;
case MODSIZEOF_MINORNAME: s = "MODSIZEOF_MINORNAME"; break;
case MODGETMINORNAME: s = "MODGETMINORNAME"; break;
case MODGETFBNAME: s = "MODGETFBNAME"; break;
case MODEVENTS: s = "MODEVENTS"; break;
case MODREREADDACF: s = "MODREREADDACF"; break;
case MODLOADDRVCONF: s = "MODLOADDRVCONF"; break;
case MODUNLOADDRVCONF: s = "MODUNLOADDRVCONF"; break;
case MODREMMAJBIND: s = "MODREMMAJBIND"; break;
case MODDEVT2INSTANCE: s = "MODDEVT2INSTANCE"; break;
case MODGETDEVFSPATH_LEN: s = "MODGETDEVFSPATH_LEN"; break;
case MODGETDEVFSPATH: s = "MODGETDEVFSPATH"; break;
case MODDEVID2PATHS: s = "MODDEVID2PATHS"; break;
case MODSETDEVPOLICY: s = "MODSETDEVPOLICY"; break;
case MODGETDEVPOLICY: s = "MODGETDEVPOLICY"; break;
case MODALLOCPRIV: s = "MODALLOCPRIV"; break;
case MODGETDEVPOLICYBYNAME:
s = "MODGETDEVPOLICYBYNAME"; break;
case MODLOADMINORPERM: s = "MODLOADMINORPERM"; break;
case MODADDMINORPERM: s = "MODADDMINORPERM"; break;
case MODREMMINORPERM: s = "MODREMMINORPERM"; break;
case MODREMDRVCLEANUP: s = "MODREMDRVCLEANUP"; break;
case MODDEVEXISTS: s = "MODDEVEXISTS"; break;
case MODDEVREADDIR: s = "MODDEVREADDIR"; break;
case MODDEVEMPTYDIR: s = "MODDEVEMPTYDIR"; break;
case MODDEVNAME: s = "MODDEVNAME"; break;
case MODGETDEVFSPATH_MI_LEN:
s = "MODGETDEVFSPATH_MI_LEN"; break;
case MODGETDEVFSPATH_MI:
s = "MODGETDEVFSPATH_MI"; break;
case MODREMDRVALIAS: s = "MODREMDRVALIAS"; break;
case MODHPOPS: s = "MODHPOPS"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_acl(private_t *pri, int raw, long val) /* print acl() code */
{
const char *s = NULL;
if (!raw) {
switch (val) {
case GETACL: s = "GETACL"; break;
case SETACL: s = "SETACL"; break;
case GETACLCNT: s = "GETACLCNT"; break;
case ACE_GETACL: s = "ACE_GETACL"; break;
case ACE_SETACL: s = "ACE_SETACL"; break;
case ACE_GETACLCNT: s = "ACE_GETACLCNT"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_aio(private_t *pri, int raw, long val) /* print kaio() code */
{
const char *s = NULL;
char buf[32];
if (!raw) {
switch (val & ~AIO_POLL_BIT) {
case AIOREAD: s = "AIOREAD"; break;
case AIOWRITE: s = "AIOWRITE"; break;
case AIOWAIT: s = "AIOWAIT"; break;
case AIOCANCEL: s = "AIOCANCEL"; break;
case AIONOTIFY: s = "AIONOTIFY"; break;
case AIOINIT: s = "AIOINIT"; break;
case AIOSTART: s = "AIOSTART"; break;
case AIOLIO: s = "AIOLIO"; break;
case AIOSUSPEND: s = "AIOSUSPEND"; break;
case AIOERROR: s = "AIOERROR"; break;
case AIOLIOWAIT: s = "AIOLIOWAIT"; break;
case AIOAREAD: s = "AIOAREAD"; break;
case AIOAWRITE: s = "AIOAWRITE"; break;
/*
* We have to hardcode the values for the 64-bit versions of
* these calls, because <sys/aio.h> defines them to be identical
* when compiled 64-bit. If our target is 32-bit, we still need
* to decode them correctly.
*/
case 13: s = "AIOLIO64"; break;
case 14: s = "AIOSUSPEND64"; break;
case 15: s = "AUIOERROR64"; break;
case 16: s = "AIOLIOWAIT64"; break;
case 17: s = "AIOAREAD64"; break;
case 18: s = "AIOAWRITE64"; break;
case 19: s = "AIOCANCEL64"; break;
/*
* AIOFSYNC doesn't correspond to a syscall.
*/
case AIOWAITN: s = "AIOWAITN"; break;
}
if (s != NULL && (val & AIO_POLL_BIT)) {
(void) strlcpy(buf, s, sizeof (buf));
(void) strlcat(buf, "|AIO_POLL_BIT", sizeof (buf));
s = (const char *)buf;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_aud(private_t *pri, int raw, long val) /* print auditsys() code */
{
const char *s = NULL;
if (!raw) {
switch (val) {
case BSM_GETAUID: s = "BSM_GETAUID"; break;
case BSM_SETAUID: s = "BSM_SETAUID"; break;
case BSM_GETAUDIT: s = "BSM_GETAUDIT"; break;
case BSM_SETAUDIT: s = "BSM_SETAUDIT"; break;
case BSM_AUDIT: s = "BSM_AUDIT"; break;
case BSM_AUDITCTL: s = "BSM_AUDITCTL"; break;
case BSM_GETAUDIT_ADDR: s = "BSM_GETAUDIT_ADDR"; break;
case BSM_SETAUDIT_ADDR: s = "BSM_SETAUDIT_ADDR"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_cor(private_t *pri, int raw, long val) /* print corectl() subcode */
{
const char *s = NULL;
if (!raw) {
switch (val) {
case CC_SET_OPTIONS:
s = "CC_SET_OPTIONS"; break;
case CC_GET_OPTIONS:
s = "CC_GET_OPTIONS"; break;
case CC_SET_GLOBAL_PATH:
s = "CC_SET_GLOBAL_PATH"; break;
case CC_GET_GLOBAL_PATH:
s = "CC_GET_GLOBAL_PATH"; break;
case CC_SET_PROCESS_PATH:
s = "CC_SET_PROCESS_PATH"; break;
case CC_GET_PROCESS_PATH:
s = "CC_GET_PROCESS_PATH"; break;
case CC_SET_GLOBAL_CONTENT:
s = "CC_SET_GLOBAL_CONTENT"; break;
case CC_GET_GLOBAL_CONTENT:
s = "CC_GET_GLOBAL_CONTENT"; break;
case CC_SET_PROCESS_CONTENT:
s = "CC_SET_PROCESS_CONTENT"; break;
case CC_GET_PROCESS_CONTENT:
s = "CC_GET_PROCESS_CONTENT"; break;
case CC_SET_DEFAULT_PATH:
s = "CC_SET_DEFAULT_PATH"; break;
case CC_GET_DEFAULT_PATH:
s = "CC_GET_DEFAULT_PATH"; break;
case CC_SET_DEFAULT_CONTENT:
s = "CC_SET_DEFAULT_CONTENT"; break;
case CC_GET_DEFAULT_CONTENT:
s = "CC_GET_DEFAULT_CONTENT"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_cco(private_t *pri, int raw, long val) /* print corectl() options */
{
char *s;
if (val == 0)
prt_dec(pri, 0, val);
else if (raw || (val & ~CC_OPTIONS))
prt_hhx(pri, 0, val);
else {
#define CBSIZE sizeof (pri->code_buf)
s = pri->code_buf;
*s = '\0';
if (val & CC_GLOBAL_PATH)
(void) strlcat(s, "|CC_GLOBAL_PATH", CBSIZE);
if (val & CC_PROCESS_PATH)
(void) strlcat(s, "|CC_PROCESS_PATH", CBSIZE);
if (val & CC_GLOBAL_SETID)
(void) strlcat(s, "|CC_GLOBAL_SETID", CBSIZE);
if (val & CC_PROCESS_SETID)
(void) strlcat(s, "|CC_PROCESS_SETID", CBSIZE);
if (val & CC_GLOBAL_LOG)
(void) strlcat(s, "|CC_GLOBAL_LOG", CBSIZE);
if (*s == '\0')
prt_hhx(pri, 0, val);
else
outstring(pri, ++s);
#undef CBSIZE
}
}
void
prt_ccc(private_t *pri, int raw, long val) /* print corectl() content */
{
core_content_t ccc;
if (Pread(Proc, &ccc, sizeof (ccc), val) != sizeof (ccc))
prt_hex(pri, 0, val);
else if (!raw && proc_content2str(ccc, pri->code_buf,
sizeof (pri->code_buf)) >= 0)
outstring(pri, pri->code_buf);
else
prt_hhx(pri, 0, (long)ccc);
}
void
prt_rcc(private_t *pri, int raw, long val) /* print corectl() ret. cont. */
{
core_content_t ccc;
if (pri->Errno || Pread(Proc, &ccc, sizeof (ccc), val) != sizeof (ccc))
prt_hex(pri, 0, val);
else if (!raw && proc_content2str(ccc, pri->code_buf,
sizeof (pri->code_buf)) >= 0)
outstring(pri, pri->code_buf);
else
prt_hhx(pri, 0, (long)ccc);
}
void
prt_cpc(private_t *pri, int raw, long val) /* print cpc() subcode */
{
const char *s = NULL;
if (!raw) {
switch (val) {
case CPC_BIND: s = "CPC_BIND"; break;
case CPC_SAMPLE: s = "CPC_SAMPLE"; break;
case CPC_INVALIDATE: s = "CPC_INVALIDATE"; break;
case CPC_RELE: s = "CPC_RELE"; break;
case CPC_EVLIST_SIZE: s = "CPC_EVLIST_SIZE"; break;
case CPC_LIST_EVENTS: s = "CPC_LIST_EVENTS"; break;
case CPC_ATTRLIST_SIZE: s = "CPC_ATTRLIST_SIZE"; break;
case CPC_LIST_ATTRS: s = "CPC_LIST_ATTRS"; break;
case CPC_IMPL_NAME: s = "CPC_IMPL_NAME"; break;
case CPC_CPUREF: s = "CPC_CPUREF"; break;
case CPC_USR_EVENTS: s = "CPC_USR_EVENTS"; break;
case CPC_SYS_EVENTS: s = "CPC_SYS_EVENTS"; break;
case CPC_NPIC: s = "CPC_NPIC"; break;
case CPC_CAPS: s = "CPC_CAPS"; break;
case CPC_ENABLE: s = "CPC_ENABLE"; break;
case CPC_DISABLE: s = "CPC_DISABLE"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
outstring(private_t *pri, const char *s)
{
int len = strlen(s);
GROW(len);
(void) strcpy(pri->sys_string + pri->sys_leng, s);
pri->sys_leng += len;
}
void
grow(private_t *pri, int nbyte) /* reallocate format buffer if necessary */
{
while (pri->sys_leng + nbyte >= pri->sys_ssize)
pri->sys_string = my_realloc(pri->sys_string,
pri->sys_ssize *= 2, "format buffer");
}
void
prt_clc(private_t *pri, int raw, long val)
{
const char *s = NULL;
if (!raw) {
switch (val) {
case CL_INITIALIZE: s = "CL_INITIALIZE"; break;
case CL_CONFIG: s = "CL_CONFIG"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_clf(private_t *pri, int raw, long val)
{
const char *s = NULL;
if (!raw) {
switch (pri->sys_args[0]) {
case CL_CONFIG:
switch (pri->sys_args[1]) {
case CL_NODEID:
s = "CL_NODEID"; break;
case CL_HIGHEST_NODEID:
s = "CL_HIGHEST_NODEID"; break;
}
break;
case CL_INITIALIZE:
switch (pri->sys_args[1]) {
case CL_GET_BOOTFLAG:
s = "CL_GET_BOOTFLAG"; break;
}
break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
void
prt_sqc(private_t *pri, int raw, long val) /* print sigqueue() si_code */
{
const char *s = NULL;
if (!raw) {
switch ((int)val) {
case SI_QUEUE: s = "SI_QUEUE"; break;
case SI_TIMER: s = "SI_TIMER"; break;
case SI_ASYNCIO: s = "SI_ASYNCIO"; break;
case SI_MESGQ: s = "SI_MESGQ"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
/*
* print priocntlsys() (key, value) pair key.
*/
void
print_pck(private_t *pri, int raw, long val)
{
const char *s = NULL;
char clname[PC_CLNMSZ];
if ((pri->sys_args[2] != PC_GETXPARMS &&
pri->sys_args[2] != PC_SETXPARMS) || val == 0 || raw) {
prt_dec(pri, 0, val);
return;
}
if (pri->sys_args[3] == NULL) {
if (val == PC_KY_CLNAME) {
s = "PC_KY_CLNAME";
outstring(pri, s);
} else
prt_dec(pri, 0, val);
return;
}
if (Pread(Proc, &clname, PC_CLNMSZ, pri->sys_args[3]) != PC_CLNMSZ) {
prt_dec(pri, 0, val);
return;
}
if (strcmp(clname, "TS") == 0) {
switch (val) {
case TS_KY_UPRILIM: s = "TS_KY_UPRILIM"; break;
case TS_KY_UPRI: s = "TS_KY_UPRI"; break;
default: break;
}
} else if (strcmp(clname, "IA") == 0) {
switch (val) {
case IA_KY_UPRILIM: s = "IA_KY_UPRILIM"; break;
case IA_KY_UPRI: s = "IA_KY_UPRI"; break;
case IA_KY_MODE: s = "IA_KY_MODE"; break;
default: break;
}
} else if (strcmp(clname, "RT") == 0) {
switch (val) {
case RT_KY_PRI: s = "RT_KY_PRI"; break;
case RT_KY_TQSECS: s = "RT_KY_TQSECS"; break;
case RT_KY_TQNSECS: s = "RT_KY_TQNSECS"; break;
case RT_KY_TQSIG: s = "RT_KY_TQSIG"; break;
default: break;
}
} else if (strcmp(clname, "FSS") == 0) {
switch (val) {
case FSS_KY_UPRILIM: s = "FSS_KY_UPRILIM"; break;
case FSS_KY_UPRI: s = "FSS_KY_UPRI"; break;
default: break;
}
} else if (strcmp(clname, "FX") == 0) {
switch (val) {
case FX_KY_UPRILIM: s = "FX_KY_UPRILIM"; break;
case FX_KY_UPRI: s = "FX_KY_UPRI"; break;
case FX_KY_TQSECS: s = "FX_KY_TQSECS"; break;
case FX_KY_TQNSECS: s = "FX_KY_TQNSECS"; break;
default: break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
/*
* print priocntlsys() fourth argument.
*/
/*ARGSUSED*/
void
prt_pc4(private_t *pri, int raw, long val)
{
/* look at pricntlsys function */
if ((pri->sys_args[2] != PC_GETXPARMS &&
pri->sys_args[2] != PC_SETXPARMS))
prt_hex(pri, 0, val);
else if (val)
prt_stg(pri, 0, val);
else
prt_dec(pri, 0, val);
}
/*
* print priocntlsys() (key, value) pairs (5th argument).
*/
/*ARGSUSED*/
void
prt_pc5(private_t *pri, int raw, long val)
{
pc_vaparms_t prms;
pc_vaparm_t *vpp = &prms.pc_parms[0];
uint_t cnt;
/* look at pricntlsys function */
if ((pri->sys_args[2] != PC_GETXPARMS &&
pri->sys_args[2] != PC_SETXPARMS) || val == 0) {
prt_dec(pri, 0, 0);
return;
}
if (Pread(Proc, &prms, sizeof (prms), val) != sizeof (prms)) {
prt_hex(pri, 0, val);
return;
}
if ((cnt = prms.pc_vaparmscnt) > PC_VAPARMCNT)
return;
for (; cnt--; vpp++) {
print_pck(pri, 0, vpp->pc_key);
outstring(pri, ", ");
prt_hex(pri, 0, (long)vpp->pc_parm);
outstring(pri, ", ");
}
prt_dec(pri, 0, PC_KY_NULL);
}
/*
* Print processor set id, including logical expansion of "special" ids.
*/
void
prt_pst(private_t *pri, int raw, long val)
{
const char *s = NULL;
if (!raw) {
switch ((psetid_t)val) {
case PS_NONE: s = "PS_NONE"; break;
case PS_QUERY: s = "PS_QUERY"; break;
case PS_MYID: s = "PS_MYID"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
/*
* Print meminfo() argument.
*/
/*ARGSUSED*/
void
prt_mif(private_t *pri, int raw, long val)
{
struct meminfo minfo;
#ifdef _LP64
if (data_model == PR_MODEL_ILP32) {
struct meminfo32 minfo32;
if (Pread(Proc, &minfo32, sizeof (struct meminfo32), val) !=
sizeof (struct meminfo32)) {
prt_dec(pri, 0, pri->sys_args[1]); /* addr_count */
outstring(pri, ", ");
prt_hex(pri, 0, val);
return;
}
/*
* arrange the arguments in the order that user calls with
*/
prt_hex(pri, 0, minfo32.mi_inaddr);
outstring(pri, ", ");
prt_dec(pri, 0, pri->sys_args[1]); /* addr_count */
outstring(pri, ", ");
prt_hex(pri, 0, minfo32.mi_info_req);
outstring(pri, ", ");
prt_dec(pri, 0, minfo32.mi_info_count);
outstring(pri, ", ");
prt_hex(pri, 0, minfo32.mi_outdata);
outstring(pri, ", ");
prt_hex(pri, 0, minfo32.mi_validity);
return;
}
#endif
if (Pread(Proc, &minfo, sizeof (struct meminfo), val) !=
sizeof (struct meminfo)) {
prt_dec(pri, 0, pri->sys_args[1]); /* addr_count */
outstring(pri, ", ");
prt_hex(pri, 0, val);
return;
}
/*
* arrange the arguments in the order that user calls with
*/
prt_hex(pri, 0, (long)minfo.mi_inaddr);
outstring(pri, ", ");
prt_dec(pri, 0, pri->sys_args[1]); /* addr_count */
outstring(pri, ", ");
prt_hex(pri, 0, (long)minfo.mi_info_req);
outstring(pri, ", ");
prt_dec(pri, 0, minfo.mi_info_count);
outstring(pri, ", ");
prt_hex(pri, 0, (long)minfo.mi_outdata);
outstring(pri, ", ");
prt_hex(pri, 0, (long)minfo.mi_validity);
}
/*
* Print so_socket() 1st argument.
*/
/*ARGSUSED*/
void
prt_pfm(private_t *pri, int raw, long val)
{
/* Protocol Families have same names as Address Families */
if ((ulong_t)val < MAX_AFCODES) {
outstring(pri, "PF_");
outstring(pri, afcodes[val]);
} else {
prt_dec(pri, 0, val);
}
}
/*
* Print so_socket() 2nd argument.
*/
/*ARGSUSED*/
void
prt_skt(private_t *pri, int raw, long val)
{
const char *s;
if ((ulong_t)val <= MAX_SOCKTYPES && (s = socktype_codes[val]) != NULL)
outstring(pri, s);
else
prt_dec(pri, 0, val);
}
/*
* Print so_socket() 3rd argument.
*/
/*ARGSUSED*/
void
prt_skp(private_t *pri, int raw, long val)
{
const char *s;
/* cheating -- look at the protocol-family */
switch (pri->sys_args[0]) {
case PF_INET6:
case PF_INET:
case PF_NCA: if ((s = ipprotos((int)val)) != NULL) {
outstring(pri, s);
break;
}
/* FALLTHROUGH */
default: prt_dec(pri, 0, val);
break;
}
}
/*
* Print so_socket() 5th argument.
*/
/*ARGSUSED*/
void
prt_skv(private_t *pri, int raw, long val)
{
switch (val) {
case SOV_STREAM: outstring(pri, "SOV_STREAM"); break;
case SOV_DEFAULT: outstring(pri, "SOV_DEFAULT"); break;
case SOV_SOCKSTREAM: outstring(pri, "SOV_SOCKSTREAM"); break;
case SOV_SOCKBSD: outstring(pri, "SOV_SOCKBSD"); break;
case SOV_XPG4_2: outstring(pri, "SOV_XPG4_2"); break;
default: prt_dec(pri, 0, val); break;
}
}
/*
* Print setsockopt()/getsockopt() 2nd argument.
*/
/*ARGSUSED*/
void
prt_sol(private_t *pri, int raw, long val)
{
if (val == SOL_SOCKET) {
outstring(pri, "SOL_SOCKET");
} else if (val == SOL_ROUTE) {
outstring(pri, "SOL_ROUTE");
} else {
const struct protoent *p;
struct protoent res;
char buf[NSS_BUFLEN_PROTOCOLS];
if ((p = getprotobynumber_r(val, &res,
(char *)buf, sizeof (buf))) != NULL)
outstring(pri, p->p_name);
else
prt_dec(pri, 0, val);
}
}
const char *
sol_optname(private_t *pri, long val)
{
#define CBSIZE sizeof (pri->code_buf)
if (val >= SO_SNDBUF) {
switch (val) {
case SO_SNDBUF: return ("SO_SNDBUF");
case SO_RCVBUF: return ("SO_RCVBUF");
case SO_SNDLOWAT: return ("SO_SNDLOWAT");
case SO_RCVLOWAT: return ("SO_RCVLOWAT");
case SO_SNDTIMEO: return ("SO_SNDTIMEO");
case SO_RCVTIMEO: return ("SO_RCVTIMEO");
case SO_ERROR: return ("SO_ERROR");
case SO_TYPE: return ("SO_TYPE");
case SO_PROTOTYPE: return ("SO_PROTOTYPE");
case SO_ANON_MLP: return ("SO_ANON_MLP");
case SO_MAC_EXEMPT: return ("SO_MAC_EXEMPT");
case SO_ALLZONES: return ("SO_ALLZONES");
case SO_MAC_IMPLICIT: return ("SO_MAC_IMPLICIT");
case SO_VRRP: return ("SO_VRRP");
case SO_EXCLBIND: return ("SO_EXCLBIND");
case SO_DOMAIN: return ("SO_DOMAIN");
default: (void) snprintf(pri->code_buf, CBSIZE,
"0x%lx", val);
return (pri->code_buf);
}
} else {
char *s = pri->code_buf;
size_t used = 1;
long val2;
*s = '\0';
val2 = val & ~(SO_DEBUG|SO_ACCEPTCONN|SO_REUSEADDR|SO_KEEPALIVE|
SO_DONTROUTE|SO_BROADCAST|SO_USELOOPBACK|SO_LINGER|
SO_OOBINLINE|SO_DGRAM_ERRIND|SO_RECVUCRED);
if (val2)
used = snprintf(s, CBSIZE, "|0x%lx", val2);
if (val & SO_DEBUG)
used = strlcat(s, "|SO_DEBUG", CBSIZE);
if (val & SO_ACCEPTCONN)
used = strlcat(s, "|SO_ACCEPTCONN", CBSIZE);
if (val & SO_REUSEADDR)
used = strlcat(s, "|SO_REUSEADDR", CBSIZE);
if (val & SO_KEEPALIVE)
used = strlcat(s, "|SO_KEEPALIVE", CBSIZE);
if (val & SO_DONTROUTE)
used = strlcat(s, "|SO_DONTROUTE", CBSIZE);
if (val & SO_BROADCAST)
used = strlcat(s, "|SO_BROADCAST", CBSIZE);
if (val & SO_USELOOPBACK)
used = strlcat(s, "|SO_USELOOPBACK", CBSIZE);
if (val & SO_LINGER)
used = strlcat(s, "|SO_LINGER", CBSIZE);
if (val & SO_OOBINLINE)
used = strlcat(s, "|SO_OOBINLINE", CBSIZE);
if (val & SO_DGRAM_ERRIND)
used = strlcat(s, "|SO_DGRAM_ERRIND", CBSIZE);
if (val & SO_RECVUCRED)
used = strlcat(s, "|SO_RECVUCRED", CBSIZE);
if (used >= CBSIZE || val == 0)
(void) snprintf(s + 1, CBSIZE-1, "0x%lx", val);
return ((const char *)(s + 1));
}
#undef CBSIZE
}
const char *
route_optname(private_t *pri, long val)
{
switch (val) {
case RT_AWARE:
return ("RT_AWARE");
default:
(void) snprintf(pri->code_buf, sizeof (pri->code_buf),
"0x%lx", val);
return (pri->code_buf);
}
}
const char *
tcp_optname(private_t *pri, long val)
{
switch (val) {
case TCP_NODELAY: return ("TCP_NODELAY");
case TCP_MAXSEG: return ("TCP_MAXSEG");
case TCP_KEEPALIVE: return ("TCP_KEEPALIVE");
case TCP_NOTIFY_THRESHOLD: return ("TCP_NOTIFY_THRESHOLD");
case TCP_ABORT_THRESHOLD: return ("TCP_ABORT_THRESHOLD");
case TCP_CONN_NOTIFY_THRESHOLD: return ("TCP_CONN_NOTIFY_THRESHOLD");
case TCP_CONN_ABORT_THRESHOLD: return ("TCP_CONN_ABORT_THRESHOLD");
case TCP_RECVDSTADDR: return ("TCP_RECVDSTADDR");
case TCP_ANONPRIVBIND: return ("TCP_ANONPRIVBIND");
case TCP_EXCLBIND: return ("TCP_EXCLBIND");
case TCP_INIT_CWND: return ("TCP_INIT_CWND");
case TCP_KEEPALIVE_THRESHOLD: return ("TCP_KEEPALIVE_THRESHOLD");
case TCP_KEEPALIVE_ABORT_THRESHOLD:
return ("TCP_KEEPALIVE_ABORT_THRESHOLD");
case TCP_CORK: return ("TCP_CORK");
default: (void) snprintf(pri->code_buf,
sizeof (pri->code_buf),
"0x%lx", val);
return (pri->code_buf);
}
}
const char *
sctp_optname(private_t *pri, long val)
{
switch (val) {
case SCTP_RTOINFO: return ("SCTP_RTOINFO");
case SCTP_ASSOCINFO: return ("SCTP_ASSOCINFO");
case SCTP_INITMSG: return ("SCTP_INITMSG");
case SCTP_NODELAY: return ("SCTP_NODELAY");
case SCTP_AUTOCLOSE: return ("SCTP_AUTOCLOSE");
case SCTP_SET_PEER_PRIMARY_ADDR:
return ("SCTP_SET_PEER_PRIMARY_ADDR");
case SCTP_PRIMARY_ADDR: return ("SCTP_PRIMARY_ADDR");
case SCTP_ADAPTATION_LAYER: return ("SCTP_ADAPTATION_LAYER");
case SCTP_DISABLE_FRAGMENTS: return ("SCTP_DISABLE_FRAGMENTS");
case SCTP_PEER_ADDR_PARAMS: return ("SCTP_PEER_ADDR_PARAMS");
case SCTP_DEFAULT_SEND_PARAM: return ("SCTP_DEFAULT_SEND_PARAM");
case SCTP_EVENTS: return ("SCTP_EVENTS");
case SCTP_I_WANT_MAPPED_V4_ADDR:
return ("SCTP_I_WANT_MAPPED_V4_ADDR");
case SCTP_MAXSEG: return ("SCTP_MAXSEG");
case SCTP_STATUS: return ("SCTP_STATUS");
case SCTP_GET_PEER_ADDR_INFO: return ("SCTP_GET_PEER_ADDR_INFO");
case SCTP_ADD_ADDR: return ("SCTP_ADD_ADDR");
case SCTP_REM_ADDR: return ("SCTP_REM_ADDR");
default: (void) snprintf(pri->code_buf,
sizeof (pri->code_buf),
"0x%lx", val);
return (pri->code_buf);
}
}
const char *
udp_optname(private_t *pri, long val)
{
switch (val) {
case UDP_CHECKSUM: return ("UDP_CHECKSUM");
case UDP_ANONPRIVBIND: return ("UDP_ANONPRIVBIND");
case UDP_EXCLBIND: return ("UDP_EXCLBIND");
case UDP_RCVHDR: return ("UDP_RCVHDR");
case UDP_NAT_T_ENDPOINT: return ("UDP_NAT_T_ENDPOINT");
default: (void) snprintf(pri->code_buf,
sizeof (pri->code_buf), "0x%lx",
val);
return (pri->code_buf);
}
}
/*
* Print setsockopt()/getsockopt() 3rd argument.
*/
/*ARGSUSED*/
void
prt_son(private_t *pri, int raw, long val)
{
/* cheating -- look at the level */
switch (pri->sys_args[1]) {
case SOL_SOCKET: outstring(pri, sol_optname(pri, val));
break;
case SOL_ROUTE: outstring(pri, route_optname(pri, val));
break;
case IPPROTO_TCP: outstring(pri, tcp_optname(pri, val));
break;
case IPPROTO_UDP: outstring(pri, udp_optname(pri, val));
break;
case IPPROTO_SCTP: outstring(pri, sctp_optname(pri, val));
break;
default: prt_dec(pri, 0, val);
break;
}
}
/*
* Print utrap type
*/
/*ARGSUSED*/
void
prt_utt(private_t *pri, int raw, long val)
{
const char *s = NULL;
#ifdef __sparc
if (!raw) {
switch (val) {
case UT_INSTRUCTION_DISABLED:
s = "UT_INSTRUCTION_DISABLED"; break;
case UT_INSTRUCTION_ERROR:
s = "UT_INSTRUCTION_ERROR"; break;
case UT_INSTRUCTION_PROTECTION:
s = "UT_INSTRUCTION_PROTECTION"; break;
case UT_ILLTRAP_INSTRUCTION:
s = "UT_ILLTRAP_INSTRUCTION"; break;
case UT_ILLEGAL_INSTRUCTION:
s = "UT_ILLEGAL_INSTRUCTION"; break;
case UT_PRIVILEGED_OPCODE:
s = "UT_PRIVILEGED_OPCODE"; break;
case UT_FP_DISABLED:
s = "UT_FP_DISABLED"; break;
case UT_FP_EXCEPTION_IEEE_754:
s = "UT_FP_EXCEPTION_IEEE_754"; break;
case UT_FP_EXCEPTION_OTHER:
s = "UT_FP_EXCEPTION_OTHER"; break;
case UT_TAG_OVERFLOW:
s = "UT_TAG_OVERFLOW"; break;
case UT_DIVISION_BY_ZERO:
s = "UT_DIVISION_BY_ZERO"; break;
case UT_DATA_EXCEPTION:
s = "UT_DATA_EXCEPTION"; break;
case UT_DATA_ERROR:
s = "UT_DATA_ERROR"; break;
case UT_DATA_PROTECTION:
s = "UT_DATA_PROTECTION"; break;
case UT_MEM_ADDRESS_NOT_ALIGNED:
s = "UT_MEM_ADDRESS_NOT_ALIGNED"; break;
case UT_PRIVILEGED_ACTION:
s = "UT_PRIVILEGED_ACTION"; break;
case UT_ASYNC_DATA_ERROR:
s = "UT_ASYNC_DATA_ERROR"; break;
case UT_TRAP_INSTRUCTION_16:
s = "UT_TRAP_INSTRUCTION_16"; break;
case UT_TRAP_INSTRUCTION_17:
s = "UT_TRAP_INSTRUCTION_17"; break;
case UT_TRAP_INSTRUCTION_18:
s = "UT_TRAP_INSTRUCTION_18"; break;
case UT_TRAP_INSTRUCTION_19:
s = "UT_TRAP_INSTRUCTION_19"; break;
case UT_TRAP_INSTRUCTION_20:
s = "UT_TRAP_INSTRUCTION_20"; break;
case UT_TRAP_INSTRUCTION_21:
s = "UT_TRAP_INSTRUCTION_21"; break;
case UT_TRAP_INSTRUCTION_22:
s = "UT_TRAP_INSTRUCTION_22"; break;
case UT_TRAP_INSTRUCTION_23:
s = "UT_TRAP_INSTRUCTION_23"; break;
case UT_TRAP_INSTRUCTION_24:
s = "UT_TRAP_INSTRUCTION_24"; break;
case UT_TRAP_INSTRUCTION_25:
s = "UT_TRAP_INSTRUCTION_25"; break;
case UT_TRAP_INSTRUCTION_26:
s = "UT_TRAP_INSTRUCTION_26"; break;
case UT_TRAP_INSTRUCTION_27:
s = "UT_TRAP_INSTRUCTION_27"; break;
case UT_TRAP_INSTRUCTION_28:
s = "UT_TRAP_INSTRUCTION_28"; break;
case UT_TRAP_INSTRUCTION_29:
s = "UT_TRAP_INSTRUCTION_29"; break;
case UT_TRAP_INSTRUCTION_30:
s = "UT_TRAP_INSTRUCTION_30"; break;
case UT_TRAP_INSTRUCTION_31:
s = "UT_TRAP_INSTRUCTION_31"; break;
}
}
#endif /* __sparc */
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
/*
* Print utrap handler
*/
void
prt_uth(private_t *pri, int raw, long val)
{
const char *s = NULL;
if (!raw) {
switch (val) {
case (long)UTH_NOCHANGE: s = "UTH_NOCHANGE"; break;
}
}
if (s == NULL)
prt_hex(pri, 0, val);
else
outstring(pri, s);
}
const char *
access_flags(private_t *pri, long arg)
{
#define E_OK 010
char *str = pri->code_buf;
if (arg & ~(R_OK|W_OK|X_OK|E_OK))
return (NULL);
/* NB: F_OK == 0 */
if (arg == F_OK)
return ("F_OK");
if (arg == E_OK)
return ("F_OK|E_OK");
*str = '\0';
if (arg & R_OK)
(void) strlcat(str, "|R_OK", sizeof (pri->code_buf));
if (arg & W_OK)
(void) strlcat(str, "|W_OK", sizeof (pri->code_buf));
if (arg & X_OK)
(void) strlcat(str, "|X_OK", sizeof (pri->code_buf));
if (arg & E_OK)
(void) strlcat(str, "|E_OK", sizeof (pri->code_buf));
return ((const char *)(str + 1));
#undef E_OK
}
/*
* Print access() flags.
*/
void
prt_acc(private_t *pri, int raw, long val)
{
const char *s = raw? NULL : access_flags(pri, val);
if (s == NULL)
prt_dex(pri, 0, val);
else
outstring(pri, s);
}
/*
* Print shutdown() "how" (2nd) argument
*/
void
prt_sht(private_t *pri, int raw, long val)
{
if (raw) {
prt_dex(pri, 0, val);
return;
}
switch (val) {
case SHUT_RD: outstring(pri, "SHUT_RD"); break;
case SHUT_WR: outstring(pri, "SHUT_WR"); break;
case SHUT_RDWR: outstring(pri, "SHUT_RDWR"); break;
default: prt_dec(pri, 0, val); break;
}
}
/*
* Print fcntl() F_SETFL flags (3rd) argument or fdsync flag (2nd arg)
*/
static struct fcntl_flags {
long val;
const char *name;
} fcntl_flags[] = {
#define FC_FL(flag) { (long)flag, "|" # flag }
FC_FL(FREVOKED),
FC_FL(FREAD),
FC_FL(FWRITE),
FC_FL(FNDELAY),
FC_FL(FAPPEND),
FC_FL(FSYNC),
FC_FL(FDSYNC),
FC_FL(FRSYNC),
FC_FL(FOFFMAX),
FC_FL(FNONBLOCK),
FC_FL(FCREAT),
FC_FL(FTRUNC),
FC_FL(FEXCL),
FC_FL(FNOCTTY),
FC_FL(FXATTR),
FC_FL(FASYNC),
FC_FL(FNODSYNC)
#undef FC_FL
};
void
prt_ffg(private_t *pri, int raw, long val)
{
#define CBSIZE sizeof (pri->code_buf)
char *s = pri->code_buf;
size_t used = 1;
struct fcntl_flags *fp;
if (raw) {
(void) snprintf(s, CBSIZE, "0x%lx", val);
outstring(pri, s);
return;
}
if (val == 0) {
outstring(pri, "(no flags)");
return;
}
*s = '\0';
for (fp = fcntl_flags;
fp < &fcntl_flags[sizeof (fcntl_flags) / sizeof (*fp)]; fp++) {
if (val & fp->val) {
used = strlcat(s, fp->name, CBSIZE);
val &= ~fp->val;
}
}
if (val != 0 && used <= CBSIZE)
used += snprintf(s + used, CBSIZE - used, "|0x%lx", val);
if (used >= CBSIZE)
(void) snprintf(s + 1, CBSIZE-1, "0x%lx", val);
outstring(pri, s + 1);
#undef CBSIZE
}
void
prt_prs(private_t *pri, int raw, long val)
{
static size_t setsize;
priv_set_t *set = priv_allocset();
if (setsize == 0) {
const priv_impl_info_t *info = getprivimplinfo();
if (info != NULL)
setsize = info->priv_setsize * sizeof (priv_chunk_t);
}
if (setsize != 0 && !raw && set != NULL &&
Pread(Proc, set, setsize, val) == setsize) {
int i;
outstring(pri, "{");
for (i = 0; i < setsize / sizeof (priv_chunk_t); i++) {
char buf[9]; /* 8 hex digits + '\0' */
(void) snprintf(buf, sizeof (buf), "%08x",
((priv_chunk_t *)set)[i]);
outstring(pri, buf);
}
outstring(pri, "}");
} else {
prt_hex(pri, 0, val);
}
if (set != NULL)
priv_freeset(set);
}
/*
* Print privilege set operation.
*/
void
prt_pro(private_t *pri, int raw, long val)
{
const char *s = NULL;
if (!raw) {
switch ((priv_op_t)val) {
case PRIV_ON: s = "PRIV_ON"; break;
case PRIV_OFF: s = "PRIV_OFF"; break;
case PRIV_SET: s = "PRIV_SET"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
/*
* Print privilege set name
*/
void
prt_prn(private_t *pri, int raw, long val)
{
const char *s = NULL;
if (!raw)
s = priv_getsetbynum((int)val);
if (s == NULL)
prt_dec(pri, 0, val);
else {
char *dup = strdup(s);
char *q;
/* Do the best we can in this case */
if (dup == NULL) {
outstring(pri, s);
return;
}
outstring(pri, "PRIV_");
q = dup;
while (*q != '\0') {
*q = toupper(*q);
q++;
}
outstring(pri, dup);
free(dup);
}
}
/*
* Print process flag names.
*/
void
prt_pfl(private_t *pri, int raw, long val)
{
const char *s = NULL;
if (!raw) {
switch ((int)val) {
case PRIV_DEBUG: s = "PRIV_DEBUG"; break;
case PRIV_AWARE: s = "PRIV_AWARE"; break;
case PRIV_XPOLICY: s = "PRIV_XPOLICY"; break;
case PRIV_AWARE_RESET: s = "PRIV_AWARE_RESET"; break;
case PRIV_PFEXEC: s = "PRIV_PFEXEC"; break;
case NET_MAC_AWARE: s = "NET_MAC_AWARE"; break;
case NET_MAC_AWARE_INHERIT:
s = "NET_MAC_AWARE_INHERIT";
break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
/*
* Print lgrp_affinity_{get,set}() arguments.
*/
/*ARGSUSED*/
void
prt_laf(private_t *pri, int raw, long val)
{
lgrp_affinity_args_t laff;
if (Pread(Proc, &laff, sizeof (lgrp_affinity_args_t), val) !=
sizeof (lgrp_affinity_args_t)) {
prt_hex(pri, 0, val);
return;
}
/*
* arrange the arguments in the order that user calls with
*/
prt_dec(pri, 0, laff.idtype);
outstring(pri, ", ");
prt_dec(pri, 0, laff.id);
outstring(pri, ", ");
prt_dec(pri, 0, laff.lgrp);
outstring(pri, ", ");
if (pri->sys_args[0] == LGRP_SYS_AFFINITY_SET)
prt_dec(pri, 0, laff.aff);
}
/*
* Print a key_t as IPC_PRIVATE if it is 0.
*/
void
prt_key(private_t *pri, int raw, long val)
{
if (!raw && val == 0)
outstring(pri, "IPC_PRIVATE");
else
prt_dec(pri, 0, val);
}
/*
* Print zone_getattr() attribute types.
*/
void
prt_zga(private_t *pri, int raw, long val)
{
const char *s = NULL;
if (!raw) {
switch ((int)val) {
case ZONE_ATTR_NAME: s = "ZONE_ATTR_NAME"; break;
case ZONE_ATTR_ROOT: s = "ZONE_ATTR_ROOT"; break;
case ZONE_ATTR_STATUS: s = "ZONE_ATTR_STATUS"; break;
case ZONE_ATTR_PRIVSET: s = "ZONE_ATTR_PRIVSET"; break;
case ZONE_ATTR_UNIQID: s = "ZONE_ATTR_UNIQID"; break;
case ZONE_ATTR_POOLID: s = "ZONE_ATTR_POOLID"; break;
case ZONE_ATTR_INITPID: s = "ZONE_ATTR_INITPID"; break;
case ZONE_ATTR_SLBL: s = "ZONE_ATTR_SLBL"; break;
case ZONE_ATTR_INITNAME: s = "ZONE_ATTR_INITNAME"; break;
case ZONE_ATTR_BOOTARGS: s = "ZONE_ATTR_BOOTARGS"; break;
case ZONE_ATTR_BRAND: s = "ZONE_ATTR_BRAND"; break;
case ZONE_ATTR_FLAGS: s = "ZONE_ATTR_FLAGS"; break;
case ZONE_ATTR_PHYS_MCAP: s = "ZONE_ATTR_PHYS_MCAP"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
/*
* Print a file descriptor as AT_FDCWD if necessary
*/
void
prt_atc(private_t *pri, int raw, long val)
{
if ((int)val == AT_FDCWD) {
if (raw)
prt_hex(pri, 0, (uint_t)AT_FDCWD);
else
outstring(pri, "AT_FDCWD");
} else {
prt_dec(pri, 0, val);
}
}
/*
* Print Trusted Networking database operation codes (labelsys; tn*)
*/
static void
prt_tnd(private_t *pri, int raw, long val)
{
const char *s = NULL;
if (!raw) {
switch ((tsol_dbops_t)val) {
case TNDB_NOOP: s = "TNDB_NOOP"; break;
case TNDB_LOAD: s = "TNDB_LOAD"; break;
case TNDB_DELETE: s = "TNDB_DELETE"; break;
case TNDB_FLUSH: s = "TNDB_FLUSH"; break;
case TNDB_GET: s = "TNDB_GET"; break;
}
}
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
/*
* Print LIO_XX flags
*/
void
prt_lio(private_t *pri, int raw, long val)
{
if (raw)
prt_dec(pri, 0, val);
else if (val == LIO_WAIT)
outstring(pri, "LIO_WAIT");
else if (val == LIO_NOWAIT)
outstring(pri, "LIO_NOWAIT");
else
prt_dec(pri, 0, val);
}
const char *
door_flags(private_t *pri, long val)
{
door_attr_t attr = (door_attr_t)val;
char *str = pri->code_buf;
*str = '\0';
#define PROCESS_FLAG(flg) \
if (attr & flg) { \
(void) strlcat(str, "|" #flg, sizeof (pri->code_buf)); \
attr &= ~flg; \
}
PROCESS_FLAG(DOOR_UNREF);
PROCESS_FLAG(DOOR_UNREF_MULTI);
PROCESS_FLAG(DOOR_PRIVATE);
PROCESS_FLAG(DOOR_REFUSE_DESC);
PROCESS_FLAG(DOOR_NO_CANCEL);
PROCESS_FLAG(DOOR_LOCAL);
PROCESS_FLAG(DOOR_REVOKED);
PROCESS_FLAG(DOOR_IS_UNREF);
#undef PROCESS_FLAG
if (attr != 0 || *str == '\0') {
size_t len = strlen(str);
(void) snprintf(str + len, sizeof (pri->code_buf) - len,
"|0x%X", attr);
}
return (str + 1);
}
/*
* Print door_create() flags
*/
void
prt_dfl(private_t *pri, int raw, long val)
{
if (raw)
prt_hex(pri, 0, val);
else
outstring(pri, door_flags(pri, val));
}
/*
* Print door_*param() param argument
*/
void
prt_dpm(private_t *pri, int raw, long val)
{
if (raw)
prt_hex(pri, 0, val);
else if (val == DOOR_PARAM_DESC_MAX)
outstring(pri, "DOOR_PARAM_DESC_MAX");
else if (val == DOOR_PARAM_DATA_MIN)
outstring(pri, "DOOR_PARAM_DATA_MIN");
else if (val == DOOR_PARAM_DATA_MAX)
outstring(pri, "DOOR_PARAM_DATA_MAX");
else
prt_hex(pri, 0, val);
}
/*
* Print rctlsys subcodes
*/
void
prt_rsc(private_t *pri, int raw, long val) /* print utssys code */
{
const char *s = raw? NULL : rctlsyscode(val);
if (s == NULL)
prt_dec(pri, 0, val);
else
outstring(pri, s);
}
/*
* Print getrctl flags
*/
void
prt_rgf(private_t *pri, int raw, long val)
{
long action = val & (~RCTLSYS_ACTION_MASK);
if (raw)
prt_hex(pri, 0, val);
else if (action == RCTL_FIRST)
outstring(pri, "RCTL_FIRST");
else if (action == RCTL_NEXT)
outstring(pri, "RCTL_NEXT");
else if (action == RCTL_USAGE)
outstring(pri, "RCTL_USAGE");
else
prt_hex(pri, 0, val);
}
/*
* Print setrctl flags
*/
void
prt_rsf(private_t *pri, int raw, long val)
{
long action = val & (~RCTLSYS_ACTION_MASK);
long pval = val & RCTL_LOCAL_ACTION_MASK;
char *s = pri->code_buf;
if (raw) {
prt_hex(pri, 0, val);
return;
} else if (action == RCTL_INSERT)
(void) strcpy(s, "RCTL_INSERT");
else if (action == RCTL_DELETE)
(void) strcpy(s, "RCTL_DELETE");
else if (action == RCTL_REPLACE)
(void) strcpy(s, "RCTL_REPLACE");
else {
prt_hex(pri, 0, val);
return;
}
if (pval & RCTL_USE_RECIPIENT_PID) {
pval ^= RCTL_USE_RECIPIENT_PID;
(void) strlcat(s, "|RCTL_USE_RECIPIENT_PID",
sizeof (pri->code_buf));
}
if ((pval & RCTLSYS_ACTION_MASK) != 0)
prt_hex(pri, 0, val);
else if (*s != '\0')
outstring(pri, s);
else
prt_hex(pri, 0, val);
}
/*
* Print rctlctl flags
*/
void
prt_rcf(private_t *pri, int raw, long val)
{
long action = val & (~RCTLSYS_ACTION_MASK);
if (raw)
prt_hex(pri, 0, val);
else if (action == RCTLCTL_GET)
outstring(pri, "RCTLCTL_GET");
else if (action == RCTLCTL_SET)
outstring(pri, "RCTLCTL_SET");
else
prt_hex(pri, 0, val);
}
/*
* Print setprojrctl flags
*/
void
prt_spf(private_t *pri, int raw, long val)
{
long action = val & TASK_PROJ_MASK;
if (!raw && (action == TASK_PROJ_PURGE))
outstring(pri, "TASK_PROJ_PURGE");
else
prt_hex(pri, 0, val);
}
/*
* Print forkx() flags
*/
void
prt_fxf(private_t *pri, int raw, long val)
{
char *str;
if (val == 0)
outstring(pri, "0");
else if (raw || (val & ~(FORK_NOSIGCHLD | FORK_WAITPID)))
prt_hhx(pri, 0, val);
else {
str = pri->code_buf;
*str = '\0';
if (val & FORK_NOSIGCHLD)
(void) strlcat(str, "|FORK_NOSIGCHLD",
sizeof (pri->code_buf));
if (val & FORK_WAITPID)
(void) strlcat(str, "|FORK_WAITPID",
sizeof (pri->code_buf));
outstring(pri, str + 1);
}
}
/*
* Print utimensat() flag
*/
void
prt_utf(private_t *pri, int raw, long val)
{
if (val == 0)
outstring(pri, "0");
else if (!raw && val == AT_SYMLINK_NOFOLLOW)
outstring(pri, "AT_SYMLINK_NOFOLLOW");
else
prt_hex(pri, 0, val);
}
/*
* Array of pointers to print functions, one for each format.
*/
void (* const Print[])() = {
prt_nov, /* NOV -- no value */
prt_dec, /* DEC -- print value in decimal */
prt_oct, /* OCT -- print value in octal */
prt_hex, /* HEX -- print value in hexadecimal */
prt_dex, /* DEX -- print value in hexadecimal if big enough */
prt_stg, /* STG -- print value as string */
prt_ioc, /* IOC -- print ioctl code */
prt_fcn, /* FCN -- print fcntl code */
prt_s86, /* S86 -- print sysi86 code */
prt_uts, /* UTS -- print utssys code */
prt_opn, /* OPN -- print open code */
prt_sig, /* SIG -- print signal name plus flags */
prt_nov, /* Was ACT, now available for reuse */
prt_msc, /* MSC -- print msgsys command */
prt_msf, /* MSF -- print msgsys flags */
prt_smc, /* SMC -- print semsys command */
prt_sef, /* SEF -- print semsys flags */
prt_shc, /* SHC -- print shmsys command */
prt_shf, /* SHF -- print shmsys flags */
prt_nov, /* Was PLK, now available for reuse */
prt_sfs, /* SFS -- print sysfs code */
prt_rst, /* RST -- print string returned by syscall */
prt_smf, /* SMF -- print streams message flags */
prt_ioa, /* IOA -- print ioctl argument */
prt_nov, /* Was SIX, now available for reuse */
prt_mtf, /* MTF -- print mount flags */
prt_mft, /* MFT -- print mount file system type */
prt_iob, /* IOB -- print contents of I/O buffer */
prt_hhx, /* HHX -- print value in hexadecimal (half size) */
prt_wop, /* WOP -- print waitsys() options */
prt_spm, /* SPM -- print sigprocmask argument */
prt_rlk, /* RLK -- print readlink buffer */
prt_mpr, /* MPR -- print mmap()/mprotect() flags */
prt_mty, /* MTY -- print mmap() mapping type flags */
prt_mcf, /* MCF -- print memcntl() function */
prt_mc4, /* MC4 -- print memcntl() (fourth) argument */
prt_mc5, /* MC5 -- print memcntl() (fifth) argument */
prt_mad, /* MAD -- print madvise() argument */
prt_ulm, /* ULM -- print ulimit() argument */
prt_rlm, /* RLM -- print get/setrlimit() argument */
prt_cnf, /* CNF -- print sysconfig() argument */
prt_inf, /* INF -- print sysinfo() argument */
prt_ptc, /* PTC -- print pathconf/fpathconf() argument */
prt_fui, /* FUI -- print fusers() input argument */
prt_idt, /* IDT -- print idtype_t, waitid() argument */
prt_lwf, /* LWF -- print lwp_create() flags */
prt_itm, /* ITM -- print [get|set]itimer() arg */
prt_llo, /* LLO -- print long long offset arg */
prt_mod, /* MOD -- print modctl() subcode */
prt_whn, /* WHN -- print lseek() whence arguiment */
prt_acl, /* ACL -- print acl() code */
prt_aio, /* AIO -- print kaio() code */
prt_aud, /* AUD -- print auditsys() code */
prt_uns, /* DEC -- print value in unsigned decimal */
prt_clc, /* CLC -- print cladm command argument */
prt_clf, /* CLF -- print cladm flag argument */
prt_cor, /* COR -- print corectl() subcode */
prt_cco, /* CCO -- print corectl() options */
prt_ccc, /* CCC -- print corectl() content */
prt_rcc, /* RCC -- print corectl() returned content */
prt_cpc, /* CPC -- print cpc() subcode */
prt_sqc, /* SQC -- print sigqueue() si_code argument */
prt_pc4, /* PC4 -- print priocntlsys() (fourth) argument */
prt_pc5, /* PC5 -- print priocntlsys() (key, value) pairs */
prt_pst, /* PST -- print processor set id */
prt_mif, /* MIF -- print meminfo() arguments */
prt_pfm, /* PFM -- print so_socket() proto-family (1st) arg */
prt_skt, /* SKT -- print so_socket() socket-type (2nd) arg */
prt_skp, /* SKP -- print so_socket() protocol (3rd) arg */
prt_skv, /* SKV -- print socket version arg */
prt_sol, /* SOL -- print [sg]etsockopt() level (2nd) arg */
prt_son, /* SON -- print [sg]etsockopt() opt-name (3rd) arg */
prt_utt, /* UTT -- print utrap type */
prt_uth, /* UTH -- print utrap handler */
prt_acc, /* ACC -- print access() flags */
prt_sht, /* SHT -- print shutdown() how (2nd) argument */
prt_ffg, /* FFG -- print fcntl() flags (3rd) argument */
prt_prs, /* PRS -- print privilege set */
prt_pro, /* PRO -- print privilege set operation */
prt_prn, /* PRN -- print privilege set name */
prt_pfl, /* PFL -- print privilege/process flag name */
prt_laf, /* LAF -- print lgrp_affinity arguments */
prt_key, /* KEY -- print key_t 0 as IPC_PRIVATE */
prt_zga, /* ZGA -- print zone_getattr attribute types */
prt_atc, /* ATC -- print AT_FDCWD or file descriptor */
prt_lio, /* LIO -- print LIO_XX flags */
prt_dfl, /* DFL -- print door_create() flags */
prt_dpm, /* DPM -- print DOOR_PARAM_XX flags */
prt_tnd, /* TND -- print trusted network data base opcode */
prt_rsc, /* RSC -- print rctlsys() subcodes */
prt_rgf, /* RGF -- print getrctl() flags */
prt_rsf, /* RSF -- print setrctl() flags */
prt_rcf, /* RCF -- print rctlsys_ctl() flags */
prt_fxf, /* FXF -- print forkx() flags */
prt_spf, /* SPF -- print rctlsys_projset() flags */
prt_un1, /* UN1 -- as prt_uns except for -1 */
prt_mob, /* MOB -- print mmapobj() flags */
prt_utf, /* UTF -- print utimensat() flag */
prt_dec, /* HID -- hidden argument, make this the last one */
};